From 0fd60285b5a0939f3d4ec81e013b262a554941c6 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Mon, 10 Apr 2023 19:23:32 +0530 Subject: [PATCH 001/753] Updated roi not allowed check in ios vision task runner --- mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm index 98d46f17e..964cd38c7 100644 --- a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm +++ b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm @@ -90,7 +90,7 @@ static const NSInteger kMPPOrientationDegreesLeft = -270; (UIImageOrientation)imageOrientation ROIAllowed:(BOOL)ROIAllowed error:(NSError **)error { - if (CGRectEqualToRect(roi, CGRectZero) && !ROIAllowed) { + if (!CGRectEqualToRect(roi, CGRectZero) && !ROIAllowed) { [MPPCommonUtils createCustomError:error withCode:MPPTasksErrorCodeInvalidArgumentError description:@"This task doesn't support region-of-interest."]; From adfe47d456e106a0e22eb85e6dbd9b30b7114285 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Mon, 10 Apr 2023 19:24:58 +0530 Subject: [PATCH 002/753] Removed roi apis from iOS object detector --- .../sources/MPPObjectDetector.h | 79 ------------------- .../sources/MPPObjectDetector.mm | 56 +++++++------ 2 files changed, 30 insertions(+), 105 deletions(-) diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h index 58344d0c7..8b01c6671 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h @@ -109,28 +109,6 @@ NS_SWIFT_NAME(ObjectDetector) error:(NSError **)error NS_SWIFT_NAME(detect(image:)); -/** - * Performs object detectionon the provided `MPPImage` cropped to the specified region of - * interest. Rotation will be applied on the cropped image according to the `orientation` property - * of the provided `MPPImage`. Only use this method when the `MPPObjectDetector` is created with - * `MPPRunningModeImage`. - * - * @param image The `MPPImage` on which object detection is to be performed. - * @param roi A `CGRect` specifying the region of interest within the given `MPPImage`, on which - * object detection should be performed. - * @param error An optional error parameter populated when there is an error in performing object - * detection on the input image. - * - * @return An `MPPObjectDetectionResult` object that contains a list of detections, each detection - * has a bounding box that is expressed in the unrotated input frame of reference coordinates - * system, i.e. in `[0,image_width) x [0,image_height)`, which are the dimensions of the underlying - * image data. - */ -- (nullable MPPObjectDetectionResult *)detectInImage:(MPPImage *)image - regionOfInterest:(CGRect)roi - error:(NSError **)error - NS_SWIFT_NAME(detect(image:regionOfInterest:)); - /** * Performs object detection on the provided video frame of type `MPPImage` using the whole * image as region of interest. Rotation will be applied according to the `orientation` property of @@ -153,36 +131,6 @@ NS_SWIFT_NAME(ObjectDetector) error:(NSError **)error NS_SWIFT_NAME(detect(videoFrame:timestampMs:)); -/** - * Performs object detection on the provided video frame of type `MPPImage` cropped to the - * specified region of interest. Rotation will be applied according to the `orientation` property of - * the provided `MPPImage`. Only use this method when the `MPPObjectDetector` is created with - * `MPPRunningModeVideo`. - * - * It's required to provide the video frame's timestamp (in milliseconds). The input timestamps must - * be monotonically increasing. - * - * @param image A live stream image data of type `MPPImage` on which object detection is to be - * performed. - * @param timestampMs The video frame's timestamp (in milliseconds). The input timestamps must be - * monotonically increasing. - * @param roi A `CGRect` specifying the region of interest within the given `MPPImage`, on which - * object detection should be performed. - * - * @param error An optional error parameter populated when there is an error in performing object - * detection on the input image. - * - * @return An `MPPObjectDetectionResult` object that contains a list of detections, each detection - * has a bounding box that is expressed in the unrotated input frame of reference coordinates - * system, i.e. in `[0,image_width) x [0,image_height)`, which are the dimensions of the underlying - * image data. - */ -- (nullable MPPObjectDetectionResult *)detectInVideoFrame:(MPPImage *)image - timestampMs:(NSInteger)timestampMs - regionOfInterest:(CGRect)roi - error:(NSError **)error - NS_SWIFT_NAME(detect(videoFrame:timestampMs:regionOfInterest:)); - /** * Sends live stream image data of type `MPPImage` to perform object detection using the whole * image as region of interest. Rotation will be applied according to the `orientation` property of @@ -206,33 +154,6 @@ NS_SWIFT_NAME(ObjectDetector) timestampMs:(NSInteger)timestampMs error:(NSError **)error NS_SWIFT_NAME(detectAsync(image:timestampMs:)); -/** - * Sends live stream image data of type `MPPImage` to perform object detection, cropped to the - * specified region of interest. Rotation will be applied according to the `orientation` property - * of the provided `MPPImage`. Only use this method when the `MPPObjectDetector` is created with - * `MPPRunningModeLiveStream`. Results are provided asynchronously via the `completion` callback - * provided in the `MPPObjectDetectorOptions`. - * - * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent - * to the object detector. The input timestamps must be monotonically increasing. - * - * @param image A live stream image data of type `MPPImage` on which object detection is to be - * performed. - * @param timestampMs The timestamp (in milliseconds) which indicates when the input image is sent - * to the object detector. The input timestamps must be monotonically increasing. - * @param roi A `CGRect` specifying the region of interest within the given live stream image data - * of type `MPPImage`, on which iobject detection should be performed. - * @param error An optional error parameter populated when there is an error in performing object - * detection on the input live stream image data. - * - * @return `YES` if the image was sent to the task successfully, otherwise `NO`. - */ -- (BOOL)detectAsyncInImage:(MPPImage *)image - timestampMs:(NSInteger)timestampMs - regionOfInterest:(CGRect)roi - error:(NSError **)error - NS_SWIFT_NAME(detectAsync(image:timestampMs:regionOfInterest:)); - - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm index 53dcad4a8..cca339819 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm @@ -158,12 +158,11 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG - (std::optional)inputPacketMapWithMPPImage:(MPPImage *)image timestampMs:(NSInteger)timestampMs - regionOfInterest:(CGRect)roi error:(NSError **)error { std::optional rect = - [_visionTaskRunner normalizedRectFromRegionOfInterest:roi + [_visionTaskRunner normalizedRectFromRegionOfInterest:CGRectZero imageOrientation:image.orientation - ROIAllowed:YES + ROIAllowed:NO error:error]; if (!rect.has_value()) { return std::nullopt; @@ -184,16 +183,41 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG } - (nullable MPPObjectDetectionResult *)detectInImage:(MPPImage *)image error:(NSError **)error { - return [self detectInImage:image regionOfInterest:CGRectZero error:error]; + std::optional rect = + [_visionTaskRunner normalizedRectFromRegionOfInterest:CGRectZero + imageOrientation:image.orientation + ROIAllowed:YES + error:error]; + if (!rect.has_value()) { + return nil; + } + + Packet imagePacket = [MPPVisionPacketCreator createPacketWithMPPImage:image error:error]; + if (imagePacket.IsEmpty()) { + return nil; + } + + Packet normalizedRectPacket = + [MPPVisionPacketCreator createPacketWithNormalizedRect:rect.value()]; + + PacketMap inputPacketMap = InputPacketMap(imagePacket, normalizedRectPacket); + + std::optional outputPacketMap = [_visionTaskRunner processImagePacketMap:inputPacketMap + error:error]; + if (!outputPacketMap.has_value()) { + return nil; + } + + return [MPPObjectDetectionResult + objectDetectionResultWithDetectionsPacket:outputPacketMap + .value()[kDetectionsStreamName.cppString]]; } - (nullable MPPObjectDetectionResult *)detectInVideoFrame:(MPPImage *)image timestampMs:(NSInteger)timestampMs - regionOfInterest:(CGRect)roi error:(NSError **)error { std::optional inputPacketMap = [self inputPacketMapWithMPPImage:image timestampMs:timestampMs - regionOfInterest:roi error:error]; if (!inputPacketMap.has_value()) { return nil; @@ -211,22 +235,11 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG .value()[kDetectionsStreamName.cppString]]; } -- (nullable MPPObjectDetectionResult *)detectInVideoFrame:(MPPImage *)image - timestampMs:(NSInteger)timestampMs - error:(NSError **)error { - return [self detectInVideoFrame:image - timestampMs:timestampMs - regionOfInterest:CGRectZero - error:error]; -} - - (BOOL)detectAsyncInImage:(MPPImage *)image timestampMs:(NSInteger)timestampMs - regionOfInterest:(CGRect)roi error:(NSError **)error { std::optional inputPacketMap = [self inputPacketMapWithMPPImage:image timestampMs:timestampMs - regionOfInterest:roi error:error]; if (!inputPacketMap.has_value()) { return NO; @@ -235,13 +248,4 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG return [_visionTaskRunner processLiveStreamPacketMap:inputPacketMap.value() error:error]; } -- (BOOL)detectAsyncInImage:(MPPImage *)image - timestampMs:(NSInteger)timestampMs - error:(NSError **)error { - return [self detectAsyncInImage:image - timestampMs:timestampMs - regionOfInterest:CGRectZero - error:error]; -} - @end From a2bab54640902a4178f8d63c7f05c17c24267366 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Mon, 10 Apr 2023 19:25:37 +0530 Subject: [PATCH 003/753] Added iOS Object Detector Objective D tests --- .../ios/test/vision/object_detector/BUILD | 55 ++ .../object_detector/MPPObjectDetectorTests.m | 703 ++++++++++++++++++ 2 files changed, 758 insertions(+) create mode 100644 mediapipe/tasks/ios/test/vision/object_detector/BUILD create mode 100644 mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m diff --git a/mediapipe/tasks/ios/test/vision/object_detector/BUILD b/mediapipe/tasks/ios/test/vision/object_detector/BUILD new file mode 100644 index 000000000..36e1afb2f --- /dev/null +++ b/mediapipe/tasks/ios/test/vision/object_detector/BUILD @@ -0,0 +1,55 @@ +load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test") +load( + "//mediapipe/tasks:ios/ios.bzl", + "MPP_TASK_MINIMUM_OS_VERSION", +) +load( + "@org_tensorflow//tensorflow/lite:special_rules.bzl", + "tflite_ios_lab_runner", +) + +package(default_visibility = ["//mediapipe/tasks:internal"]) + +licenses(["notice"]) + +# Default tags for filtering iOS targets. Targets are restricted to Apple platforms. +TFL_DEFAULT_TAGS = [ + "apple", +] + +# Following sanitizer tests are not supported by iOS test targets. +TFL_DISABLED_SANITIZER_TAGS = [ + "noasan", + "nomsan", + "notsan", +] + +objc_library( + name = "MPPObjectDetectorObjcTestLibrary", + testonly = 1, + srcs = ["MPPObjectDetectorTests.m"], + copts = [ + "-ObjC++", + "-std=c++17", + "-x objective-c++", + ], + data = [ + "//mediapipe/tasks/testdata/vision:test_images", + "//mediapipe/tasks/testdata/vision:test_models", + ], + deps = [ + "//mediapipe/tasks/ios/common:MPPCommon", + "//mediapipe/tasks/ios/test/vision/utils:MPPImageTestUtils", + "//mediapipe/tasks/ios/vision/object_detector:MPPObjectDetector", + ], +) + +ios_unit_test( + name = "MPPObjectDetectorObjcTest", + minimum_os_version = MPP_TASK_MINIMUM_OS_VERSION, + runner = tflite_ios_lab_runner("IOS_LATEST"), + tags = TFL_DEFAULT_TAGS + TFL_DISABLED_SANITIZER_TAGS, + deps = [ + ":MPPObjectDetectorObjcTestLibrary", + ], +) diff --git a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m new file mode 100644 index 000000000..cb76de88e --- /dev/null +++ b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m @@ -0,0 +1,703 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +#import "mediapipe/tasks/ios/common/sources/MPPCommon.h" +#import "mediapipe/tasks/ios/test/vision/utils/sources/MPPImage+TestUtils.h" +#import "mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h" + +static NSString *const kModelName = @"coco_ssd_mobilenet_v1_1.0_quant_2018_06_29"; +static NSDictionary *const kCatsAndDogsImage = @{@"name" : @"cats_and_dogs", @"type" : @"jpg"}; +static NSDictionary *const kCatsAndDogsRotatedImage = + @{@"name" : @"cats_and_dogs_rotated", @"type" : @"jpg"}; +static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; + +#define PixelDifferenceTolerance 5.0f +#define ScoreDifferenceTolerance 1e-2f + +#define AssertEqualErrors(error, expectedError) \ + XCTAssertNotNil(error); \ + XCTAssertEqualObjects(error.domain, expectedError.domain); \ + XCTAssertEqual(error.code, expectedError.code); \ + XCTAssertNotEqual( \ + [error.localizedDescription rangeOfString:expectedError.localizedDescription].location, \ + NSNotFound) + +#define AssertEqualCategoryArrays(categories, expectedCategories, detectionIndex) \ + XCTAssertEqual(categories.count, expectedCategories.count); \ + for (int j = 0; j < categories.count; j++) { \ + XCTAssertEqual(categories[j].index, expectedCategories[j].index, \ + @"detection Index = %d category array index j = %d", detectionIndex, j); \ + XCTAssertEqualWithAccuracy( \ + categories[j].score, expectedCategories[j].score, ScoreDifferenceTolerance, \ + @"detection Index = %d, category array index j = %d", detectionIndex, j); \ + XCTAssertEqualObjects(categories[j].categoryName, expectedCategories[j].categoryName, \ + @"detection Index = %d, category array index j = %d", detectionIndex, \ + j); \ + XCTAssertEqualObjects(categories[j].displayName, expectedCategories[j].displayName, \ + @"detection Index = %d, category array index j = %d", detectionIndex, \ + j); \ + \ + \ + } + +#define AssertApproximatelyEqualBoundingBoxes(boundingBox, expectedBoundingBox, idx) \ + XCTAssertEqualWithAccuracy(boundingBox.origin.x, expectedBoundingBox.origin.x, \ + PixelDifferenceTolerance, @"index i = %d", idx); \ + XCTAssertEqualWithAccuracy(boundingBox.origin.y, expectedBoundingBox.origin.y, \ + PixelDifferenceTolerance, @"index i = %d", idx); \ + XCTAssertEqualWithAccuracy(boundingBox.size.width, expectedBoundingBox.size.width, \ + PixelDifferenceTolerance, @"index i = %d", idx); \ + XCTAssertEqualWithAccuracy(boundingBox.size.height, expectedBoundingBox.size.height, \ + PixelDifferenceTolerance, @"index i = %d", idx); + +#define AssertEqualDetections(detection, expectedDetection, idx) \ + XCTAssertNotNil(detection); \ + AssertEqualCategoryArrays(detection.categories, expectedDetection.categories, idx); \ + AssertApproximatelyEqualBoundingBoxes(detection.boundingBox, expectedDetection.boundingBox, idx); + +#define AssertEqualDetectionArrays(detections, expectedDetections) \ + XCTAssertEqual(detections.count, expectedDetections.count); \ + for (int i = 0; i < detections.count; i++) { \ + AssertEqualDetections(detections[i], expectedDetections[i], i); \ + } + +#define AssertEqualObjectDetectionResults(objectDetectionResult, expectedObjectDetectionResult, \ + expectedDetectionCount) \ + XCTAssertNotNil(objectDetectionResult); \ + NSArray *detectionsSubsetToCompare; \ + XCTAssertEqual(objectDetectionResult.detections.count, expectedDetectionCount); \ + if (objectDetectionResult.detections.count > expectedObjectDetectionResult.detections.count) { \ + detectionsSubsetToCompare = [objectDetectionResult.detections \ + subarrayWithRange:NSMakeRange(0, expectedObjectDetectionResult.detections.count)]; \ + } else { \ + detectionsSubsetToCompare = objectDetectionResult.detections; \ + } \ + \ + AssertEqualDetectionArrays(detectionsSubsetToCompare, expectedObjectDetectionResult.detections); \ + XCTAssertEqual(objectDetectionResult.timestampMs, expectedObjectDetectionResult.timestampMs); + +@interface MPPObjectDetectorTests : XCTestCase +@end + +@implementation MPPObjectDetectorTests + +#pragma mark Results + ++ (MPPObjectDetectionResult *)expectedDetectionResultForCatsAndDogsImageWithTimestampMs: + (NSInteger)timestampMs { + NSArray *detections = @[ + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 score:0.69921875f categoryName:@"cat" displayName:nil], + ] + boundingBox:CGRectMake(608, 161, 381, 439) + keypoints:nil], + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 score:0.656250f categoryName:@"cat" displayName:nil], + ] + boundingBox:CGRectMake(57, 398, 392, 196) + keypoints:nil], + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 score:0.51171875f categoryName:@"cat" displayName:nil], + ] + boundingBox:CGRectMake(257, 395, 173, 202) + keypoints:nil], + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 score:0.48828125f categoryName:@"cat" displayName:nil], + ] + boundingBox:CGRectMake(363, 195, 330, 412) + keypoints:nil], + ]; + + return [[MPPObjectDetectionResult alloc] initWithDetections:detections timestampMs:timestampMs]; +} + +#pragma mark File + +- (NSString *)filePathWithName:(NSString *)fileName extension:(NSString *)extension { + NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:fileName + ofType:extension]; + return filePath; +} + +#pragma mark Object Detector Initializers + +- (MPPObjectDetectorOptions *)objectDetectorOptionsWithModelName:(NSString *)modelName { + NSString *modelPath = [self filePathWithName:modelName extension:@"tflite"]; + MPPObjectDetectorOptions *objectDetectorOptions = [[MPPObjectDetectorOptions alloc] init]; + objectDetectorOptions.baseOptions.modelAssetPath = modelPath; + + return objectDetectorOptions; +} + +- (void)assertCreateObjectDetectorWithOptions:(MPPObjectDetectorOptions *)objectDetectorOptions + failsWithExpectedError:(NSError *)expectedError { + NSError *error = nil; + MPPObjectDetector *objectDetector = + [[MPPObjectDetector alloc] initWithOptions:objectDetectorOptions error:&error]; + + XCTAssertNil(objectDetector); + AssertEqualErrors(error, expectedError); +} + +- (MPPObjectDetector *)objectDetectorWithOptionsSucceeds: + (MPPObjectDetectorOptions *)objectDetectorOptions { + MPPObjectDetector *objectDetector = + [[MPPObjectDetector alloc] initWithOptions:objectDetectorOptions error:nil]; + XCTAssertNotNil(objectDetector); + + return objectDetector; +} + +#pragma mark Assert Detection Results + +- (MPPImage *)imageWithFileInfo:(NSDictionary *)fileInfo { + MPPImage *image = [MPPImage imageFromBundleWithClass:[MPPObjectDetectorTests class] + fileName:fileInfo[@"name"] + ofType:fileInfo[@"type"]]; + XCTAssertNotNil(image); + + return image; +} + +- (MPPImage *)imageWithFileInfo:(NSDictionary *)fileInfo + orientation:(UIImageOrientation)orientation { + MPPImage *image = [MPPImage imageFromBundleWithClass:[MPPObjectDetectorTests class] + fileName:fileInfo[@"name"] + ofType:fileInfo[@"type"] + orientation:orientation]; + XCTAssertNotNil(image); + + return image; +} + +- (void)assertResultsOfDetectInImage:(MPPImage *)mppImage + usingObjectDetector:(MPPObjectDetector *)objectDetector + maxResults:(NSInteger)maxResults + equalsObjectDetectionResult:(MPPObjectDetectionResult *)expectedObjectDetectionResult { + MPPObjectDetectionResult *objectDetectionResult = [objectDetector detectInImage:mppImage + error:nil]; + AssertEqualObjectDetectionResults( + objectDetectionResult, expectedObjectDetectionResult, + maxResults > 0 ? maxResults : objectDetectionResult.detections.count); +} + +- (void)assertResultsOfDetectInImageWithFileInfo:(NSDictionary *)fileInfo + usingObjectDetector:(MPPObjectDetector *)objectDetector + maxResults:(NSInteger)maxResults + + equalsObjectDetectionResult: + (MPPObjectDetectionResult *)expectedObjectDetectionResult { + MPPImage *mppImage = [self imageWithFileInfo:fileInfo]; + + [self assertResultsOfDetectInImage:mppImage + usingObjectDetector:objectDetector + maxResults:maxResults + equalsObjectDetectionResult:expectedObjectDetectionResult]; +} + +#pragma mark General Tests + +- (void)testCreateObjectDetectorWithMissingModelPathFails { + NSString *modelPath = [self filePathWithName:@"" extension:@""]; + + NSError *error = nil; + MPPObjectDetector *objectDetector = [[MPPObjectDetector alloc] initWithModelPath:modelPath + error:&error]; + XCTAssertNil(objectDetector); + + NSError *expectedError = [NSError + errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : + @"INVALID_ARGUMENT: ExternalFile must specify at least one of 'file_content', " + @"'file_name', 'file_pointer_meta' or 'file_descriptor_meta'." + }]; + AssertEqualErrors(error, expectedError); +} + +- (void)testCreateObjectDetectorAllowlistAndDenylistFails { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + options.categoryAllowlist = @[ @"cat" ]; + options.categoryDenylist = @[ @"dog" ]; + + [self assertCreateObjectDetectorWithOptions:options + failsWithExpectedError: + [NSError + errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : + @"INVALID_ARGUMENT: `category_allowlist` and " + @"`category_denylist` are mutually exclusive options." + }]]; +} + +- (void)testDetectWithModelPathSucceeds { + NSString *modelPath = [self filePathWithName:kModelName extension:@"tflite"]; + MPPObjectDetector *objectDetector = [[MPPObjectDetector alloc] initWithModelPath:modelPath + error:nil]; + XCTAssertNotNil(objectDetector); + + [self assertResultsOfDetectInImageWithFileInfo:kCatsAndDogsImage + usingObjectDetector:objectDetector + maxResults:-1 + equalsObjectDetectionResult: + [MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampMs:0]]; +} + +- (void)testDetectWithOptionsSucceeds { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + + MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + + [self assertResultsOfDetectInImageWithFileInfo:kCatsAndDogsImage + usingObjectDetector:objectDetector + maxResults:-1 + equalsObjectDetectionResult: + [MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampMs:0]]; +} + +- (void)testDetectWithMaxResultsSucceeds { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + + const NSInteger maxResults = 4; + options.maxResults = maxResults; + + MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + + [self assertResultsOfDetectInImageWithFileInfo:kCatsAndDogsImage + usingObjectDetector:objectDetector + maxResults:maxResults + equalsObjectDetectionResult: + [MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampMs:0]]; +} + +- (void)testDetectWithScoreThresholdSucceeds { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + options.scoreThreshold = 0.68f; + + MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + + NSArray *detections = @[ + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 score:0.69921875f categoryName:@"cat" displayName:nil], + ] + boundingBox:CGRectMake(608, 161, 381, 439) + keypoints:nil], + ]; + MPPObjectDetectionResult *expectedObjectDetectionResult = + [[MPPObjectDetectionResult alloc] initWithDetections:detections timestampMs:0]; + + [self assertResultsOfDetectInImageWithFileInfo:kCatsAndDogsImage + usingObjectDetector:objectDetector + maxResults:-1 + equalsObjectDetectionResult:expectedObjectDetectionResult]; +} + +- (void)testDetectWithCategoryAllowlistSucceeds { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + options.categoryAllowlist = @[ @"cat" ]; + + MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + + NSArray *detections = @[ + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 score:0.69921875f categoryName:@"cat" displayName:nil], + ] + boundingBox:CGRectMake(608, 161, 381, 439) + keypoints:nil], + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 score:0.656250f categoryName:@"cat" displayName:nil], + ] + boundingBox:CGRectMake(57, 398, 392, 196) + keypoints:nil], + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 score:0.51171875f categoryName:@"cat" displayName:nil], + ] + boundingBox:CGRectMake(257, 395, 173, 202) + keypoints:nil], + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 score:0.48828125f categoryName:@"cat" displayName:nil], + ] + boundingBox:CGRectMake(363, 195, 330, 412) + keypoints:nil], + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 score:0.355469f categoryName:@"cat" displayName:nil], + ] + boundingBox:CGRectMake(275, 216, 610, 386) + keypoints:nil], + ]; + + MPPObjectDetectionResult *expectedDetectionResult = + [[MPPObjectDetectionResult alloc] initWithDetections:detections timestampMs:0]; + + [self assertResultsOfDetectInImageWithFileInfo:kCatsAndDogsImage + usingObjectDetector:objectDetector + maxResults:-1 + equalsObjectDetectionResult:expectedDetectionResult]; +} + +- (void)testDetectWithCategoryDenylistSucceeds { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + options.categoryDenylist = @[ @"cat" ]; + + MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + + NSArray *detections = @[ + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 + score:0.476562f + categoryName:@"teddy bear" + displayName:nil], + ] + boundingBox:CGRectMake(780, 407, 314, 190) + keypoints:nil], + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 + score:0.390625f + categoryName:@"teddy bear" + displayName:nil], + ] + boundingBox:CGRectMake(90, 225, 568, 366) + keypoints:nil], + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 + score:0.367188f + categoryName:@"teddy bear" + displayName:nil], + ] + boundingBox:CGRectMake(888, 434, 187, 167) + keypoints:nil], + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 score:0.332031f categoryName:@"bed" displayName:nil], + ] + boundingBox:CGRectMake(79, 364, 1097, 224) + keypoints:nil], + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 + score:0.289062f + categoryName:@"teddy bear" + displayName:nil], + ] + boundingBox:CGRectMake(605, 398, 445, 199) + keypoints:nil], + ]; + + MPPObjectDetectionResult *expectedDetectionResult = + [[MPPObjectDetectionResult alloc] initWithDetections:detections timestampMs:0]; + + [self assertResultsOfDetectInImageWithFileInfo:kCatsAndDogsImage + usingObjectDetector:objectDetector + maxResults:-1 + equalsObjectDetectionResult:expectedDetectionResult]; +} + +- (void)testDetectWithOrientationSucceeds { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + options.maxResults = 1; + + MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + + NSArray *detections = @[ + [[MPPDetection alloc] initWithCategories:@[ + [[MPPCategory alloc] initWithIndex:-1 + score:0.750000f + categoryName:@"teddy bear" + displayName:nil], + ] + boundingBox:CGRectMake(0, 372, 416, 276) + keypoints:nil], + ]; + + MPPObjectDetectionResult *expectedDetectionResult = + [[MPPObjectDetectionResult alloc] initWithDetections:detections timestampMs:0]; + + MPPImage *image = [self imageWithFileInfo:kCatsAndDogsRotatedImage + orientation:UIImageOrientationRight]; + + [self assertResultsOfDetectInImage:image + usingObjectDetector:objectDetector + maxResults:1 + equalsObjectDetectionResult:expectedDetectionResult]; +} + +#pragma mark Running Mode Tests + +- (void)testCreateObjectDetectorFailsWithResultListenerInNonLiveStreamMode { + MPPRunningMode runningModesToTest[] = {MPPRunningModeImage, MPPRunningModeVideo}; + for (int i = 0; i < sizeof(runningModesToTest) / sizeof(runningModesToTest[0]); i++) { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + + options.runningMode = runningModesToTest[i]; + options.completion = + ^(MPPObjectDetectionResult *result, NSInteger timestampMs, NSError *error) { + }; + + [self + assertCreateObjectDetectorWithOptions:options + failsWithExpectedError: + [NSError + errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : + @"The vision task is in image or video mode, a " + @"user-defined result callback should not be provided." + }]]; + } +} + +- (void)testCreateObjectDetectorFailsWithMissingResultListenerInLiveStreamMode { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + + options.runningMode = MPPRunningModeLiveStream; + + [self assertCreateObjectDetectorWithOptions:options + failsWithExpectedError: + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : + @"The vision task is in live stream mode, a " + @"user-defined result callback must be provided." + }]]; +} + +- (void)testDetectFailsWithCallingWrongApiInImageMode { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + + MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + + MPPImage *image = [self imageWithFileInfo:kCatsAndDogsImage]; + + NSError *liveStreamApiCallError; + XCTAssertFalse([objectDetector detectAsyncInImage:image + timestampMs:0 + error:&liveStreamApiCallError]); + + NSError *expectedLiveStreamApiCallError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : @"The vision task is not initialized with live " + @"stream mode. Current Running Mode: Image" + }]; + + AssertEqualErrors(liveStreamApiCallError, expectedLiveStreamApiCallError); + + NSError *videoApiCallError; + XCTAssertFalse([objectDetector detectInVideoFrame:image timestampMs:0 error:&videoApiCallError]); + + NSError *expectedVideoApiCallError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : @"The vision task is not initialized with " + @"video mode. Current Running Mode: Image" + }]; + AssertEqualErrors(videoApiCallError, expectedVideoApiCallError); +} + +- (void)testDetectFailsWithCallingWrongApiInVideoMode { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + options.runningMode = MPPRunningModeVideo; + + MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + + MPPImage *image = [self imageWithFileInfo:kCatsAndDogsImage]; + + NSError *liveStreamApiCallError; + XCTAssertFalse([objectDetector detectAsyncInImage:image + timestampMs:0 + error:&liveStreamApiCallError]); + + NSError *expectedLiveStreamApiCallError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : @"The vision task is not initialized with live " + @"stream mode. Current Running Mode: Video" + }]; + + AssertEqualErrors(liveStreamApiCallError, expectedLiveStreamApiCallError); + + NSError *imageApiCallError; + XCTAssertFalse([objectDetector detectInImage:image error:&imageApiCallError]); + + NSError *expectedImageApiCallError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : @"The vision task is not initialized with " + @"image mode. Current Running Mode: Video" + }]; + AssertEqualErrors(imageApiCallError, expectedImageApiCallError); +} + +- (void)testDetectFailsWithCallingWrongApiInLiveStreamMode { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + + options.runningMode = MPPRunningModeLiveStream; + options.completion = ^(MPPObjectDetectionResult *result, NSInteger timestampMs, NSError *error) { + + }; + + MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + + MPPImage *image = [self imageWithFileInfo:kCatsAndDogsImage]; + + NSError *imageApiCallError; + XCTAssertFalse([objectDetector detectInImage:image error:&imageApiCallError]); + + NSError *expectedImageApiCallError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : @"The vision task is not initialized with " + @"image mode. Current Running Mode: Live Stream" + }]; + AssertEqualErrors(imageApiCallError, expectedImageApiCallError); + + NSError *videoApiCallError; + XCTAssertFalse([objectDetector detectInVideoFrame:image timestampMs:0 error:&videoApiCallError]); + + NSError *expectedVideoApiCallError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : @"The vision task is not initialized with " + @"video mode. Current Running Mode: Live Stream" + }]; + AssertEqualErrors(videoApiCallError, expectedVideoApiCallError); +} + +- (void)testClassifyWithVideoModeSucceeds { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + + options.runningMode = MPPRunningModeVideo; + + NSInteger maxResults = 4; + options.maxResults = maxResults; + + MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + + MPPImage *image = [self imageWithFileInfo:kCatsAndDogsImage]; + + for (int i = 0; i < 3; i++) { + MPPObjectDetectionResult *objectDetectionResult = [objectDetector detectInVideoFrame:image + timestampMs:i + error:nil]; + AssertEqualObjectDetectionResults( + objectDetectionResult, + [MPPObjectDetectorTests expectedDetectionResultForCatsAndDogsImageWithTimestampMs:i], + maxResults); + } +} + +- (void)testDetectWithOutOfOrderTimestampsAndLiveStreamModeFails { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + + NSInteger maxResults = 4; + options.maxResults = maxResults; + + options.runningMode = MPPRunningModeLiveStream; + + XCTestExpectation *expectation = [[XCTestExpectation alloc] + initWithDescription:@"detectWithOutOfOrderTimestampsAndLiveStream"]; + expectation.expectedFulfillmentCount = 1; + + options.completion = ^(MPPObjectDetectionResult *result, NSInteger timestampMs, NSError *error) { + AssertEqualObjectDetectionResults( + result, + [MPPObjectDetectorTests expectedDetectionResultForCatsAndDogsImageWithTimestampMs:1], + maxResults); + [expectation fulfill]; + }; + + MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + + MPPImage *image = [self imageWithFileInfo:kCatsAndDogsImage]; + + XCTAssertTrue([objectDetector detectAsyncInImage:image timestampMs:1 error:nil]); + + NSError *error; + XCTAssertFalse([objectDetector detectAsyncInImage:image timestampMs:0 error:&error]); + + NSError *expectedError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : + @"INVALID_ARGUMENT: Input timestamp must be monotonically increasing." + }]; + AssertEqualErrors(error, expectedError); + [self waitForExpectations:@[ expectation ] timeout:0.1]; +} + +- (void)testDetectWithLiveStreamModeSucceeds { + MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; + + NSInteger maxResults = 4; + options.maxResults = maxResults; + + options.runningMode = MPPRunningModeLiveStream; + + NSInteger iterationCount = 100; + + // Because of flow limiting, we cannot ensure that the callback will be + // invoked `iterationCount` times. + // An normal expectation will fail if expectation.fullfill() is not called + // `expectation.expectedFulfillmentCount` times. + // If `expectation.isInverted = true`, the test will only succeed if + // expectation is not fullfilled for the specified `expectedFulfillmentCount`. + // Since in our case we cannot predict how many times the expectation is + // supposed to be fullfilled setting, + // `expectation.expectedFulfillmentCount` = `iterationCount` + 1 and + // `expectation.isInverted = true` ensures that test succeeds if + // expectation is fullfilled <= `iterationCount` times. + XCTestExpectation *expectation = [[XCTestExpectation alloc] + initWithDescription:@"detectWithOutOfOrderTimestampsAndLiveStream"]; + expectation.expectedFulfillmentCount = iterationCount + 1; + expectation.inverted = YES; + + options.completion = ^(MPPObjectDetectionResult *result, NSInteger timestampMs, NSError *error) { + AssertEqualObjectDetectionResults( + result, + [MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampMs:timestampMs], + maxResults); + [expectation fulfill]; + }; + + MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + + // TODO: Mimic initialization from CMSampleBuffer as live stream mode is most likely to be used + // with the iOS camera. AVCaptureVideoDataOutput sample buffer delegates provide frames of type + // `CMSampleBuffer`. + MPPImage *image = [self imageWithFileInfo:kCatsAndDogsImage]; + + for (int i = 0; i < iterationCount; i++) { + XCTAssertTrue([objectDetector detectAsyncInImage:image timestampMs:i error:nil]); + } + + [self waitForExpectations:@[ expectation ] timeout:0.5]; +} + +@end From d06cf68c70189a04cc0f184b0b4164393bb8c4a4 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Mon, 10 Apr 2023 19:28:46 +0530 Subject: [PATCH 004/753] Removed detect in image with region of interest api from iOS Object Detector --- .../sources/MPPObjectDetector.mm | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm index cca339819..499353558 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm @@ -123,39 +123,6 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG return [self initWithOptions:options error:error]; } -- (nullable MPPObjectDetectionResult *)detectInImage:(MPPImage *)image - regionOfInterest:(CGRect)roi - error:(NSError **)error { - std::optional rect = - [_visionTaskRunner normalizedRectFromRegionOfInterest:roi - imageOrientation:image.orientation - ROIAllowed:YES - error:error]; - if (!rect.has_value()) { - return nil; - } - - Packet imagePacket = [MPPVisionPacketCreator createPacketWithMPPImage:image error:error]; - if (imagePacket.IsEmpty()) { - return nil; - } - - Packet normalizedRectPacket = - [MPPVisionPacketCreator createPacketWithNormalizedRect:rect.value()]; - - PacketMap inputPacketMap = InputPacketMap(imagePacket, normalizedRectPacket); - - std::optional outputPacketMap = [_visionTaskRunner processImagePacketMap:inputPacketMap - error:error]; - if (!outputPacketMap.has_value()) { - return nil; - } - - return [MPPObjectDetectionResult - objectDetectionResultWithDetectionsPacket:outputPacketMap - .value()[kDetectionsStreamName.cppString]]; -} - - (std::optional)inputPacketMapWithMPPImage:(MPPImage *)image timestampMs:(NSInteger)timestampMs error:(NSError **)error { From 89491df8c1d4fe4f07b5dc1c0ba2cedcaf30ab89 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 10 Apr 2023 22:38:14 +0530 Subject: [PATCH 005/753] Migrate stale management probot to Github action --- .github/stale.yml | 34 ------------------- .github/workflows/stale.yaml | 66 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 34 deletions(-) delete mode 100644 .github/stale.yml create mode 100644 .github/workflows/stale.yaml diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index 03c67d0f6..000000000 --- a/.github/stale.yml +++ /dev/null @@ -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. diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml new file mode 100644 index 000000000..c79824a42 --- /dev/null +++ b/.github/workflows/stale.yaml @@ -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" \ No newline at end of file From 089361cd8953ce014d2300b8373c117064b3bdec Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 11 Apr 2023 17:37:54 +0530 Subject: [PATCH 006/753] Split macros into helpers in Objective C Tests --- .../object_detector/MPPObjectDetectorTests.m | 139 +++++++++--------- 1 file changed, 73 insertions(+), 66 deletions(-) diff --git a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m index cb76de88e..67551c984 100644 --- a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m +++ b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m @@ -23,9 +23,8 @@ static NSDictionary *const kCatsAndDogsImage = @{@"name" : @"cats_and_dogs", @"t static NSDictionary *const kCatsAndDogsRotatedImage = @{@"name" : @"cats_and_dogs_rotated", @"type" : @"jpg"}; static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; - -#define PixelDifferenceTolerance 5.0f -#define ScoreDifferenceTolerance 1e-2f +static const float pixelDifferenceTolerance = 5.0f; +static const float scoreDifferenceTolerance = 1e-2f; #define AssertEqualErrors(error, expectedError) \ XCTAssertNotNil(error); \ @@ -35,59 +34,29 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; [error.localizedDescription rangeOfString:expectedError.localizedDescription].location, \ NSNotFound) -#define AssertEqualCategoryArrays(categories, expectedCategories, detectionIndex) \ - XCTAssertEqual(categories.count, expectedCategories.count); \ - for (int j = 0; j < categories.count; j++) { \ - XCTAssertEqual(categories[j].index, expectedCategories[j].index, \ - @"detection Index = %d category array index j = %d", detectionIndex, j); \ - XCTAssertEqualWithAccuracy( \ - categories[j].score, expectedCategories[j].score, ScoreDifferenceTolerance, \ - @"detection Index = %d, category array index j = %d", detectionIndex, j); \ - XCTAssertEqualObjects(categories[j].categoryName, expectedCategories[j].categoryName, \ - @"detection Index = %d, category array index j = %d", detectionIndex, \ - j); \ - XCTAssertEqualObjects(categories[j].displayName, expectedCategories[j].displayName, \ - @"detection Index = %d, category array index j = %d", detectionIndex, \ - j); \ - \ - \ - } +#define AssertEqualCategories(category, expectedCategory, detectionIndex, categoryIndex) \ + XCTAssertEqual(category.index, expectedCategory.index, \ + @"detection Index = %d category array index j = %d", detectionIndex, \ + categoryIndex); \ + XCTAssertEqualWithAccuracy(category.score, expectedCategory.score, scoreDifferenceTolerance, \ + @"detection Index = %d, category array index j = %d", detectionIndex, \ + categoryIndex); \ + XCTAssertEqualObjects(category.categoryName, expectedCategory.categoryName, \ + @"detection Index = %d, category array index j = %d", detectionIndex, \ + categoryIndex); \ + XCTAssertEqualObjects(category.displayName, expectedCategory.displayName, \ + @"detection Index = %d, category array index j = %d", detectionIndex, \ + categoryIndex); #define AssertApproximatelyEqualBoundingBoxes(boundingBox, expectedBoundingBox, idx) \ XCTAssertEqualWithAccuracy(boundingBox.origin.x, expectedBoundingBox.origin.x, \ - PixelDifferenceTolerance, @"index i = %d", idx); \ + pixelDifferenceTolerance, @"index i = %d", idx); \ XCTAssertEqualWithAccuracy(boundingBox.origin.y, expectedBoundingBox.origin.y, \ - PixelDifferenceTolerance, @"index i = %d", idx); \ + pixelDifferenceTolerance, @"index i = %d", idx); \ XCTAssertEqualWithAccuracy(boundingBox.size.width, expectedBoundingBox.size.width, \ - PixelDifferenceTolerance, @"index i = %d", idx); \ + pixelDifferenceTolerance, @"index i = %d", idx); \ XCTAssertEqualWithAccuracy(boundingBox.size.height, expectedBoundingBox.size.height, \ - PixelDifferenceTolerance, @"index i = %d", idx); - -#define AssertEqualDetections(detection, expectedDetection, idx) \ - XCTAssertNotNil(detection); \ - AssertEqualCategoryArrays(detection.categories, expectedDetection.categories, idx); \ - AssertApproximatelyEqualBoundingBoxes(detection.boundingBox, expectedDetection.boundingBox, idx); - -#define AssertEqualDetectionArrays(detections, expectedDetections) \ - XCTAssertEqual(detections.count, expectedDetections.count); \ - for (int i = 0; i < detections.count; i++) { \ - AssertEqualDetections(detections[i], expectedDetections[i], i); \ - } - -#define AssertEqualObjectDetectionResults(objectDetectionResult, expectedObjectDetectionResult, \ - expectedDetectionCount) \ - XCTAssertNotNil(objectDetectionResult); \ - NSArray *detectionsSubsetToCompare; \ - XCTAssertEqual(objectDetectionResult.detections.count, expectedDetectionCount); \ - if (objectDetectionResult.detections.count > expectedObjectDetectionResult.detections.count) { \ - detectionsSubsetToCompare = [objectDetectionResult.detections \ - subarrayWithRange:NSMakeRange(0, expectedObjectDetectionResult.detections.count)]; \ - } else { \ - detectionsSubsetToCompare = objectDetectionResult.detections; \ - } \ - \ - AssertEqualDetectionArrays(detectionsSubsetToCompare, expectedObjectDetectionResult.detections); \ - XCTAssertEqual(objectDetectionResult.timestampMs, expectedObjectDetectionResult.timestampMs); + pixelDifferenceTolerance, @"index i = %d", idx); @interface MPPObjectDetectorTests : XCTestCase @end @@ -124,6 +93,39 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; return [[MPPObjectDetectionResult alloc] initWithDetections:detections timestampMs:timestampMs]; } +- (void)assertDetections:(NSArray *)detections + isEqualToExpectedDetections:(NSArray *)expectedDetections { + for (int i = 0; i < detections.count; i++) { + MPPDetection *detection = detections[i]; + XCTAssertNotNil(detection); + for (int j = 0; j < detection.categories.count; j++) { + AssertEqualCategories(detection.categories[j], expectedDetections[i].categories[j], i, j); + } + AssertApproximatelyEqualBoundingBoxes(detection.boundingBox, expectedDetections[i].boundingBox, + i); + } +} + +- (void)assertObjectDetectionResult:(MPPObjectDetectionResult *)objectDetectionResult + isEqualToExpectedResult:(MPPObjectDetectionResult *)expectedObjectDetectionResult + expectedDetectionsCount:(NSInteger)expectedDetectionsCount { + XCTAssertNotNil(objectDetectionResult); + + NSArray *detectionsSubsetToCompare; + XCTAssertEqual(objectDetectionResult.detections.count, expectedDetectionsCount); + if (objectDetectionResult.detections.count > expectedObjectDetectionResult.detections.count) { + detectionsSubsetToCompare = [objectDetectionResult.detections + subarrayWithRange:NSMakeRange(0, expectedObjectDetectionResult.detections.count)]; + } else { + detectionsSubsetToCompare = objectDetectionResult.detections; + } + + [self assertDetections:detectionsSubsetToCompare + isEqualToExpectedDetections:expectedObjectDetectionResult.detections]; + + XCTAssertEqual(objectDetectionResult.timestampMs, expectedObjectDetectionResult.timestampMs); +} + #pragma mark File - (NSString *)filePathWithName:(NSString *)fileName extension:(NSString *)extension { @@ -189,9 +191,11 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; equalsObjectDetectionResult:(MPPObjectDetectionResult *)expectedObjectDetectionResult { MPPObjectDetectionResult *objectDetectionResult = [objectDetector detectInImage:mppImage error:nil]; - AssertEqualObjectDetectionResults( - objectDetectionResult, expectedObjectDetectionResult, - maxResults > 0 ? maxResults : objectDetectionResult.detections.count); + + [self assertObjectDetectionResult:objectDetectionResult + isEqualToExpectedResult:expectedObjectDetectionResult + expectedDetectionsCount:maxResults > 0 ? maxResults + : objectDetectionResult.detections.count]; } - (void)assertResultsOfDetectInImageWithFileInfo:(NSDictionary *)fileInfo @@ -604,10 +608,12 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; MPPObjectDetectionResult *objectDetectionResult = [objectDetector detectInVideoFrame:image timestampMs:i error:nil]; - AssertEqualObjectDetectionResults( - objectDetectionResult, - [MPPObjectDetectorTests expectedDetectionResultForCatsAndDogsImageWithTimestampMs:i], - maxResults); + + [self + assertObjectDetectionResult:objectDetectionResult + isEqualToExpectedResult:[MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampMs:i] + expectedDetectionsCount:maxResults]; } } @@ -624,10 +630,11 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; expectation.expectedFulfillmentCount = 1; options.completion = ^(MPPObjectDetectionResult *result, NSInteger timestampMs, NSError *error) { - AssertEqualObjectDetectionResults( - result, - [MPPObjectDetectorTests expectedDetectionResultForCatsAndDogsImageWithTimestampMs:1], - maxResults); + [self assertObjectDetectionResult:result + isEqualToExpectedResult: + [MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampMs:timestampMs] + expectedDetectionsCount:maxResults]; [expectation fulfill]; }; @@ -678,11 +685,11 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; expectation.inverted = YES; options.completion = ^(MPPObjectDetectionResult *result, NSInteger timestampMs, NSError *error) { - AssertEqualObjectDetectionResults( - result, - [MPPObjectDetectorTests - expectedDetectionResultForCatsAndDogsImageWithTimestampMs:timestampMs], - maxResults); + [self assertObjectDetectionResult:result + isEqualToExpectedResult: + [MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampMs:timestampMs] + expectedDetectionsCount:maxResults]; [expectation fulfill]; }; From 27353310c35aa8aaa14052f36e09b38f0653b395 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 11 Apr 2023 18:11:33 +0530 Subject: [PATCH 007/753] Updated normalized rect calculation for some angles in MPPVisionTaskRunner --- mediapipe/tasks/ios/vision/core/sources/MPPImage.h | 7 ++----- mediapipe/tasks/ios/vision/core/sources/MPPImage.m | 9 +++------ .../ios/vision/core/sources/MPPVisionTaskRunner.h | 3 +++ .../ios/vision/core/sources/MPPVisionTaskRunner.mm | 14 ++++++++++++-- .../object_detector/sources/MPPObjectDetector.mm | 2 ++ 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/mediapipe/tasks/ios/vision/core/sources/MPPImage.h b/mediapipe/tasks/ios/vision/core/sources/MPPImage.h index deffc97e2..db865b0e5 100644 --- a/mediapipe/tasks/ios/vision/core/sources/MPPImage.h +++ b/mediapipe/tasks/ios/vision/core/sources/MPPImage.h @@ -33,11 +33,8 @@ static const MPPImageSourceType MPPImageSourceTypeSampleBuffer = 2; NS_SWIFT_NAME(MPImage) @interface MPPImage : NSObject -/** Width of the image in pixels. */ -@property(nonatomic, readonly) CGFloat width; - -/** Height of the image in pixels. */ -@property(nonatomic, readonly) CGFloat height; +/** Size of the image in pixels. */ +@property(nonatomic, readonly) CGSize size; /** * The display orientation of the image. If `imageSourceType` is `MPPImageSourceTypeImage`, the diff --git a/mediapipe/tasks/ios/vision/core/sources/MPPImage.m b/mediapipe/tasks/ios/vision/core/sources/MPPImage.m index 1f5104ef7..c8bba9ace 100644 --- a/mediapipe/tasks/ios/vision/core/sources/MPPImage.m +++ b/mediapipe/tasks/ios/vision/core/sources/MPPImage.m @@ -46,8 +46,7 @@ NS_ASSUME_NONNULL_BEGIN _imageSourceType = MPPImageSourceTypeImage; _orientation = orientation; _image = image; - _width = image.size.width * image.scale; - _height = image.size.height * image.scale; + _size = CGSizeMake(image.size.width * image.scale, image.size.height * image.scale); } return self; } @@ -72,8 +71,7 @@ NS_ASSUME_NONNULL_BEGIN _orientation = orientation; CVPixelBufferRetain(pixelBuffer); _pixelBuffer = pixelBuffer; - _width = CVPixelBufferGetWidth(pixelBuffer); - _height = CVPixelBufferGetHeight(pixelBuffer); + _size = CGSizeMake(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer)); } return self; } @@ -105,8 +103,7 @@ NS_ASSUME_NONNULL_BEGIN _orientation = orientation; CFRetain(sampleBuffer); _sampleBuffer = sampleBuffer; - _width = CVPixelBufferGetWidth(imageBuffer); - _height = CVPixelBufferGetHeight(imageBuffer); + _size = CGSizeMake(CVPixelBufferGetWidth(imageBuffer), CVPixelBufferGetHeight(imageBuffer)); } return self; } diff --git a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h index a7216840c..92b5563ef 100644 --- a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h +++ b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h @@ -70,6 +70,8 @@ NS_ASSUME_NONNULL_BEGIN * @param roi A `CGRect` specifying the region of interest. If the input region of interest equals * `CGRectZero`, the returned `NormalizedRect` covers the whole image. Make sure that `roi` equals * `CGRectZero` if `ROIAllowed` is NO. Otherwise, an error will be returned. + * @param imageSize A `CGSize` specifying the size of the image within which normalized rect is + * calculated. * @param imageOrientation A `UIImageOrientation` indicating the rotation to be applied to the * image. The resulting `NormalizedRect` will convert the `imageOrientation` to degrees clockwise. * Mirrored orientations (`UIImageOrientationUpMirrored`, `UIImageOrientationDownMirrored`, @@ -83,6 +85,7 @@ NS_ASSUME_NONNULL_BEGIN */ - (std::optional) normalizedRectFromRegionOfInterest:(CGRect)roi + imageSize:(CGSize)imageSize imageOrientation:(UIImageOrientation)imageOrientation ROIAllowed:(BOOL)ROIAllowed error:(NSError **)error; diff --git a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm index 964cd38c7..893470481 100644 --- a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm +++ b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm @@ -86,6 +86,7 @@ static const NSInteger kMPPOrientationDegreesLeft = -270; } - (std::optional)normalizedRectFromRegionOfInterest:(CGRect)roi + imageSize:(CGSize)imageSize imageOrientation: (UIImageOrientation)imageOrientation ROIAllowed:(BOOL)ROIAllowed @@ -102,8 +103,6 @@ static const NSInteger kMPPOrientationDegreesLeft = -270; NormalizedRect normalizedRect; normalizedRect.set_x_center(CGRectGetMidX(calculatedRoi)); normalizedRect.set_y_center(CGRectGetMidY(calculatedRoi)); - normalizedRect.set_width(CGRectGetWidth(calculatedRoi)); - normalizedRect.set_height(CGRectGetHeight(calculatedRoi)); int rotationDegrees = 0; switch (imageOrientation) { @@ -134,6 +133,17 @@ static const NSInteger kMPPOrientationDegreesLeft = -270; normalizedRect.set_rotation(rotationDegrees * M_PI / kMPPOrientationDegreesDown); + if (rotationDegrees % 180 == 0) { + normalizedRect.set_width(CGRectGetWidth(calculatedRoi)); + normalizedRect.set_height(CGRectGetHeight(calculatedRoi)); + } else { + const float width = CGRectGetHeight(calculatedRoi) * imageSize.height / imageSize.width; + const float height = CGRectGetWidth(calculatedRoi) * imageSize.width / imageSize.height; + + normalizedRect.set_width(width); + normalizedRect.set_height(height); + } + return normalizedRect; } diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm index 499353558..16bcf5d7b 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm @@ -128,6 +128,7 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG error:(NSError **)error { std::optional rect = [_visionTaskRunner normalizedRectFromRegionOfInterest:CGRectZero + imageSize:image.size imageOrientation:image.orientation ROIAllowed:NO error:error]; @@ -152,6 +153,7 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG - (nullable MPPObjectDetectionResult *)detectInImage:(MPPImage *)image error:(NSError **)error { std::optional rect = [_visionTaskRunner normalizedRectFromRegionOfInterest:CGRectZero + imageSize:image.size imageOrientation:image.orientation ROIAllowed:YES error:error]; From 114a11dc4e87d4fc69a47e83ef27262694a386b4 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 11 Apr 2023 18:11:58 +0530 Subject: [PATCH 008/753] Updated iOS tests to reflect the new orientation calculation. --- .../test/vision/object_detector/MPPObjectDetectorTests.m | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m index 67551c984..e68b48f02 100644 --- a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m +++ b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m @@ -421,12 +421,9 @@ static const float scoreDifferenceTolerance = 1e-2f; NSArray *detections = @[ [[MPPDetection alloc] initWithCategories:@[ - [[MPPCategory alloc] initWithIndex:-1 - score:0.750000f - categoryName:@"teddy bear" - displayName:nil], + [[MPPCategory alloc] initWithIndex:-1 score:0.699219f categoryName:@"cat" displayName:nil], ] - boundingBox:CGRectMake(0, 372, 416, 276) + boundingBox:CGRectMake(0, 608, 439, 387) keypoints:nil], ]; From 0fcf92d7d5c2fac1cfb549bbf223f0bafd4bb20a Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 11 Apr 2023 18:18:35 +0530 Subject: [PATCH 009/753] Updated iOS Image Classifier to reflect new calculation for normalized rect --- .../image_classifier/MPPImageClassifierTests.m | 14 +++++++------- .../image_classifier/sources/MPPImageClassifier.mm | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m b/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m index f7b26837e..36a62d990 100644 --- a/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m +++ b/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m @@ -387,16 +387,16 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; NSArray *expectedCategories = @[ [[MPPCategory alloc] initWithIndex:934 - score:0.622074f + score:0.753852f categoryName:@"cheeseburger" displayName:nil], - [[MPPCategory alloc] initWithIndex:963 - score:0.051214f - categoryName:@"meat loaf" - displayName:nil], [[MPPCategory alloc] initWithIndex:925 - score:0.048719f + score:0.028609f categoryName:@"guacamole" + displayName:nil], + [[MPPCategory alloc] initWithIndex:932 + score:0.027782f + categoryName:@"bagel" displayName:nil] ]; @@ -420,7 +420,7 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; NSArray *expectedCategories = @[ [[MPPCategory alloc] initWithIndex:560 - score:0.682305f + score:0.604605f categoryName:@"folding chair" displayName:nil] ]; diff --git a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.mm b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.mm index 8051fbf3d..b9bde841c 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.mm +++ b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.mm @@ -120,6 +120,7 @@ static NSString *const kTaskGraphName = error:(NSError **)error { std::optional rect = [_visionTaskRunner normalizedRectFromRegionOfInterest:roi + imageSize:image.size imageOrientation:image.orientation ROIAllowed:YES error:error]; @@ -154,6 +155,7 @@ static NSString *const kTaskGraphName = error:(NSError **)error { std::optional rect = [_visionTaskRunner normalizedRectFromRegionOfInterest:roi + imageSize:image.size imageOrientation:image.orientation ROIAllowed:YES error:error]; From 3f68f90238a36521994c9ab5ee8500473f7f657d Mon Sep 17 00:00:00 2001 From: kinaryml Date: Wed, 12 Apr 2023 14:37:16 -0700 Subject: [PATCH 010/753] Deprecated output_type for the ImageSegmenter and InteractiveSegmenter APIs --- mediapipe/tasks/python/test/vision/BUILD | 19 ++ .../test/vision/image_segmenter_test.py | 194 ++++++++++++------ .../test/vision/interactive_segmenter_test.py | 29 ++- .../tasks/python/vision/image_segmenter.py | 96 ++++++--- .../python/vision/interactive_segmenter.py | 64 ++++-- mediapipe/tasks/testdata/vision/BUILD | 2 + 6 files changed, 272 insertions(+), 132 deletions(-) diff --git a/mediapipe/tasks/python/test/vision/BUILD b/mediapipe/tasks/python/test/vision/BUILD index 704e1af5c..46838c264 100644 --- a/mediapipe/tasks/python/test/vision/BUILD +++ b/mediapipe/tasks/python/test/vision/BUILD @@ -93,6 +93,25 @@ py_test( ], ) +py_test( + name = "interactive_segmenter_test", + srcs = ["interactive_segmenter_test.py"], + data = [ + "//mediapipe/tasks/testdata/vision:test_images", + "//mediapipe/tasks/testdata/vision:test_models", + ], + deps = [ + "//mediapipe/python:_framework_bindings", + "//mediapipe/tasks/python/components/containers:keypoint", + "//mediapipe/tasks/python/components/containers:rect", + "//mediapipe/tasks/python/core:base_options", + "//mediapipe/tasks/python/test:test_utils", + "//mediapipe/tasks/python/vision:interactive_segmenter", + "//mediapipe/tasks/python/vision/core:image_processing_options", + "//mediapipe/tasks/python/vision/core:vision_task_running_mode", + ], +) + py_test( name = "face_detector_test", srcs = ["face_detector_test.py"], diff --git a/mediapipe/tasks/python/test/vision/image_segmenter_test.py b/mediapipe/tasks/python/test/vision/image_segmenter_test.py index 7f0b47eb7..327925191 100644 --- a/mediapipe/tasks/python/test/vision/image_segmenter_test.py +++ b/mediapipe/tasks/python/test/vision/image_segmenter_test.py @@ -30,10 +30,10 @@ from mediapipe.tasks.python.test import test_utils from mediapipe.tasks.python.vision import image_segmenter from mediapipe.tasks.python.vision.core import vision_task_running_mode +ImageSegmenterResult = image_segmenter.ImageSegmenterResult _BaseOptions = base_options_module.BaseOptions _Image = image_module.Image _ImageFormat = image_frame.ImageFormat -_OutputType = image_segmenter.ImageSegmenterOptions.OutputType _Activation = image_segmenter.ImageSegmenterOptions.Activation _ImageSegmenter = image_segmenter.ImageSegmenter _ImageSegmenterOptions = image_segmenter.ImageSegmenterOptions @@ -42,11 +42,33 @@ _RUNNING_MODE = vision_task_running_mode.VisionTaskRunningMode _MODEL_FILE = 'deeplabv3.tflite' _IMAGE_FILE = 'segmentation_input_rotation0.jpg' _SEGMENTATION_FILE = 'segmentation_golden_rotation0.png' +_CAT_IMAGE = 'cat.jpg' +_CAT_MASK = 'cat_mask.jpg' _MASK_MAGNIFICATION_FACTOR = 10 _MASK_SIMILARITY_THRESHOLD = 0.98 _TEST_DATA_DIR = 'mediapipe/tasks/testdata/vision' +def _calculate_soft_iou(m1, m2): + intersection_sum = np.sum(m1 * m2) + union_sum = np.sum(m1 * m1) + np.sum(m2 * m2) - intersection_sum + + if union_sum > 0: + return intersection_sum / union_sum + else: + return 0 + + +def _similar_to_float_mask(actual_mask, expected_mask, similarity_threshold): + actual_mask = actual_mask.numpy_view() + expected_mask = expected_mask.numpy_view() / 255.0 + + return ( + actual_mask.shape == expected_mask.shape + and _calculate_soft_iou(actual_mask, expected_mask) > similarity_threshold + ) + + def _similar_to_uint8_mask(actual_mask, expected_mask): actual_mask_pixels = actual_mask.numpy_view().flatten() expected_mask_pixels = expected_mask.numpy_view().flatten() @@ -84,6 +106,14 @@ class ImageSegmenterTest(parameterized.TestCase): self.model_path = test_utils.get_test_data_path( os.path.join(_TEST_DATA_DIR, _MODEL_FILE)) + def _load_segmentation_mask(self, file_path: str): + # Loads ground truth segmentation file. + gt_segmentation_data = cv2.imread( + test_utils.get_test_data_path(os.path.join(_TEST_DATA_DIR, file_path)), + cv2.IMREAD_GRAYSCALE, + ) + return _Image(_ImageFormat.GRAY8, gt_segmentation_data) + def test_create_from_file_succeeds_with_valid_model_path(self): # Creates with default option and valid model file successfully. with _ImageSegmenter.create_from_model_path(self.model_path) as segmenter: @@ -127,20 +157,19 @@ class ImageSegmenterTest(parameterized.TestCase): raise ValueError('model_file_type is invalid.') options = _ImageSegmenterOptions( - base_options=base_options, output_type=_OutputType.CATEGORY_MASK) + base_options=base_options, output_category_mask=True) segmenter = _ImageSegmenter.create_from_options(options) # Performs image segmentation on the input. - category_masks = segmenter.segment(self.test_image) - self.assertLen(category_masks, 1) - category_mask = category_masks[0] + segmentation_result = segmenter.segment(self.test_image) + category_mask = segmentation_result.category_mask result_pixels = category_mask.numpy_view().flatten() # Check if data type of `category_mask` is correct. self.assertEqual(result_pixels.dtype, np.uint8) self.assertTrue( - _similar_to_uint8_mask(category_masks[0], self.test_seg_image), + _similar_to_uint8_mask(category_mask, self.test_seg_image), f'Number of pixels in the candidate mask differing from that of the ' f'ground truth mask exceeds {_MASK_SIMILARITY_THRESHOLD}.') @@ -152,67 +181,33 @@ class ImageSegmenterTest(parameterized.TestCase): # Creates segmenter. base_options = _BaseOptions(model_asset_path=self.model_path) - # Run segmentation on the model in CATEGORY_MASK mode. - options = _ImageSegmenterOptions( - base_options=base_options, output_type=_OutputType.CATEGORY_MASK) - segmenter = _ImageSegmenter.create_from_options(options) - category_masks = segmenter.segment(self.test_image) - category_mask = category_masks[0].numpy_view() + # Load the cat image. + test_image = _Image.create_from_file( + test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, _CAT_IMAGE))) # Run segmentation on the model in CONFIDENCE_MASK mode. options = _ImageSegmenterOptions( base_options=base_options, - output_type=_OutputType.CONFIDENCE_MASK, activation=_Activation.SOFTMAX) - segmenter = _ImageSegmenter.create_from_options(options) - confidence_masks = segmenter.segment(self.test_image) - # Check if confidence mask shape is correct. - self.assertLen( - confidence_masks, 21, - 'Number of confidence masks must match with number of categories.') - - # Gather the confidence masks in a single array `confidence_mask_array`. - confidence_mask_array = np.array( - [confidence_mask.numpy_view() for confidence_mask in confidence_masks]) - - # Check if data type of `confidence_masks` are correct. - self.assertEqual(confidence_mask_array.dtype, np.float32) - - # Compute the category mask from the created confidence mask. - calculated_category_mask = np.argmax(confidence_mask_array, axis=0) - self.assertListEqual( - calculated_category_mask.tolist(), category_mask.tolist(), - 'Confidence mask does not match with the category mask.') - - # Closes the segmenter explicitly when the segmenter is not used in - # a context. - segmenter.close() - - @parameterized.parameters((ModelFileType.FILE_NAME), - (ModelFileType.FILE_CONTENT)) - def test_segment_in_context(self, model_file_type): - if model_file_type is ModelFileType.FILE_NAME: - base_options = _BaseOptions(model_asset_path=self.model_path) - elif model_file_type is ModelFileType.FILE_CONTENT: - with open(self.model_path, 'rb') as f: - model_contents = f.read() - base_options = _BaseOptions(model_asset_buffer=model_contents) - else: - # Should never happen - raise ValueError('model_file_type is invalid.') - - options = _ImageSegmenterOptions( - base_options=base_options, output_type=_OutputType.CATEGORY_MASK) with _ImageSegmenter.create_from_options(options) as segmenter: - # Performs image segmentation on the input. - category_masks = segmenter.segment(self.test_image) - self.assertLen(category_masks, 1) + segmentation_result = segmenter.segment(test_image) + confidence_masks = segmentation_result.confidence_masks + + # Check if confidence mask shape is correct. + self.assertLen( + confidence_masks, 21, + 'Number of confidence masks must match with number of categories.') + + # Loads ground truth segmentation file. + expected_mask = self._load_segmentation_mask(_CAT_MASK) self.assertTrue( - _similar_to_uint8_mask(category_masks[0], self.test_seg_image), - f'Number of pixels in the candidate mask differing from that of the ' - f'ground truth mask exceeds {_MASK_SIMILARITY_THRESHOLD}.') + _similar_to_float_mask( + confidence_masks[8], expected_mask, _MASK_SIMILARITY_THRESHOLD + ) + ) def test_missing_result_callback(self): options = _ImageSegmenterOptions( @@ -280,20 +275,49 @@ class ImageSegmenterTest(parameterized.TestCase): ValueError, r'Input timestamp must be monotonically increasing'): segmenter.segment_for_video(self.test_image, 0) - def test_segment_for_video(self): + def test_segment_for_video_in_category_mask_mode(self): options = _ImageSegmenterOptions( base_options=_BaseOptions(model_asset_path=self.model_path), - output_type=_OutputType.CATEGORY_MASK, + output_category_mask=True, running_mode=_RUNNING_MODE.VIDEO) with _ImageSegmenter.create_from_options(options) as segmenter: for timestamp in range(0, 300, 30): - category_masks = segmenter.segment_for_video(self.test_image, timestamp) - self.assertLen(category_masks, 1) + segmentation_result = segmenter.segment_for_video( + self.test_image, timestamp) + category_mask = segmentation_result.category_mask self.assertTrue( - _similar_to_uint8_mask(category_masks[0], self.test_seg_image), + _similar_to_uint8_mask(category_mask, self.test_seg_image), f'Number of pixels in the candidate mask differing from that of the ' f'ground truth mask exceeds {_MASK_SIMILARITY_THRESHOLD}.') + def test_segment_for_video_in_confidence_mask_mode(self): + # Load the cat image. + test_image = _Image.create_from_file( + test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, _CAT_IMAGE))) + + options = _ImageSegmenterOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.VIDEO) + with _ImageSegmenter.create_from_options(options) as segmenter: + for timestamp in range(0, 300, 30): + segmentation_result = segmenter.segment_for_video( + test_image, timestamp) + confidence_masks = segmentation_result.confidence_masks + + # Check if confidence mask shape is correct. + self.assertLen( + confidence_masks, 21, + 'Number of confidence masks must match with number of categories.') + + # Loads ground truth segmentation file. + expected_mask = self._load_segmentation_mask(_CAT_MASK) + self.assertTrue( + _similar_to_float_mask( + confidence_masks[8], expected_mask, _MASK_SIMILARITY_THRESHOLD + ) + ) + def test_calling_segment_in_live_stream_mode(self): options = _ImageSegmenterOptions( base_options=_BaseOptions(model_asset_path=self.model_path), @@ -325,13 +349,13 @@ class ImageSegmenterTest(parameterized.TestCase): ValueError, r'Input timestamp must be monotonically increasing'): segmenter.segment_async(self.test_image, 0) - def test_segment_async_calls(self): + def test_segment_async_calls_in_category_mask_mode(self): observed_timestamp_ms = -1 - def check_result(result: List[image_module.Image], output_image: _Image, + def check_result(result: ImageSegmenterResult, output_image: _Image, timestamp_ms: int): # Get the output category mask. - category_mask = result[0] + category_mask = result.category_mask self.assertEqual(output_image.width, self.test_image.width) self.assertEqual(output_image.height, self.test_image.height) self.assertEqual(output_image.width, self.test_seg_image.width) @@ -345,13 +369,49 @@ class ImageSegmenterTest(parameterized.TestCase): options = _ImageSegmenterOptions( base_options=_BaseOptions(model_asset_path=self.model_path), - output_type=_OutputType.CATEGORY_MASK, + output_category_mask=True, running_mode=_RUNNING_MODE.LIVE_STREAM, result_callback=check_result) with _ImageSegmenter.create_from_options(options) as segmenter: for timestamp in range(0, 300, 30): segmenter.segment_async(self.test_image, timestamp) + def test_segment_async_calls_in_confidence_mask_mode(self): + # Load the cat image. + test_image = _Image.create_from_file( + test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, _CAT_IMAGE))) + + # Loads ground truth segmentation file. + expected_mask = self._load_segmentation_mask(_CAT_MASK) + observed_timestamp_ms = -1 + + def check_result(result: ImageSegmenterResult, output_image: _Image, + timestamp_ms: int): + # Get the output category mask. + confidence_masks = result.confidence_masks + + # Check if confidence mask shape is correct. + self.assertLen( + confidence_masks, 21, + 'Number of confidence masks must match with number of categories.') + + self.assertTrue( + _similar_to_float_mask( + confidence_masks[8], expected_mask, _MASK_SIMILARITY_THRESHOLD + ) + ) + self.assertLess(observed_timestamp_ms, timestamp_ms) + self.observed_timestamp_ms = timestamp_ms + + options = _ImageSegmenterOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.LIVE_STREAM, + result_callback=check_result) + with _ImageSegmenter.create_from_options(options) as segmenter: + for timestamp in range(0, 300, 30): + segmenter.segment_async(test_image, timestamp) + if __name__ == '__main__': absltest.main() diff --git a/mediapipe/tasks/python/test/vision/interactive_segmenter_test.py b/mediapipe/tasks/python/test/vision/interactive_segmenter_test.py index e8c52ae3e..6af15aa09 100644 --- a/mediapipe/tasks/python/test/vision/interactive_segmenter_test.py +++ b/mediapipe/tasks/python/test/vision/interactive_segmenter_test.py @@ -30,12 +30,12 @@ from mediapipe.tasks.python.test import test_utils from mediapipe.tasks.python.vision import interactive_segmenter from mediapipe.tasks.python.vision.core import image_processing_options as image_processing_options_module +InteractiveSegmenterResult = interactive_segmenter.InteractiveSegmenterResult _BaseOptions = base_options_module.BaseOptions _Image = image_module.Image _ImageFormat = image_frame.ImageFormat _NormalizedKeypoint = keypoint_module.NormalizedKeypoint _Rect = rect.Rect -_OutputType = interactive_segmenter.InteractiveSegmenterOptions.OutputType _InteractiveSegmenter = interactive_segmenter.InteractiveSegmenter _InteractiveSegmenterOptions = interactive_segmenter.InteractiveSegmenterOptions _RegionOfInterest = interactive_segmenter.RegionOfInterest @@ -200,15 +200,14 @@ class InteractiveSegmenterTest(parameterized.TestCase): raise ValueError('model_file_type is invalid.') options = _InteractiveSegmenterOptions( - base_options=base_options, output_type=_OutputType.CATEGORY_MASK + base_options=base_options, output_category_mask=True ) segmenter = _InteractiveSegmenter.create_from_options(options) # Performs image segmentation on the input. roi = _RegionOfInterest(format=roi_format, keypoint=keypoint) - category_masks = segmenter.segment(self.test_image, roi) - self.assertLen(category_masks, 1) - category_mask = category_masks[0] + segmentation_result = segmenter.segment(self.test_image, roi) + category_mask = segmentation_result.category_mask result_pixels = category_mask.numpy_view().flatten() # Check if data type of `category_mask` is correct. @@ -219,7 +218,7 @@ class InteractiveSegmenterTest(parameterized.TestCase): self.assertTrue( _similar_to_uint8_mask( - category_masks[0], test_seg_image, similarity_threshold + category_mask, test_seg_image, similarity_threshold ), ( 'Number of pixels in the candidate mask differing from that of the' @@ -253,13 +252,12 @@ class InteractiveSegmenterTest(parameterized.TestCase): roi = _RegionOfInterest(format=roi_format, keypoint=keypoint) # Run segmentation on the model in CONFIDENCE_MASK mode. - options = _InteractiveSegmenterOptions( - base_options=base_options, output_type=_OutputType.CONFIDENCE_MASK - ) + options = _InteractiveSegmenterOptions(base_options=base_options) with _InteractiveSegmenter.create_from_options(options) as segmenter: # Perform segmentation - confidence_masks = segmenter.segment(self.test_image, roi) + segmentation_result = segmenter.segment(self.test_image, roi) + confidence_masks = segmentation_result.confidence_masks # Check if confidence mask shape is correct. self.assertLen( @@ -286,16 +284,15 @@ class InteractiveSegmenterTest(parameterized.TestCase): ) # Run segmentation on the model in CONFIDENCE_MASK mode. - options = _InteractiveSegmenterOptions( - base_options=base_options, output_type=_OutputType.CONFIDENCE_MASK - ) + options = _InteractiveSegmenterOptions(base_options=base_options) with _InteractiveSegmenter.create_from_options(options) as segmenter: # Perform segmentation image_processing_options = _ImageProcessingOptions(rotation_degrees=-90) - confidence_masks = segmenter.segment( + segmentation_result = segmenter.segment( self.test_image, roi, image_processing_options ) + confidence_masks = segmentation_result.confidence_masks # Check if confidence mask shape is correct. self.assertLen( @@ -313,9 +310,7 @@ class InteractiveSegmenterTest(parameterized.TestCase): ) # Run segmentation on the model in CONFIDENCE_MASK mode. - options = _InteractiveSegmenterOptions( - base_options=base_options, output_type=_OutputType.CONFIDENCE_MASK - ) + options = _InteractiveSegmenterOptions(base_options=base_options) with self.assertRaisesRegex( ValueError, "This task doesn't support region-of-interest." diff --git a/mediapipe/tasks/python/vision/image_segmenter.py b/mediapipe/tasks/python/vision/image_segmenter.py index e50ffbf79..102773173 100644 --- a/mediapipe/tasks/python/vision/image_segmenter.py +++ b/mediapipe/tasks/python/vision/image_segmenter.py @@ -31,7 +31,6 @@ from mediapipe.tasks.python.vision.core import base_vision_task_api from mediapipe.tasks.python.vision.core import image_processing_options as image_processing_options_module from mediapipe.tasks.python.vision.core import vision_task_running_mode -ImageSegmenterResult = List[image_module.Image] _NormalizedRect = rect.NormalizedRect _BaseOptions = base_options_module.BaseOptions _SegmenterOptionsProto = segmenter_options_pb2.SegmenterOptions @@ -42,8 +41,10 @@ _RunningMode = vision_task_running_mode.VisionTaskRunningMode _ImageProcessingOptions = image_processing_options_module.ImageProcessingOptions _TaskInfo = task_info_module.TaskInfo -_SEGMENTATION_OUT_STREAM_NAME = 'segmented_mask_out' -_SEGMENTATION_TAG = 'GROUPED_SEGMENTATION' +_CONFIDENCE_MASKS_STREAM_NAME = 'confidence_masks' +_CONFIDENCE_MASKS_TAG = 'CONFIDENCE_MASKS' +_CATEGORY_MASK_STREAM_NAME = 'category_mask' +_CATEGORY_MASK_TAG = 'CATEGORY_MASK' _IMAGE_IN_STREAM_NAME = 'image_in' _IMAGE_OUT_STREAM_NAME = 'image_out' _IMAGE_TAG = 'IMAGE' @@ -53,6 +54,12 @@ _TASK_GRAPH_NAME = 'mediapipe.tasks.vision.image_segmenter.ImageSegmenterGraph' _MICRO_SECONDS_PER_MILLISECOND = 1000 +@dataclasses.dataclass +class ImageSegmenterResult: + confidence_masks: Optional[List[image_module.Image]] = None + category_mask: Optional[image_module.Image] = None + + @dataclasses.dataclass class ImageSegmenterOptions: """Options for the image segmenter task. @@ -64,19 +71,13 @@ class ImageSegmenterOptions: objects on single image inputs. 2) The video mode for segmenting objects on the decoded frames of a video. 3) The live stream mode for segmenting objects on a live stream of input data, such as from camera. - output_type: The output mask type allows specifying the type of - post-processing to perform on the raw model results. - activation: Activation function to apply to input tensor. + output_confidence_masks: Whether to output confidence masks. + output_category_mask: Whether to output category mask. result_callback: The user-defined result callback for processing live stream data. The result callback should only be specified when the running mode is set to the live stream mode. """ - class OutputType(enum.Enum): - UNSPECIFIED = 0 - CATEGORY_MASK = 1 - CONFIDENCE_MASK = 2 - class Activation(enum.Enum): NONE = 0 SIGMOID = 1 @@ -84,7 +85,8 @@ class ImageSegmenterOptions: base_options: _BaseOptions running_mode: _RunningMode = _RunningMode.IMAGE - output_type: Optional[OutputType] = OutputType.CATEGORY_MASK + output_confidence_masks: bool = True + output_category_mask: bool = False activation: Optional[Activation] = Activation.NONE result_callback: Optional[ Callable[[ImageSegmenterResult, image_module.Image, int], None] @@ -98,7 +100,7 @@ class ImageSegmenterOptions: False if self.running_mode == _RunningMode.IMAGE else True ) segmenter_options_proto = _SegmenterOptionsProto( - output_type=self.output_type.value, activation=self.activation.value + activation=self.activation.value ) return _ImageSegmenterGraphOptionsProto( base_options=base_options_proto, @@ -177,27 +179,48 @@ class ImageSegmenter(base_vision_task_api.BaseVisionTaskApi): def packets_callback(output_packets: Mapping[str, packet.Packet]): if output_packets[_IMAGE_OUT_STREAM_NAME].is_empty(): return - segmentation_result = packet_getter.get_image_list( - output_packets[_SEGMENTATION_OUT_STREAM_NAME] - ) + + segmentation_result = ImageSegmenterResult() + + if options.output_confidence_masks: + segmentation_result.confidence_masks = packet_getter.get_image_list( + output_packets[_CONFIDENCE_MASKS_STREAM_NAME] + ) + + if options.output_category_mask: + segmentation_result.category_mask = packet_getter.get_image( + output_packets[_CATEGORY_MASK_STREAM_NAME] + ) + image = packet_getter.get_image(output_packets[_IMAGE_OUT_STREAM_NAME]) - timestamp = output_packets[_SEGMENTATION_OUT_STREAM_NAME].timestamp + timestamp = output_packets[_IMAGE_OUT_STREAM_NAME].timestamp options.result_callback( segmentation_result, image, timestamp.value // _MICRO_SECONDS_PER_MILLISECOND, ) + output_streams = [ + ':'.join([_IMAGE_TAG, _IMAGE_OUT_STREAM_NAME]), + ] + + if options.output_confidence_masks: + output_streams.append( + ':'.join([_CONFIDENCE_MASKS_TAG, _CONFIDENCE_MASKS_STREAM_NAME]) + ) + + if options.output_category_mask: + output_streams.append( + ':'.join([_CATEGORY_MASK_TAG, _CATEGORY_MASK_STREAM_NAME]) + ) + task_info = _TaskInfo( task_graph=_TASK_GRAPH_NAME, input_streams=[ ':'.join([_IMAGE_TAG, _IMAGE_IN_STREAM_NAME]), ':'.join([_NORM_RECT_TAG, _NORM_RECT_STREAM_NAME]), ], - output_streams=[ - ':'.join([_SEGMENTATION_TAG, _SEGMENTATION_OUT_STREAM_NAME]), - ':'.join([_IMAGE_TAG, _IMAGE_OUT_STREAM_NAME]), - ], + output_streams=output_streams, task_options=options, ) return cls( @@ -240,9 +263,18 @@ class ImageSegmenter(base_vision_task_api.BaseVisionTaskApi): normalized_rect.to_pb2() ), }) - segmentation_result = packet_getter.get_image_list( - output_packets[_SEGMENTATION_OUT_STREAM_NAME] - ) + segmentation_result = ImageSegmenterResult() + + if _CONFIDENCE_MASKS_STREAM_NAME in output_packets: + segmentation_result.confidence_masks = packet_getter.get_image_list( + output_packets[_CONFIDENCE_MASKS_STREAM_NAME] + ) + + if _CATEGORY_MASK_STREAM_NAME in output_packets: + segmentation_result.category_mask = packet_getter.get_image( + output_packets[_CATEGORY_MASK_STREAM_NAME] + ) + return segmentation_result def segment_for_video( @@ -285,9 +317,19 @@ class ImageSegmenter(base_vision_task_api.BaseVisionTaskApi): normalized_rect.to_pb2() ).at(timestamp_ms * _MICRO_SECONDS_PER_MILLISECOND), }) - segmentation_result = packet_getter.get_image_list( - output_packets[_SEGMENTATION_OUT_STREAM_NAME] - ) + segmentation_result = ImageSegmenterResult() + + if _CONFIDENCE_MASKS_STREAM_NAME in output_packets: + segmentation_result.confidence_masks = packet_getter.get_image_list( + output_packets[_CONFIDENCE_MASKS_STREAM_NAME] + ) + + if _CATEGORY_MASK_STREAM_NAME in output_packets: + segmentation_result.category_mask = packet_getter.get_image( + output_packets[_CATEGORY_MASK_STREAM_NAME] + ) + + return segmentation_result def segment_async( diff --git a/mediapipe/tasks/python/vision/interactive_segmenter.py b/mediapipe/tasks/python/vision/interactive_segmenter.py index 12a30b6ef..6f423d76c 100644 --- a/mediapipe/tasks/python/vision/interactive_segmenter.py +++ b/mediapipe/tasks/python/vision/interactive_segmenter.py @@ -41,8 +41,10 @@ _RunningMode = vision_task_running_mode.VisionTaskRunningMode _ImageProcessingOptions = image_processing_options_module.ImageProcessingOptions _TaskInfo = task_info_module.TaskInfo -_SEGMENTATION_OUT_STREAM_NAME = 'segmented_mask_out' -_SEGMENTATION_TAG = 'GROUPED_SEGMENTATION' +_CONFIDENCE_MASKS_STREAM_NAME = 'confidence_masks' +_CONFIDENCE_MASKS_TAG = 'CONFIDENCE_MASKS' +_CATEGORY_MASK_STREAM_NAME = 'category_mask' +_CATEGORY_MASK_TAG = 'CATEGORY_MASK' _IMAGE_IN_STREAM_NAME = 'image_in' _IMAGE_OUT_STREAM_NAME = 'image_out' _ROI_STREAM_NAME = 'roi_in' @@ -55,32 +57,32 @@ _TASK_GRAPH_NAME = ( ) +@dataclasses.dataclass +class InteractiveSegmenterResult: + confidence_masks: Optional[List[image_module.Image]] = None + category_mask: Optional[image_module.Image] = None + + @dataclasses.dataclass class InteractiveSegmenterOptions: """Options for the interactive segmenter task. Attributes: base_options: Base options for the interactive segmenter task. - output_type: The output mask type allows specifying the type of - post-processing to perform on the raw model results. + output_confidence_masks: Whether to output confidence masks. + output_category_mask: Whether to output category mask. """ - class OutputType(enum.Enum): - UNSPECIFIED = 0 - CATEGORY_MASK = 1 - CONFIDENCE_MASK = 2 - base_options: _BaseOptions - output_type: Optional[OutputType] = OutputType.CATEGORY_MASK + output_confidence_masks: bool = True + output_category_mask: bool = False @doc_controls.do_not_generate_docs def to_pb2(self) -> _ImageSegmenterGraphOptionsProto: """Generates an InteractiveSegmenterOptions protobuf object.""" base_options_proto = self.base_options.to_pb2() base_options_proto.use_stream_mode = False - segmenter_options_proto = _SegmenterOptionsProto( - output_type=self.output_type.value - ) + segmenter_options_proto = _SegmenterOptionsProto() return _ImageSegmenterGraphOptionsProto( base_options=base_options_proto, segmenter_options=segmenter_options_proto, @@ -192,6 +194,20 @@ class InteractiveSegmenter(base_vision_task_api.BaseVisionTaskApi): RuntimeError: If other types of error occurred. """ + output_streams = [ + ':'.join([_IMAGE_TAG, _IMAGE_OUT_STREAM_NAME]), + ] + + if options.output_confidence_masks: + output_streams.append( + ':'.join([_CONFIDENCE_MASKS_TAG, _CONFIDENCE_MASKS_STREAM_NAME]) + ) + + if options.output_category_mask: + output_streams.append( + ':'.join([_CATEGORY_MASK_TAG, _CATEGORY_MASK_STREAM_NAME]) + ) + task_info = _TaskInfo( task_graph=_TASK_GRAPH_NAME, input_streams=[ @@ -199,10 +215,7 @@ class InteractiveSegmenter(base_vision_task_api.BaseVisionTaskApi): ':'.join([_ROI_TAG, _ROI_STREAM_NAME]), ':'.join([_NORM_RECT_TAG, _NORM_RECT_STREAM_NAME]), ], - output_streams=[ - ':'.join([_SEGMENTATION_TAG, _SEGMENTATION_OUT_STREAM_NAME]), - ':'.join([_IMAGE_TAG, _IMAGE_OUT_STREAM_NAME]), - ], + output_streams=output_streams, task_options=options, ) return cls( @@ -216,7 +229,7 @@ class InteractiveSegmenter(base_vision_task_api.BaseVisionTaskApi): image: image_module.Image, roi: RegionOfInterest, image_processing_options: Optional[_ImageProcessingOptions] = None, - ) -> List[image_module.Image]: + ) -> InteractiveSegmenterResult: """Performs the actual segmentation task on the provided MediaPipe Image. The image can be of any size with format RGB. @@ -248,7 +261,16 @@ class InteractiveSegmenter(base_vision_task_api.BaseVisionTaskApi): normalized_rect.to_pb2() ), }) - segmentation_result = packet_getter.get_image_list( - output_packets[_SEGMENTATION_OUT_STREAM_NAME] - ) + segmentation_result = InteractiveSegmenterResult() + + if _CONFIDENCE_MASKS_STREAM_NAME in output_packets: + segmentation_result.confidence_masks = packet_getter.get_image_list( + output_packets[_CONFIDENCE_MASKS_STREAM_NAME] + ) + + if _CATEGORY_MASK_STREAM_NAME in output_packets: + segmentation_result.category_mask = packet_getter.get_image( + output_packets[_CATEGORY_MASK_STREAM_NAME] + ) + return segmentation_result diff --git a/mediapipe/tasks/testdata/vision/BUILD b/mediapipe/tasks/testdata/vision/BUILD index 0de0c255c..23dc3ed5f 100644 --- a/mediapipe/tasks/testdata/vision/BUILD +++ b/mediapipe/tasks/testdata/vision/BUILD @@ -77,6 +77,7 @@ mediapipe_files(srcs = [ "portrait_selfie_segmentation_landscape_expected_category_mask.jpg", "pose.jpg", "pose_detection.tflite", + "ptm_512_hdt_ptm_woid.tflite", "pose_landmark_lite.tflite", "pose_landmarker.task", "right_hands.jpg", @@ -187,6 +188,7 @@ filegroup( "mobilenet_v3_small_100_224_embedder.tflite", "palm_detection_full.tflite", "pose_detection.tflite", + "ptm_512_hdt_ptm_woid.tflite", "pose_landmark_lite.tflite", "pose_landmarker.task", "selfie_segm_128_128_3.tflite", From a03fa448dc09d75da7f5eecae16a1a2909a46df6 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Thu, 13 Apr 2023 11:55:37 -0700 Subject: [PATCH 011/753] Explicitly state the modes in the tests for ImageSegmenterOptions and InteractiveSegmenterOptions --- .../test/vision/image_segmenter_test.py | 32 +++++++++++++------ .../test/vision/interactive_segmenter_test.py | 18 ++++++++--- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/mediapipe/tasks/python/test/vision/image_segmenter_test.py b/mediapipe/tasks/python/test/vision/image_segmenter_test.py index 327925191..aa557281f 100644 --- a/mediapipe/tasks/python/test/vision/image_segmenter_test.py +++ b/mediapipe/tasks/python/test/vision/image_segmenter_test.py @@ -157,7 +157,9 @@ class ImageSegmenterTest(parameterized.TestCase): raise ValueError('model_file_type is invalid.') options = _ImageSegmenterOptions( - base_options=base_options, output_category_mask=True) + base_options=base_options, output_category_mask=True, + output_confidence_masks=False + ) segmenter = _ImageSegmenter.create_from_options(options) # Performs image segmentation on the input. @@ -188,8 +190,9 @@ class ImageSegmenterTest(parameterized.TestCase): # Run segmentation on the model in CONFIDENCE_MASK mode. options = _ImageSegmenterOptions( - base_options=base_options, - activation=_Activation.SOFTMAX) + base_options=base_options, output_category_mask=False, + output_confidence_masks=True, activation=_Activation.SOFTMAX + ) with _ImageSegmenter.create_from_options(options) as segmenter: segmentation_result = segmenter.segment(test_image) @@ -279,7 +282,9 @@ class ImageSegmenterTest(parameterized.TestCase): options = _ImageSegmenterOptions( base_options=_BaseOptions(model_asset_path=self.model_path), output_category_mask=True, - running_mode=_RUNNING_MODE.VIDEO) + output_confidence_masks=False, + running_mode=_RUNNING_MODE.VIDEO + ) with _ImageSegmenter.create_from_options(options) as segmenter: for timestamp in range(0, 300, 30): segmentation_result = segmenter.segment_for_video( @@ -297,8 +302,10 @@ class ImageSegmenterTest(parameterized.TestCase): os.path.join(_TEST_DATA_DIR, _CAT_IMAGE))) options = _ImageSegmenterOptions( - base_options=_BaseOptions(model_asset_path=self.model_path), - running_mode=_RUNNING_MODE.VIDEO) + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.VIDEO, output_category_mask=False, + output_confidence_masks=True + ) with _ImageSegmenter.create_from_options(options) as segmenter: for timestamp in range(0, 300, 30): segmentation_result = segmenter.segment_for_video( @@ -370,8 +377,10 @@ class ImageSegmenterTest(parameterized.TestCase): options = _ImageSegmenterOptions( base_options=_BaseOptions(model_asset_path=self.model_path), output_category_mask=True, + output_confidence_masks=False, running_mode=_RUNNING_MODE.LIVE_STREAM, - result_callback=check_result) + result_callback=check_result + ) with _ImageSegmenter.create_from_options(options) as segmenter: for timestamp in range(0, 300, 30): segmenter.segment_async(self.test_image, timestamp) @@ -405,9 +414,12 @@ class ImageSegmenterTest(parameterized.TestCase): self.observed_timestamp_ms = timestamp_ms options = _ImageSegmenterOptions( - base_options=_BaseOptions(model_asset_path=self.model_path), - running_mode=_RUNNING_MODE.LIVE_STREAM, - result_callback=check_result) + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.LIVE_STREAM, + output_category_mask=False, + output_confidence_masks=True, + result_callback=check_result + ) with _ImageSegmenter.create_from_options(options) as segmenter: for timestamp in range(0, 300, 30): segmenter.segment_async(test_image, timestamp) diff --git a/mediapipe/tasks/python/test/vision/interactive_segmenter_test.py b/mediapipe/tasks/python/test/vision/interactive_segmenter_test.py index 6af15aa09..aea4f8a1d 100644 --- a/mediapipe/tasks/python/test/vision/interactive_segmenter_test.py +++ b/mediapipe/tasks/python/test/vision/interactive_segmenter_test.py @@ -200,7 +200,8 @@ class InteractiveSegmenterTest(parameterized.TestCase): raise ValueError('model_file_type is invalid.') options = _InteractiveSegmenterOptions( - base_options=base_options, output_category_mask=True + base_options=base_options, output_category_mask=True, + output_confidence_masks=False ) segmenter = _InteractiveSegmenter.create_from_options(options) @@ -252,7 +253,10 @@ class InteractiveSegmenterTest(parameterized.TestCase): roi = _RegionOfInterest(format=roi_format, keypoint=keypoint) # Run segmentation on the model in CONFIDENCE_MASK mode. - options = _InteractiveSegmenterOptions(base_options=base_options) + options = _InteractiveSegmenterOptions( + base_options=base_options, output_category_mask=False, + output_confidence_masks=True + ) with _InteractiveSegmenter.create_from_options(options) as segmenter: # Perform segmentation @@ -284,7 +288,10 @@ class InteractiveSegmenterTest(parameterized.TestCase): ) # Run segmentation on the model in CONFIDENCE_MASK mode. - options = _InteractiveSegmenterOptions(base_options=base_options) + options = _InteractiveSegmenterOptions( + base_options=base_options, output_category_mask=False, + output_confidence_masks=True + ) with _InteractiveSegmenter.create_from_options(options) as segmenter: # Perform segmentation @@ -310,7 +317,10 @@ class InteractiveSegmenterTest(parameterized.TestCase): ) # Run segmentation on the model in CONFIDENCE_MASK mode. - options = _InteractiveSegmenterOptions(base_options=base_options) + options = _InteractiveSegmenterOptions( + base_options=base_options, output_category_mask=False, + output_confidence_masks=True + ) with self.assertRaisesRegex( ValueError, "This task doesn't support region-of-interest." From a036bf70cc014ce5ba435ab53e3aa25b38a7ad0e Mon Sep 17 00:00:00 2001 From: kinaryml Date: Thu, 13 Apr 2023 21:09:01 -0700 Subject: [PATCH 012/753] Removed Activation from ImageSegmenterOptions --- .../tasks/python/test/vision/image_segmenter_test.py | 4 +--- mediapipe/tasks/python/vision/image_segmenter.py | 10 +--------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/mediapipe/tasks/python/test/vision/image_segmenter_test.py b/mediapipe/tasks/python/test/vision/image_segmenter_test.py index aa557281f..de0a263f3 100644 --- a/mediapipe/tasks/python/test/vision/image_segmenter_test.py +++ b/mediapipe/tasks/python/test/vision/image_segmenter_test.py @@ -15,7 +15,6 @@ import enum import os -from typing import List from unittest import mock from absl.testing import absltest @@ -34,7 +33,6 @@ ImageSegmenterResult = image_segmenter.ImageSegmenterResult _BaseOptions = base_options_module.BaseOptions _Image = image_module.Image _ImageFormat = image_frame.ImageFormat -_Activation = image_segmenter.ImageSegmenterOptions.Activation _ImageSegmenter = image_segmenter.ImageSegmenter _ImageSegmenterOptions = image_segmenter.ImageSegmenterOptions _RUNNING_MODE = vision_task_running_mode.VisionTaskRunningMode @@ -191,7 +189,7 @@ class ImageSegmenterTest(parameterized.TestCase): # Run segmentation on the model in CONFIDENCE_MASK mode. options = _ImageSegmenterOptions( base_options=base_options, output_category_mask=False, - output_confidence_masks=True, activation=_Activation.SOFTMAX + output_confidence_masks=True ) with _ImageSegmenter.create_from_options(options) as segmenter: diff --git a/mediapipe/tasks/python/vision/image_segmenter.py b/mediapipe/tasks/python/vision/image_segmenter.py index 102773173..c5204db47 100644 --- a/mediapipe/tasks/python/vision/image_segmenter.py +++ b/mediapipe/tasks/python/vision/image_segmenter.py @@ -78,16 +78,10 @@ class ImageSegmenterOptions: is set to the live stream mode. """ - class Activation(enum.Enum): - NONE = 0 - SIGMOID = 1 - SOFTMAX = 2 - base_options: _BaseOptions running_mode: _RunningMode = _RunningMode.IMAGE output_confidence_masks: bool = True output_category_mask: bool = False - activation: Optional[Activation] = Activation.NONE result_callback: Optional[ Callable[[ImageSegmenterResult, image_module.Image, int], None] ] = None @@ -99,9 +93,7 @@ class ImageSegmenterOptions: base_options_proto.use_stream_mode = ( False if self.running_mode == _RunningMode.IMAGE else True ) - segmenter_options_proto = _SegmenterOptionsProto( - activation=self.activation.value - ) + segmenter_options_proto = _SegmenterOptionsProto() return _ImageSegmenterGraphOptionsProto( base_options=base_options_proto, segmenter_options=segmenter_options_proto, From a745b71f97aa49a5533ddb282bfee2bd30654aa4 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Thu, 13 Apr 2023 21:11:20 -0700 Subject: [PATCH 013/753] Removed unused import --- mediapipe/tasks/python/vision/image_segmenter.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mediapipe/tasks/python/vision/image_segmenter.py b/mediapipe/tasks/python/vision/image_segmenter.py index c5204db47..8edabe321 100644 --- a/mediapipe/tasks/python/vision/image_segmenter.py +++ b/mediapipe/tasks/python/vision/image_segmenter.py @@ -14,7 +14,6 @@ """MediaPipe image segmenter task.""" import dataclasses -import enum from typing import Callable, List, Mapping, Optional from mediapipe.python import packet_creator From 5f5ce22020956663397188a922d887ef26daf105 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Fri, 14 Apr 2023 14:09:15 -0700 Subject: [PATCH 014/753] Added the PoseLandmarker Python API and a simple test --- mediapipe/python/BUILD | 1 + mediapipe/tasks/python/test/vision/BUILD | 23 + .../test/vision/pose_landmarker_test.py | 177 ++++++++ mediapipe/tasks/python/vision/BUILD | 21 + .../tasks/python/vision/pose_landmarker.py | 428 ++++++++++++++++++ 5 files changed, 650 insertions(+) create mode 100644 mediapipe/tasks/python/test/vision/pose_landmarker_test.py create mode 100644 mediapipe/tasks/python/vision/pose_landmarker.py diff --git a/mediapipe/python/BUILD b/mediapipe/python/BUILD index 2fdc08149..7ba269f51 100644 --- a/mediapipe/python/BUILD +++ b/mediapipe/python/BUILD @@ -92,6 +92,7 @@ cc_library( "//mediapipe/tasks/cc/audio/audio_embedder:audio_embedder_graph", "//mediapipe/tasks/cc/vision/face_detector:face_detector_graph", "//mediapipe/tasks/cc/vision/face_landmarker:face_landmarker_graph", + "//mediapipe/tasks/cc/vision/pose_landmarker:pose_landmarker_graph", "//mediapipe/tasks/cc/vision/face_stylizer:face_stylizer_graph", "//mediapipe/tasks/cc/vision/gesture_recognizer:gesture_recognizer_graph", "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", diff --git a/mediapipe/tasks/python/test/vision/BUILD b/mediapipe/tasks/python/test/vision/BUILD index 704e1af5c..2014b6ba7 100644 --- a/mediapipe/tasks/python/test/vision/BUILD +++ b/mediapipe/tasks/python/test/vision/BUILD @@ -162,3 +162,26 @@ py_test( "@com_google_protobuf//:protobuf_python", ], ) + +py_test( + name = "pose_landmarker_test", + srcs = ["pose_landmarker_test.py"], + data = [ + "//mediapipe/tasks/testdata/vision:test_images", + "//mediapipe/tasks/testdata/vision:test_models", + "//mediapipe/tasks/testdata/vision:test_protos", + ], + deps = [ + "//mediapipe/tasks/cc/components/containers/proto:landmarks_detection_result_py_pb2", + "//mediapipe/python:_framework_bindings", + "//mediapipe/tasks/python/components/containers:landmark", + "//mediapipe/tasks/python/components/containers:landmark_detection_result", + "//mediapipe/tasks/python/components/containers:rect", + "//mediapipe/tasks/python/core:base_options", + "//mediapipe/tasks/python/test:test_utils", + "//mediapipe/tasks/python/vision:pose_landmarker", + "//mediapipe/tasks/python/vision/core:image_processing_options", + "//mediapipe/tasks/python/vision/core:vision_task_running_mode", + "@com_google_protobuf//:protobuf_python", + ], +) diff --git a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py new file mode 100644 index 000000000..a1704e7f6 --- /dev/null +++ b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py @@ -0,0 +1,177 @@ +# Copyright 2022 The MediaPipe Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for pose landmarker.""" + +import enum +from unittest import mock + +from absl.testing import absltest +from absl.testing import parameterized +import numpy as np + +from google.protobuf import text_format +from mediapipe.python._framework_bindings import image as image_module +from mediapipe.tasks.cc.components.containers.proto import landmarks_detection_result_pb2 +from mediapipe.tasks.python.components.containers import landmark as landmark_module +from mediapipe.tasks.python.components.containers import landmark_detection_result as landmark_detection_result_module +from mediapipe.tasks.python.components.containers import rect as rect_module +from mediapipe.tasks.python.core import base_options as base_options_module +from mediapipe.tasks.python.test import test_utils +from mediapipe.tasks.python.vision import pose_landmarker +from mediapipe.tasks.python.vision.core import image_processing_options as image_processing_options_module +from mediapipe.tasks.python.vision.core import vision_task_running_mode as running_mode_module + +PoseLandmarkerResult = pose_landmarker.PoseLandmarkerResult +_LandmarksDetectionResultProto = landmarks_detection_result_pb2.LandmarksDetectionResult +_BaseOptions = base_options_module.BaseOptions +_Rect = rect_module.Rect +_Landmark = landmark_module.Landmark +_NormalizedLandmark = landmark_module.NormalizedLandmark +_LandmarksDetectionResult = landmark_detection_result_module.LandmarksDetectionResult +_Image = image_module.Image +_PoseLandmarker = pose_landmarker.PoseLandmarker +_PoseLandmarkerOptions = pose_landmarker.PoseLandmarkerOptions +_RUNNING_MODE = running_mode_module.VisionTaskRunningMode +_ImageProcessingOptions = image_processing_options_module.ImageProcessingOptions + +_POSE_LANDMARKER_BUNDLE_ASSET_FILE = 'pose_landmarker.task' +_BURGER_IMAGE = 'burger.jpg' +_POSE_IMAGE = 'pose.jpg' +_POSE_LANDMARKS = 'pose_landmarks.pbtxt' +_LANDMARKS_ERROR_TOLERANCE = 0.03 +_LANDMARKS_ON_VIDEO_ERROR_TOLERANCE = 0.03 + + +def _get_expected_pose_landmarker_result( + file_path: str) -> PoseLandmarkerResult: + landmarks_detection_result_file_path = test_utils.get_test_data_path( + file_path) + with open(landmarks_detection_result_file_path, 'rb') as f: + landmarks_detection_result_proto = _LandmarksDetectionResultProto() + # Use this if a .pb file is available. + # landmarks_detection_result_proto.ParseFromString(f.read()) + text_format.Parse(f.read(), landmarks_detection_result_proto) + landmarks_detection_result = _LandmarksDetectionResult.create_from_pb2( + landmarks_detection_result_proto) + return PoseLandmarkerResult( + pose_landmarks=[landmarks_detection_result.landmarks], + pose_world_landmarks=[], + pose_auxiliary_landmarks=[] + ) + + +class ModelFileType(enum.Enum): + FILE_CONTENT = 1 + FILE_NAME = 2 + + +class PoseLandmarkerTest(parameterized.TestCase): + + def setUp(self): + super().setUp() + self.test_image = _Image.create_from_file( + test_utils.get_test_data_path(_POSE_IMAGE)) + self.model_path = test_utils.get_test_data_path( + _POSE_LANDMARKER_BUNDLE_ASSET_FILE) + + def _expect_pose_landmarker_results_correct( + self, + actual_result: PoseLandmarkerResult, + expected_result: PoseLandmarkerResult, + error_tolerance: float + ): + # Expects to have the same number of poses detected. + self.assertLen(actual_result.pose_landmarks, + len(expected_result.pose_landmarks)) + self.assertLen(actual_result.pose_world_landmarks, + len(expected_result.pose_world_landmarks)) + self.assertLen(actual_result.pose_auxiliary_landmarks, + len(expected_result.pose_auxiliary_landmarks)) + # Actual landmarks match expected landmarks. + actual_landmarks = actual_result.pose_landmarks[0] + expected_landmarks = expected_result.pose_landmarks[0] + for i, pose_landmark in enumerate(actual_landmarks): + self.assertAlmostEqual( + pose_landmark.x, + expected_landmarks[i].x, + delta=error_tolerance + ) + self.assertAlmostEqual( + pose_landmark.y, + expected_landmarks[i].y, + delta=error_tolerance + ) + + def test_create_from_file_succeeds_with_valid_model_path(self): + # Creates with default option and valid model file successfully. + with _PoseLandmarker.create_from_model_path(self.model_path) as landmarker: + self.assertIsInstance(landmarker, _PoseLandmarker) + + def test_create_from_options_succeeds_with_valid_model_path(self): + # Creates with options containing model file successfully. + base_options = _BaseOptions(model_asset_path=self.model_path) + options = _PoseLandmarkerOptions(base_options=base_options) + with _PoseLandmarker.create_from_options(options) as landmarker: + self.assertIsInstance(landmarker, _PoseLandmarker) + + def test_create_from_options_fails_with_invalid_model_path(self): + # Invalid empty model path. + with self.assertRaisesRegex( + RuntimeError, 'Unable to open file at /path/to/invalid/model.tflite'): + base_options = _BaseOptions( + model_asset_path='/path/to/invalid/model.tflite') + options = _PoseLandmarkerOptions(base_options=base_options) + _PoseLandmarker.create_from_options(options) + + def test_create_from_options_succeeds_with_valid_model_content(self): + # Creates with options containing model content successfully. + with open(self.model_path, 'rb') as f: + base_options = _BaseOptions(model_asset_buffer=f.read()) + options = _PoseLandmarkerOptions(base_options=base_options) + landmarker = _PoseLandmarker.create_from_options(options) + self.assertIsInstance(landmarker, _PoseLandmarker) + + @parameterized.parameters( + (ModelFileType.FILE_NAME, + _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), + (ModelFileType.FILE_CONTENT, + _get_expected_pose_landmarker_result(_POSE_LANDMARKS))) + def test_detect(self, model_file_type, expected_detection_result): + # Creates pose landmarker. + if model_file_type is ModelFileType.FILE_NAME: + base_options = _BaseOptions(model_asset_path=self.model_path) + elif model_file_type is ModelFileType.FILE_CONTENT: + with open(self.model_path, 'rb') as f: + model_content = f.read() + base_options = _BaseOptions(model_asset_buffer=model_content) + else: + # Should never happen + raise ValueError('model_file_type is invalid.') + + options = _PoseLandmarkerOptions(base_options=base_options) + landmarker = _PoseLandmarker.create_from_options(options) + + # Performs pose landmarks detection on the input. + detection_result = landmarker.detect(self.test_image) + # Comparing results. + self._expect_pose_landmarker_results_correct( + detection_result, expected_detection_result, _LANDMARKS_ERROR_TOLERANCE + ) + # Closes the pose landmarker explicitly when the pose landmarker is not used + # in a context. + landmarker.close() + + +if __name__ == '__main__': + absltest.main() diff --git a/mediapipe/tasks/python/vision/BUILD b/mediapipe/tasks/python/vision/BUILD index 046ce2dc8..db04ba7ba 100644 --- a/mediapipe/tasks/python/vision/BUILD +++ b/mediapipe/tasks/python/vision/BUILD @@ -179,6 +179,27 @@ py_library( ], ) +py_library( + name = "pose_landmarker", + srcs = [ + "pose_landmarker.py", + ], + deps = [ + "//mediapipe/framework/formats:landmark_py_pb2", + "//mediapipe/python:_framework_bindings", + "//mediapipe/python:packet_creator", + "//mediapipe/python:packet_getter", + "//mediapipe/tasks/cc/vision/pose_landmarker/proto:pose_landmarker_graph_options_py_pb2", + "//mediapipe/tasks/python/components/containers:landmark", + "//mediapipe/tasks/python/core:base_options", + "//mediapipe/tasks/python/core:optional_dependencies", + "//mediapipe/tasks/python/core:task_info", + "//mediapipe/tasks/python/vision/core:base_vision_task_api", + "//mediapipe/tasks/python/vision/core:image_processing_options", + "//mediapipe/tasks/python/vision/core:vision_task_running_mode", + ], +) + py_library( name = "face_detector", srcs = [ diff --git a/mediapipe/tasks/python/vision/pose_landmarker.py b/mediapipe/tasks/python/vision/pose_landmarker.py new file mode 100644 index 000000000..370c77256 --- /dev/null +++ b/mediapipe/tasks/python/vision/pose_landmarker.py @@ -0,0 +1,428 @@ +# Copyright 2022 The MediaPipe Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""MediaPipe pose landmarker task.""" + +import dataclasses +from typing import Callable, Mapping, Optional, List + +from mediapipe.framework.formats import landmark_pb2 +from mediapipe.python import packet_creator +from mediapipe.python import packet_getter +from mediapipe.python._framework_bindings import image as image_module +from mediapipe.python._framework_bindings import packet as packet_module +from mediapipe.tasks.cc.vision.pose_landmarker.proto import pose_landmarker_graph_options_pb2 +from mediapipe.tasks.python.components.containers import landmark as landmark_module +from mediapipe.tasks.python.core import base_options as base_options_module +from mediapipe.tasks.python.core import task_info as task_info_module +from mediapipe.tasks.python.core.optional_dependencies import doc_controls +from mediapipe.tasks.python.vision.core import base_vision_task_api +from mediapipe.tasks.python.vision.core import image_processing_options as image_processing_options_module +from mediapipe.tasks.python.vision.core import vision_task_running_mode as running_mode_module + +_BaseOptions = base_options_module.BaseOptions +_PoseLandmarkerGraphOptionsProto = ( + pose_landmarker_graph_options_pb2.PoseLandmarkerGraphOptions +) +_RunningMode = running_mode_module.VisionTaskRunningMode +_ImageProcessingOptions = image_processing_options_module.ImageProcessingOptions +_TaskInfo = task_info_module.TaskInfo + +_IMAGE_IN_STREAM_NAME = 'image_in' +_IMAGE_OUT_STREAM_NAME = 'image_out' +_IMAGE_TAG = 'IMAGE' +_NORM_RECT_STREAM_NAME = 'norm_rect_in' +_NORM_RECT_TAG = 'NORM_RECT' +_SEGMENTATION_MASK_STREAM_NAME = 'segmentation_mask' +_SEGMENTATION_MASK_TAG = 'SEGMENTATION_MASK' +_NORM_LANDMARKS_STREAM_NAME = 'norm_landmarks' +_NORM_LANDMARKS_TAG = 'NORM_LANDMARKS' +_POSE_WORLD_LANDMARKS_STREAM_NAME = 'world_landmarks' +_POSE_WORLD_LANDMARKS_TAG = 'WORLD_LANDMARKS' +_POSE_AUXILIARY_LANDMARKS_STREAM_NAME = 'auxiliary_landmarks' +_POSE_AUXILIARY_LANDMARKS_TAG = 'AUXILIARY_LANDMARKS' +_TASK_GRAPH_NAME = 'mediapipe.tasks.vision.pose_landmarker.PoseLandmarkerGraph' +_MICRO_SECONDS_PER_MILLISECOND = 1000 + + +@dataclasses.dataclass +class PoseLandmarkerResult: + """The pose landmarks detection result from PoseLandmarker, where each vector element represents a single pose detected in the image. + + Attributes: + pose_landmarks: Detected pose landmarks in normalized image coordinates. + pose_world_landmarks: Detected pose landmarks in world coordinates. + pose_auxiliary_landmarks: Detected auxiliary landmarks, used for deriving + ROI for next frame. + segmentation_masks: Segmentation masks for pose. + """ + + pose_landmarks: List[List[landmark_module.NormalizedLandmark]] + pose_world_landmarks: List[List[landmark_module.Landmark]] + pose_auxiliary_landmarks: List[List[landmark_module.NormalizedLandmark]] + segmentation_masks: Optional[List[image_module.Image]] = None + + +def _build_landmarker_result( + output_packets: Mapping[str, packet_module.Packet] +) -> PoseLandmarkerResult: + """Constructs a `PoseLandmarkerResult` from output packets.""" + pose_landmarker_result = PoseLandmarkerResult([], [], [], []) + + if _SEGMENTATION_MASK_STREAM_NAME in output_packets: + pose_landmarker_result.segmentation_masks = packet_getter.get_image_list( + output_packets[_SEGMENTATION_MASK_STREAM_NAME] + ) + + pose_landmarks_proto_list = packet_getter.get_proto_list( + output_packets[_NORM_LANDMARKS_STREAM_NAME] + ) + pose_world_landmarks_proto_list = packet_getter.get_proto_list( + output_packets[_POSE_WORLD_LANDMARKS_STREAM_NAME] + ) + pose_auxiliary_landmarks_proto_list = packet_getter.get_proto_list( + output_packets[_POSE_AUXILIARY_LANDMARKS_STREAM_NAME] + ) + + for proto in pose_landmarks_proto_list: + pose_landmarks = landmark_pb2.NormalizedLandmarkList() + pose_landmarks.MergeFrom(proto) + pose_landmarks_list = [] + for pose_landmark in pose_landmarks.landmark: + pose_landmarks_list.append( + landmark_module.NormalizedLandmark.create_from_pb2(pose_landmark) + ) + pose_landmarker_result.pose_landmarks.append(pose_landmarks_list) + + for proto in pose_world_landmarks_proto_list: + pose_world_landmarks = landmark_pb2.LandmarkList() + pose_world_landmarks.MergeFrom(proto) + pose_world_landmarks_list = [] + for pose_world_landmark in pose_world_landmarks.landmark: + pose_world_landmarks_list.append( + landmark_module.Landmark.create_from_pb2(pose_world_landmark) + ) + pose_landmarker_result.pose_world_landmarks.append( + pose_world_landmarks_list + ) + + for proto in pose_auxiliary_landmarks_proto_list: + pose_auxiliary_landmarks = landmark_pb2.NormalizedLandmarkList() + pose_auxiliary_landmarks.MergeFrom(proto) + pose_auxiliary_landmarks_list = [] + for pose_auxiliary_landmark in pose_auxiliary_landmarks.landmark: + pose_auxiliary_landmarks_list.append( + landmark_module.NormalizedLandmark.create_from_pb2(pose_auxiliary_landmark) + ) + pose_landmarker_result.pose_auxiliary_landmarks.append( + pose_auxiliary_landmarks_list + ) + return pose_landmarker_result + + +@dataclasses.dataclass +class PoseLandmarkerOptions: + """Options for the pose landmarker task. + + Attributes: + base_options: Base options for the pose landmarker task. + running_mode: The running mode of the task. Default to the image mode. + HandLandmarker has three running modes: 1) The image mode for detecting + pose landmarks on single image inputs. 2) The video mode for detecting + pose landmarks on the decoded frames of a video. 3) The live stream mode + for detecting pose landmarks on the live stream of input data, such as + from camera. In this mode, the "result_callback" below must be specified + to receive the detection results asynchronously. + num_poses: The maximum number of poses can be detected by the PoseLandmarker. + min_pose_detection_confidence: The minimum confidence score for the pose + detection to be considered successful. + min_pose_presence_confidence: The minimum confidence score of pose presence + score in the pose landmark detection. + min_tracking_confidence: The minimum confidence score for the pose tracking + to be considered successful. + result_callback: The user-defined result callback for processing live stream + data. The result callback should only be specified when the running mode + is set to the live stream mode. + """ + + base_options: _BaseOptions + running_mode: _RunningMode = _RunningMode.IMAGE + num_poses: int = 1 + min_pose_detection_confidence: float = 0.5 + min_pose_presence_confidence: float = 0.5 + min_tracking_confidence: float = 0.5 + output_segmentation_masks: bool = False + result_callback: Optional[ + Callable[[PoseLandmarkerResult, image_module.Image, int], None] + ] = None + + @doc_controls.do_not_generate_docs + def to_pb2(self) -> _PoseLandmarkerGraphOptionsProto: + """Generates an PoseLandmarkerGraphOptions protobuf object.""" + base_options_proto = self.base_options.to_pb2() + base_options_proto.use_stream_mode = ( + False if self.running_mode == _RunningMode.IMAGE else True + ) + + # Initialize the pose landmarker options from base options. + pose_landmarker_options_proto = _PoseLandmarkerGraphOptionsProto( + base_options=base_options_proto + ) + pose_landmarker_options_proto.min_tracking_confidence = ( + self.min_tracking_confidence + ) + pose_landmarker_options_proto.pose_detector_graph_options.num_poses = ( + self.num_poses + ) + pose_landmarker_options_proto.pose_detector_graph_options.min_detection_confidence = ( + self.min_pose_detection_confidence + ) + pose_landmarker_options_proto.pose_landmarks_detector_graph_options.min_detection_confidence = ( + self.min_pose_presence_confidence + ) + return pose_landmarker_options_proto + + +class PoseLandmarker(base_vision_task_api.BaseVisionTaskApi): + """Class that performs pose landmarks detection on images.""" + + @classmethod + def create_from_model_path(cls, model_path: str) -> 'PoseLandmarker': + """Creates an `PoseLandmarker` object from a TensorFlow Lite model and the default `PoseLandmarkerOptions`. + + Note that the created `PoseLandmarker` instance is in image mode, for + detecting pose landmarks on single image inputs. + + Args: + model_path: Path to the model. + + Returns: + `PoseLandmarker` object that's created from the model file and the + default `PoseLandmarkerOptions`. + + Raises: + ValueError: If failed to create `PoseLandmarker` object from the + provided file such as invalid file path. + RuntimeError: If other types of error occurred. + """ + base_options = _BaseOptions(model_asset_path=model_path) + options = PoseLandmarkerOptions( + base_options=base_options, running_mode=_RunningMode.IMAGE + ) + return cls.create_from_options(options) + + @classmethod + def create_from_options( + cls, options: PoseLandmarkerOptions + ) -> 'PoseLandmarker': + """Creates the `PoseLandmarker` object from pose landmarker options. + + Args: + options: Options for the pose landmarker task. + + Returns: + `PoseLandmarker` object that's created from `options`. + + Raises: + ValueError: If failed to create `PoseLandmarker` object from + `PoseLandmarkerOptions` such as missing the model. + RuntimeError: If other types of error occurred. + """ + + def packets_callback(output_packets: Mapping[str, packet_module.Packet]): + if output_packets[_IMAGE_OUT_STREAM_NAME].is_empty(): + return + + image = packet_getter.get_image(output_packets[_IMAGE_OUT_STREAM_NAME]) + + if output_packets[_NORM_LANDMARKS_STREAM_NAME].is_empty(): + empty_packet = output_packets[_NORM_LANDMARKS_STREAM_NAME] + options.result_callback( + PoseLandmarkerResult([], [], []), + image, + empty_packet.timestamp.value // _MICRO_SECONDS_PER_MILLISECOND, + ) + return + + pose_landmarker_result = _build_landmarker_result(output_packets) + timestamp = output_packets[_NORM_LANDMARKS_STREAM_NAME].timestamp + options.result_callback( + pose_landmarker_result, + image, + timestamp.value // _MICRO_SECONDS_PER_MILLISECOND, + ) + + output_streams = [ + ':'.join([_SEGMENTATION_MASK_TAG, _SEGMENTATION_MASK_STREAM_NAME]), + ':'.join([_NORM_LANDMARKS_TAG, _NORM_LANDMARKS_STREAM_NAME]), + ':'.join([ + _POSE_WORLD_LANDMARKS_TAG, _POSE_WORLD_LANDMARKS_STREAM_NAME + ]), + ':'.join([ + _POSE_AUXILIARY_LANDMARKS_TAG, + _POSE_AUXILIARY_LANDMARKS_STREAM_NAME + ]), + ':'.join([_IMAGE_TAG, _IMAGE_OUT_STREAM_NAME]), + ] + + if options.output_segmentation_masks: + output_streams.append( + ':'.join([_SEGMENTATION_MASK_TAG, _SEGMENTATION_MASK_STREAM_NAME]) + ) + + task_info = _TaskInfo( + task_graph=_TASK_GRAPH_NAME, + input_streams=[ + ':'.join([_IMAGE_TAG, _IMAGE_IN_STREAM_NAME]), + ':'.join([_NORM_RECT_TAG, _NORM_RECT_STREAM_NAME]), + ], + output_streams=output_streams, + task_options=options, + ) + return cls( + task_info.generate_graph_config( + enable_flow_limiting=options.running_mode + == _RunningMode.LIVE_STREAM + ), + options.running_mode, + packets_callback if options.result_callback else None, + ) + + def detect( + self, + image: image_module.Image, + image_processing_options: Optional[_ImageProcessingOptions] = None, + ) -> PoseLandmarkerResult: + """Performs pose landmarks detection on the given image. + + Only use this method when the PoseLandmarker is created with the image + running mode. + + Args: + image: MediaPipe Image. + image_processing_options: Options for image processing. + + Returns: + The pose landmarker detection results. + + Raises: + ValueError: If any of the input arguments is invalid. + RuntimeError: If pose landmarker detection failed to run. + """ + normalized_rect = self.convert_to_normalized_rect( + image_processing_options, image, roi_allowed=False + ) + output_packets = self._process_image_data({ + _IMAGE_IN_STREAM_NAME: packet_creator.create_image(image), + _NORM_RECT_STREAM_NAME: packet_creator.create_proto( + normalized_rect.to_pb2() + ), + }) + + if output_packets[_NORM_LANDMARKS_STREAM_NAME].is_empty(): + return PoseLandmarkerResult([], [], []) + + return _build_landmarker_result(output_packets) + + def detect_for_video( + self, + image: image_module.Image, + timestamp_ms: int, + image_processing_options: Optional[_ImageProcessingOptions] = None, + ) -> PoseLandmarkerResult: + """Performs pose landmarks detection on the provided video frame. + + Only use this method when the PoseLandmarker is created with the video + running mode. + + Only use this method when the PoseLandmarker is created with the video + running mode. It's required to provide the video frame's timestamp (in + milliseconds) along with the video frame. The input timestamps should be + monotonically increasing for adjacent calls of this method. + + Args: + image: MediaPipe Image. + timestamp_ms: The timestamp of the input video frame in milliseconds. + image_processing_options: Options for image processing. + + Returns: + The pose landmarks detection results. + + Raises: + ValueError: If any of the input arguments is invalid. + RuntimeError: If pose landmarker detection failed to run. + """ + normalized_rect = self.convert_to_normalized_rect( + image_processing_options, image, roi_allowed=False + ) + output_packets = self._process_video_data({ + _IMAGE_IN_STREAM_NAME: packet_creator.create_image(image).at( + timestamp_ms * _MICRO_SECONDS_PER_MILLISECOND + ), + _NORM_RECT_STREAM_NAME: packet_creator.create_proto( + normalized_rect.to_pb2() + ).at(timestamp_ms * _MICRO_SECONDS_PER_MILLISECOND), + }) + + if output_packets[_NORM_LANDMARKS_STREAM_NAME].is_empty(): + return PoseLandmarkerResult([], [], []) + + return _build_landmarker_result(output_packets) + + def detect_async( + self, + image: image_module.Image, + timestamp_ms: int, + image_processing_options: Optional[_ImageProcessingOptions] = None, + ) -> None: + """Sends live image data to perform pose landmarks detection. + + The results will be available via the "result_callback" provided in the + PoseLandmarkerOptions. Only use this method when the PoseLandmarker is + created with the live stream running mode. + + Only use this method when the PoseLandmarker is created with the live + stream running mode. The input timestamps should be monotonically increasing + for adjacent calls of this method. This method will return immediately after + the input image is accepted. The results will be available via the + `result_callback` provided in the `PoseLandmarkerOptions`. The + `detect_async` method is designed to process live stream data such as + camera input. To lower the overall latency, pose landmarker may drop the + input images if needed. In other words, it's not guaranteed to have output + per input image. + + The `result_callback` provides: + - The pose landmarks detection results. + - The input image that the pose landmarker runs on. + - The input timestamp in milliseconds. + + Args: + image: MediaPipe Image. + timestamp_ms: The timestamp of the input image in milliseconds. + image_processing_options: Options for image processing. + + Raises: + ValueError: If the current input timestamp is smaller than what the + pose landmarker has already processed. + """ + normalized_rect = self.convert_to_normalized_rect( + image_processing_options, image, roi_allowed=False + ) + self._send_live_stream_data({ + _IMAGE_IN_STREAM_NAME: packet_creator.create_image(image).at( + timestamp_ms * _MICRO_SECONDS_PER_MILLISECOND + ), + _NORM_RECT_STREAM_NAME: packet_creator.create_proto( + normalized_rect.to_pb2() + ).at(timestamp_ms * _MICRO_SECONDS_PER_MILLISECOND), + }) From b4e27c137e2c5c014c3e849fec7ec0ed92759fbf Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 18 Apr 2023 00:52:09 -0700 Subject: [PATCH 015/753] Internal change PiperOrigin-RevId: 525069421 --- .../objectron/calculators/frame_annotation_tracker.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mediapipe/modules/objectron/calculators/frame_annotation_tracker.cc b/mediapipe/modules/objectron/calculators/frame_annotation_tracker.cc index eebf88579..1685a4f68 100644 --- a/mediapipe/modules/objectron/calculators/frame_annotation_tracker.cc +++ b/mediapipe/modules/objectron/calculators/frame_annotation_tracker.cc @@ -24,8 +24,8 @@ namespace mediapipe { void FrameAnnotationTracker::AddDetectionResult( const FrameAnnotation& frame_annotation) { - const int64 time_us = - static_cast(std::round(frame_annotation.timestamp())); + const int64_t time_us = + static_cast(std::round(frame_annotation.timestamp())); for (const auto& object_annotation : frame_annotation.annotations()) { detected_objects_[time_us + object_annotation.object_id()] = object_annotation; @@ -37,7 +37,7 @@ FrameAnnotation FrameAnnotationTracker::ConsolidateTrackingResult( absl::flat_hash_set* cancel_object_ids) { CHECK(cancel_object_ids != nullptr); FrameAnnotation frame_annotation; - std::vector keys_to_be_deleted; + std::vector keys_to_be_deleted; for (const auto& detected_obj : detected_objects_) { const int object_id = detected_obj.second.object_id(); if (cancel_object_ids->contains(object_id)) { From 88a10de345926cab4432c4ec61339b48af28f87e Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 18 Apr 2023 02:12:28 -0700 Subject: [PATCH 016/753] Internal change PiperOrigin-RevId: 525084368 --- mediapipe/gpu/gl_texture_buffer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/gpu/gl_texture_buffer.cc b/mediapipe/gpu/gl_texture_buffer.cc index 69b9889c7..f1497f741 100644 --- a/mediapipe/gpu/gl_texture_buffer.cc +++ b/mediapipe/gpu/gl_texture_buffer.cc @@ -64,7 +64,7 @@ std::unique_ptr GlTextureBuffer::Create( int actual_ws = image_frame.WidthStep(); int alignment = 0; std::unique_ptr temp; - const uint8* data = image_frame.PixelData(); + const uint8_t* data = image_frame.PixelData(); // Let's see if the pixel data is tightly aligned to one of the alignments // supported by OpenGL, preferring 4 if possible since it's the default. From 723cb2a91977818c2198cf394bd81db8bba1fc25 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Tue, 18 Apr 2023 02:49:13 -0700 Subject: [PATCH 017/753] Populate labels using model metadata for the ImageSegmenter Python API --- .../test/vision/image_segmenter_test.py | 33 ++++++++++ mediapipe/tasks/python/vision/BUILD | 1 + .../tasks/python/vision/image_segmenter.py | 63 +++++++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/mediapipe/tasks/python/test/vision/image_segmenter_test.py b/mediapipe/tasks/python/test/vision/image_segmenter_test.py index 7f0b47eb7..d993315e2 100644 --- a/mediapipe/tasks/python/test/vision/image_segmenter_test.py +++ b/mediapipe/tasks/python/test/vision/image_segmenter_test.py @@ -45,6 +45,29 @@ _SEGMENTATION_FILE = 'segmentation_golden_rotation0.png' _MASK_MAGNIFICATION_FACTOR = 10 _MASK_SIMILARITY_THRESHOLD = 0.98 _TEST_DATA_DIR = 'mediapipe/tasks/testdata/vision' +_EXPECTED_LABELS = [ + "background", + "aeroplane", + "bicycle", + "bird", + "boat", + "bottle", + "bus", + "car", + "cat", + "chair", + "cow", + "dining table", + "dog", + "horse", + "motorbike", + "person", + "potted plant", + "sheep", + "sofa", + "train", + "tv" +] def _similar_to_uint8_mask(actual_mask, expected_mask): @@ -214,6 +237,16 @@ class ImageSegmenterTest(parameterized.TestCase): f'Number of pixels in the candidate mask differing from that of the ' f'ground truth mask exceeds {_MASK_SIMILARITY_THRESHOLD}.') + def test_get_labels_succeeds(self): + expected_labels = _EXPECTED_LABELS + base_options = _BaseOptions(model_asset_path=self.model_path) + options = _ImageSegmenterOptions( + base_options=base_options, output_type=_OutputType.CATEGORY_MASK) + with _ImageSegmenter.create_from_options(options) as segmenter: + # Performs image segmentation on the input. + actual_labels = segmenter.get_labels() + self.assertListEqual(actual_labels, expected_labels) + def test_missing_result_callback(self): options = _ImageSegmenterOptions( base_options=_BaseOptions(model_asset_path=self.model_path), diff --git a/mediapipe/tasks/python/vision/BUILD b/mediapipe/tasks/python/vision/BUILD index 046ce2dc8..716757790 100644 --- a/mediapipe/tasks/python/vision/BUILD +++ b/mediapipe/tasks/python/vision/BUILD @@ -71,6 +71,7 @@ py_library( "//mediapipe/python:_framework_bindings", "//mediapipe/python:packet_creator", "//mediapipe/python:packet_getter", + "//mediapipe/tasks/cc/vision/image_segmenter/calculators:tensors_to_segmentation_calculator_py_pb2", "//mediapipe/tasks/cc/vision/image_segmenter/proto:image_segmenter_graph_options_py_pb2", "//mediapipe/tasks/cc/vision/image_segmenter/proto:segmenter_options_py_pb2", "//mediapipe/tasks/python/components/containers:rect", diff --git a/mediapipe/tasks/python/vision/image_segmenter.py b/mediapipe/tasks/python/vision/image_segmenter.py index e50ffbf79..f70f16534 100644 --- a/mediapipe/tasks/python/vision/image_segmenter.py +++ b/mediapipe/tasks/python/vision/image_segmenter.py @@ -21,6 +21,7 @@ from mediapipe.python import packet_creator from mediapipe.python import packet_getter from mediapipe.python._framework_bindings import image as image_module from mediapipe.python._framework_bindings import packet +from mediapipe.tasks.cc.vision.image_segmenter.calculators import tensors_to_segmentation_calculator_pb2 from mediapipe.tasks.cc.vision.image_segmenter.proto import image_segmenter_graph_options_pb2 from mediapipe.tasks.cc.vision.image_segmenter.proto import segmenter_options_pb2 from mediapipe.tasks.python.components.containers import rect @@ -38,6 +39,9 @@ _SegmenterOptionsProto = segmenter_options_pb2.SegmenterOptions _ImageSegmenterGraphOptionsProto = ( image_segmenter_graph_options_pb2.ImageSegmenterGraphOptions ) +TensorsToSegmentationCalculatorOptionsProto = ( + tensors_to_segmentation_calculator_pb2.TensorsToSegmentationCalculatorOptions +) _RunningMode = vision_task_running_mode.VisionTaskRunningMode _ImageProcessingOptions = image_processing_options_module.ImageProcessingOptions _TaskInfo = task_info_module.TaskInfo @@ -49,6 +53,7 @@ _IMAGE_OUT_STREAM_NAME = 'image_out' _IMAGE_TAG = 'IMAGE' _NORM_RECT_STREAM_NAME = 'norm_rect_in' _NORM_RECT_TAG = 'NORM_RECT' +_TENSORS_TO_SEGMENTATION_CALCULATOR_NAME = 'mediapipe.tasks.TensorsToSegmentationCalculator' _TASK_GRAPH_NAME = 'mediapipe.tasks.vision.image_segmenter.ImageSegmenterGraph' _MICRO_SECONDS_PER_MILLISECOND = 1000 @@ -130,6 +135,40 @@ class ImageSegmenter(base_vision_task_api.BaseVisionTaskApi): An example of such model can be found at: https://tfhub.dev/tensorflow/lite-model/deeplabv3/1/metadata/2 """ + def __init__(self, graph_config, running_mode, packet_callback): + super(ImageSegmenter, self).__init__( + graph_config, running_mode, packet_callback + ) + self._populate_labels() + + def _populate_labels(self): + """ + Populate the labelmap in TensorsToSegmentationCalculator to labels field. + + Returns: + Exception if there is an error during finding TensorsToSegmentationCalculator. + :return: + """ + self.labels = [] + graph_config = self._runner.get_graph_config() + found_tensors_to_segmentation = False + + for node in graph_config.node: + if _TENSORS_TO_SEGMENTATION_CALCULATOR_NAME in node.name: + if found_tensors_to_segmentation: + raise Exception( + f"The graph has more than one " + f"{_TENSORS_TO_SEGMENTATION_CALCULATOR_NAME}." + ) + found_tensors_to_segmentation = True + options = node.options.Extensions[ + TensorsToSegmentationCalculatorOptionsProto.ext + ] + if options.label_items: + for i in range(len(options.label_items)): + if i not in options.label_items: + raise Exception(f"The labelmap has no expected key: {i}.") + self.labels.append(options.label_items[i].name) @classmethod def create_from_model_path(cls, model_path: str) -> 'ImageSegmenter': @@ -209,6 +248,30 @@ class ImageSegmenter(base_vision_task_api.BaseVisionTaskApi): packets_callback if options.result_callback else None, ) + def get_labels(self): + """ Get the category label list of the ImageSegmenter can recognize. + + For CATEGORY_MASK type, the index in the category mask corresponds to the + category in the label list. + For CONFIDENCE_MASK type, the output mask list at index corresponds to the + category in the label list. + + If there is no label map provided in the model file, empty label list is + returned. + + Returns: + If the output_type is CATEGORY_MASK, the returned vector of images is + per-category segmented image mask. + If the output_type is CONFIDENCE_MASK, the returned vector of images + contains only one confidence image mask. A segmentation result object that + contains a list of segmentation masks as images. + + Raises: + ValueError: If any of the input arguments is invalid. + RuntimeError: If image segmentation failed to run. + """ + return self.labels + def segment( self, image: image_module.Image, From 1919b0e34125a3e9a4287550b9d9a357fac50f96 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Tue, 18 Apr 2023 02:54:03 -0700 Subject: [PATCH 018/753] Updated docstrings for get_labels --- mediapipe/tasks/python/vision/image_segmenter.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/mediapipe/tasks/python/vision/image_segmenter.py b/mediapipe/tasks/python/vision/image_segmenter.py index f70f16534..4f57b89db 100644 --- a/mediapipe/tasks/python/vision/image_segmenter.py +++ b/mediapipe/tasks/python/vision/image_segmenter.py @@ -258,17 +258,6 @@ class ImageSegmenter(base_vision_task_api.BaseVisionTaskApi): If there is no label map provided in the model file, empty label list is returned. - - Returns: - If the output_type is CATEGORY_MASK, the returned vector of images is - per-category segmented image mask. - If the output_type is CONFIDENCE_MASK, the returned vector of images - contains only one confidence image mask. A segmentation result object that - contains a list of segmentation masks as images. - - Raises: - ValueError: If any of the input arguments is invalid. - RuntimeError: If image segmentation failed to run. """ return self.labels From 3e0ed2ced053faae2f078dd2d53052c2f578120f Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 18 Apr 2023 10:10:58 -0700 Subject: [PATCH 019/753] Internal Changes PiperOrigin-RevId: 525180095 --- .../python/vision/object_detector/BUILD | 6 +----- .../object_detector/object_detector_test.py | 17 +++++++---------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/mediapipe/model_maker/python/vision/object_detector/BUILD b/mediapipe/model_maker/python/vision/object_detector/BUILD index f3d4407d8..b97d215da 100644 --- a/mediapipe/model_maker/python/vision/object_detector/BUILD +++ b/mediapipe/model_maker/python/vision/object_detector/BUILD @@ -175,11 +175,7 @@ py_test( data = [":testdata"], tags = ["requires-net:external"], deps = [ - ":dataset", - ":hyperparameters", - ":model_spec", - ":object_detector", - ":object_detector_options", + ":object_detector_import", "//mediapipe/tasks/python/test:test_utils", ], ) diff --git a/mediapipe/model_maker/python/vision/object_detector/object_detector_test.py b/mediapipe/model_maker/python/vision/object_detector/object_detector_test.py index df6b58a07..02f773e69 100644 --- a/mediapipe/model_maker/python/vision/object_detector/object_detector_test.py +++ b/mediapipe/model_maker/python/vision/object_detector/object_detector_test.py @@ -19,11 +19,7 @@ from unittest import mock as unittest_mock from absl.testing import parameterized import tensorflow as tf -from mediapipe.model_maker.python.vision.object_detector import dataset -from mediapipe.model_maker.python.vision.object_detector import hyperparameters -from mediapipe.model_maker.python.vision.object_detector import model_spec as ms -from mediapipe.model_maker.python.vision.object_detector import object_detector -from mediapipe.model_maker.python.vision.object_detector import object_detector_options +from mediapipe.model_maker.python.vision import object_detector from mediapipe.tasks.python.test import test_utils as task_test_utils @@ -33,7 +29,7 @@ class ObjectDetectorTest(tf.test.TestCase, parameterized.TestCase): super().setUp() dataset_folder = task_test_utils.get_test_data_path('coco_data') cache_dir = self.create_tempdir() - self.data = dataset.Dataset.from_coco_folder( + self.data = object_detector.Dataset.from_coco_folder( dataset_folder, cache_dir=cache_dir ) # Mock tempfile.gettempdir() to be unique for each test to avoid race @@ -48,15 +44,16 @@ class ObjectDetectorTest(tf.test.TestCase, parameterized.TestCase): self.addCleanup(mock_gettempdir.stop) def test_object_detector(self): - hparams = hyperparameters.HParams( + hparams = object_detector.HParams( epochs=1, batch_size=2, learning_rate=0.9, shuffle=False, export_dir=self.create_tempdir(), ) - options = object_detector_options.ObjectDetectorOptions( - supported_model=ms.SupportedModels.MOBILENET_V2, hparams=hparams + options = object_detector.ObjectDetectorOptions( + supported_model=object_detector.SupportedModels.MOBILENET_V2, + hparams=hparams, ) # Test `create`` model = object_detector.ObjectDetector.create( @@ -79,7 +76,7 @@ class ObjectDetectorTest(tf.test.TestCase, parameterized.TestCase): self.assertGreater(os.path.getsize(output_metadata_file), 0) # Test `quantization_aware_training` - qat_hparams = hyperparameters.QATHParams( + qat_hparams = object_detector.QATHParams( learning_rate=0.9, batch_size=2, epochs=1, From 64d1e74c208d04b999998dbb2560adc266280a7e Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 18 Apr 2023 10:18:19 -0700 Subject: [PATCH 020/753] Internal MediaPipe Tasks change PiperOrigin-RevId: 525182282 --- .../python/test/text/text_embedder_test.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/mediapipe/tasks/python/test/text/text_embedder_test.py b/mediapipe/tasks/python/test/text/text_embedder_test.py index 78e98a1b4..62d162f6e 100644 --- a/mediapipe/tasks/python/test/text/text_embedder_test.py +++ b/mediapipe/tasks/python/test/text/text_embedder_test.py @@ -32,6 +32,7 @@ _TextEmbedderOptions = text_embedder.TextEmbedderOptions _BERT_MODEL_FILE = 'mobilebert_embedding_with_metadata.tflite' _REGEX_MODEL_FILE = 'regex_one_embedding_with_metadata.tflite' +_USE_MODEL_FILE = 'universal_sentence_encoder_qa_with_metadata.tflite' _TEST_DATA_DIR = 'mediapipe/tasks/testdata/text' # Tolerance for embedding vector coordinate values. _EPSILON = 1e-4 @@ -138,6 +139,24 @@ class TextEmbedderTest(parameterized.TestCase): 16, (0.549632, 0.552879), ), + ( + False, + False, + _USE_MODEL_FILE, + ModelFileType.FILE_NAME, + 0.851961, + 100, + (1.422951, 1.404664), + ), + ( + True, + False, + _USE_MODEL_FILE, + ModelFileType.FILE_CONTENT, + 0.851961, + 100, + (0.127049, 0.125416), + ), ) def test_embed(self, l2_normalize, quantize, model_name, model_file_type, expected_similarity, expected_size, expected_first_values): @@ -213,6 +232,24 @@ class TextEmbedderTest(parameterized.TestCase): 16, (0.549632, 0.552879), ), + ( + False, + False, + _USE_MODEL_FILE, + ModelFileType.FILE_NAME, + 0.851961, + 100, + (1.422951, 1.404664), + ), + ( + True, + False, + _USE_MODEL_FILE, + ModelFileType.FILE_CONTENT, + 0.851961, + 100, + (0.127049, 0.125416), + ), ) def test_embed_in_context(self, l2_normalize, quantize, model_name, model_file_type, expected_similarity, expected_size, @@ -251,6 +288,7 @@ class TextEmbedderTest(parameterized.TestCase): @parameterized.parameters( # TODO: The similarity should likely be lower (_BERT_MODEL_FILE, 0.980880), + (_USE_MODEL_FILE, 0.780334), ) def test_embed_with_different_themes(self, model_file, expected_similarity): # Creates embedder. From a7743996303b87c9754cf5fffd58381b451e096b Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 18 Apr 2023 23:02:16 +0530 Subject: [PATCH 021/753] Added targets for iOS text frameworks --- mediapipe/tasks/ios/BUILD | 100 ++++++++++++++++++ mediapipe/tasks/ios/ios.bzl | 37 +++++++ .../tasks/ios/text/text_classifier/BUILD | 8 +- mediapipe/tasks/ios/text/text_embedder/BUILD | 8 +- 4 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 mediapipe/tasks/ios/BUILD diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD new file mode 100644 index 000000000..8786ed49f --- /dev/null +++ b/mediapipe/tasks/ios/BUILD @@ -0,0 +1,100 @@ +# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +load( + "//mediapipe/tasks/ios:ios.bzl", + "MPP_TASK_MINIMUM_OS_VERSION", + "strip_api_include_path_prefix", +) +load( + "@build_bazel_rules_apple//apple:apple.bzl", + "apple_static_xcframework", + "apple_static_library", +) + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +config_setting( + name = "avoid_linking_graphs", + define_values = { + "MEDIAPIPE_AVOID_LINKING_GRAPHS": "1", + }, + visibility = ["//visibility:public"], +) + +strip_api_include_path_prefix( + name = "strip_api_include_path", + hdr_labels = [ + "//mediapipe/tasks/ios/common:sources/MPPCommon.h", + "//mediapipe/tasks/ios/components/containers:sources/MPPCategory.h", + "//mediapipe/tasks/ios/components/containers:sources/MPPClassificationResult.h", + "//mediapipe/tasks/ios/components/containers:sources/MPPEmbedding.h", + "//mediapipe/tasks/ios/components/containers:sources/MPPEmbeddingResult.h", + "//mediapipe/tasks/ios/core:sources/MPPBaseOptions.h", + "//mediapipe/tasks/ios/core:sources/MPPTaskOptions.h", + "//mediapipe/tasks/ios/core:sources/MPPTaskResult.h", + "//mediapipe/tasks/ios/text/text_classifier:sources/MPPTextClassifier.h", + "//mediapipe/tasks/ios/text/text_classifier:sources/MPPTextClassifierOptions.h", + "//mediapipe/tasks/ios/text/text_classifier:sources/MPPTextClassifierResult.h", + "//mediapipe/tasks/ios/text/text_embedder:sources/MPPTextEmbedder.h", + "//mediapipe/tasks/ios/text/text_embedder:sources/MPPTextEmbedderOptions.h", + "//mediapipe/tasks/ios/text/text_embedder:sources/MPPTextEmbedderResult.h", + ], +) + +apple_static_xcframework( + name = "MediaPipeTaskText_framework", + public_hdrs = [ + ":MPPBaseOptions.h", + ":MPPCategory.h", + ":MPPClassificationResult.h", + ":MPPEmbedding.h", + ":MPPEmbeddingResult.h", + ":MPPCommon.h", + ":MPPTaskOptions.h", + ":MPPTaskResult.h", + ":MPPTextClassifier.h", + ":MPPTextClassifierOptions.h", + ":MPPTextClassifierResult.h", + ":MPPTextEmbedder.h", + ":MPPTextEmbedderOptions.h", + ":MPPTextEmbedderResult.h", + ], + bundle_name = "MediaPipeTaskText", + ios = { + "simulator" : ["arm64", "x86_64"], + "device" : ["arm64"], + }, + minimum_os_versions = { + "ios": MPP_TASK_MINIMUM_OS_VERSION, + }, + deps = [ + "//mediapipe/tasks/ios/text/text_classifier:MPPTextClassifier", + "//mediapipe/tasks/ios/text/text_embedder:MPPTextEmbedder", + "@org_tensorflow//third_party/icu/data:conversion_data", + ], +) + +apple_static_library( + name = "MediaPipeTaskText_GraphLibrary", + platform_type = "ios", + minimum_os_version = MPP_TASK_MINIMUM_OS_VERSION, + deps = [ + "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", + "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", + "@org_tensorflow//third_party/icu/data:conversion_data", + ], +) \ No newline at end of file diff --git a/mediapipe/tasks/ios/ios.bzl b/mediapipe/tasks/ios/ios.bzl index 8fe2a24a1..fdfc85d5f 100644 --- a/mediapipe/tasks/ios/ios.bzl +++ b/mediapipe/tasks/ios/ios.bzl @@ -1,3 +1,40 @@ """MediaPipe Task Library Helper Rules for iOS""" MPP_TASK_MINIMUM_OS_VERSION = "11.0" + +# When the static framework is built with bazel, the all header files are moved +# to the "Headers" directory with no header path prefixes. This auxiliary rule +# is used for stripping the path prefix to the C/iOS API header files included by +# other C/iOS API header files. +# In case of C header files includes start with a keyword of "#include'. +# Imports in iOS header files start with a keyword of '#import'. +def strip_api_include_path_prefix(name, hdr_labels, prefix = ""): + """Create modified header files with the import path stripped out. + + Args: + name: The name to be used as a prefix to the generated genrules. + hdr_labels: List of header labels to strip out the include path. Each + label must end with a colon followed by the header file name. + prefix: Optional prefix path to prepend to the header inclusion path. + """ + for hdr_label in hdr_labels: + hdr_filename = hdr_label.split(":")[-1] + + # The last path component of iOS header files is sources/some_file.h + # Hence it wiill contain a '/'. So the string can be split at '/' to get + # the header file name. + if "/" in hdr_filename: + hdr_filename = hdr_filename.split("/")[-1] + + hdr_basename = hdr_filename.split(".")[0] + native.genrule( + name = "{}_{}".format(name, hdr_basename), + srcs = [hdr_label], + outs = [hdr_filename], + cmd = """ + sed 's|#\\([a-z]*\\) ".*/\\([^/]\\{{1,\\}}\\.h\\)"|#\\1 "{}\\2"|'\ + "$(location {})"\ + > "$@" + """.format(prefix, hdr_label), + ) + diff --git a/mediapipe/tasks/ios/text/text_classifier/BUILD b/mediapipe/tasks/ios/text/text_classifier/BUILD index 7913340ac..97cf27677 100644 --- a/mediapipe/tasks/ios/text/text_classifier/BUILD +++ b/mediapipe/tasks/ios/text/text_classifier/BUILD @@ -49,7 +49,6 @@ objc_library( ":MPPTextClassifierOptions", ":MPPTextClassifierResult", "//mediapipe/tasks/cc/components/containers/proto:classifications_cc_proto", - "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", "//mediapipe/tasks/ios/common/utils:NSStringHelpers", "//mediapipe/tasks/ios/core:MPPTaskInfo", @@ -58,5 +57,10 @@ objc_library( "//mediapipe/tasks/ios/text/core:MPPTextTaskRunner", "//mediapipe/tasks/ios/text/text_classifier/utils:MPPTextClassifierOptionsHelpers", "//mediapipe/tasks/ios/text/text_classifier/utils:MPPTextClassifierResultHelpers", - ], + ] + select({ + "//mediapipe/tasks/ios:avoid_linking_graphs": [], + "//conditions:default": [ + "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", + ], + }), ) diff --git a/mediapipe/tasks/ios/text/text_embedder/BUILD b/mediapipe/tasks/ios/text/text_embedder/BUILD index a600d5366..a2edd8a2a 100644 --- a/mediapipe/tasks/ios/text/text_embedder/BUILD +++ b/mediapipe/tasks/ios/text/text_embedder/BUILD @@ -48,7 +48,6 @@ objc_library( deps = [ ":MPPTextEmbedderOptions", ":MPPTextEmbedderResult", - "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", "//mediapipe/tasks/ios/common/utils:NSStringHelpers", "//mediapipe/tasks/ios/components/utils:MPPCosineSimilarity", @@ -58,5 +57,10 @@ objc_library( "//mediapipe/tasks/ios/text/core:MPPTextTaskRunner", "//mediapipe/tasks/ios/text/text_embedder/utils:MPPTextEmbedderOptionsHelpers", "//mediapipe/tasks/ios/text/text_embedder/utils:MPPTextEmbedderResultHelpers", - ], + ] + select({ + "//mediapipe/tasks/ios:avoid_linking_graphs": [], + "//conditions:default": [ + "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", + ], + }), ) From 7ad2b7b32f205a4e715fa3fc7caaf34a55373544 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 18 Apr 2023 23:02:35 +0530 Subject: [PATCH 022/753] Added shell script for building cocoapods archive --- mediapipe/tasks/ios/build_ios_framework.sh | 184 +++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100755 mediapipe/tasks/ios/build_ios_framework.sh diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh new file mode 100755 index 000000000..c27a578aa --- /dev/null +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -0,0 +1,184 @@ +#!/usr/bin/env bash +# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Set the following variables as appropriate. +# * BAZEL: path to bazel. defaults to the first one available in PATH +# * FRAMEWORK_NAME: name of the iOS framework to be built. Currently the +# * accepted values are TensorFlowLiteTaskVision, TensorFlowLiteTaskText. +# * MPP_BUILD_VERSION: to specify the release version. defaults to 0.0.1-dev +# * IS_RELEASE_BUILD: set as true if this build should be a release build +# * ARCHIVE_FRAMEWORK: set as true if the framework should be archived +# * DEST_DIR: destination directory to which the framework will be copied + +set -ex + +if [[ "$(uname)" != "Darwin" ]]; then + echo "This build script only works on macOS." + exit 1 +fi + +BAZEL="${BAZEL:-$(which bazel)}" +MPP_BUILD_VERSION=${MPP_BUILD_VERSION:-0.0.1-dev} +MPP_ROOT_DIR=$(git rev-parse --show-toplevel) +MPP_DISABLE_GPU=true + +if [[ ! -x "${BAZEL}" ]]; then + echo "bazel executable is not found." + exit 1 +fi + +if [ -z ${FRAMEWORK_NAME+x} ]; then + echo "Name of the iOS framework, which is to be built, must be set." + exit 1 +fi + +case $FRAMEWORK_NAME in + "MediaPipeTaskText") + ;; + *) + echo "Wrong framework name. The following framework names are allowed: MediaPipeTaskText" + exit 1 + ;; +esac + +if [[ -z "${DEST_DIR+x}" || "${DEST_DIR}" == ${MPP_ROOT_DIR}* ]]; then + echo "DEST_DIR variable must be set and not be under the repository root." + exit 1 +fi + +# get_output_file_path takes one bazel target label as an argument, and prints +# the path of the first output file of the specified target. +function get_output_file_path { + local STARLARK_OUTPUT_TMPDIR="$(mktemp -d)" + + local STARLARK_FILE="${STARLARK_OUTPUT_TMPDIR}/print_output_file.starlark" + cat > "${STARLARK_FILE}" << EOF +def format(target): + return target.files.to_list()[0].path +EOF + + local OUTPUT_PATH=$(bazel cquery $1 --output=starlark --starlark:file="${STARLARK_FILE}" 2> /dev/null) + + rm -rf "${STARLARK_OUTPUT_TMPDIR}" + + echo ${OUTPUT_PATH} +} + +# build_target builds a target using the command passed in as argument and +# uses cquery to find the path to the output of the target. +function build_target { + # Build using the command passed as argument. + "${BAZEL}" build $1 + + # Get the path to the output file of the target. + local OUTPUT_PATH=$(get_output_file_path "$1") + + echo ${OUTPUT_PATH} +} + +# build_ios_frameworks_and_libraries builds 3 targets: +# 1. The ios task library xcframework +# 2. Fat static library including graphs needed for the xcframework for all simulator archs (x86_64, arm64). +# 2. Static library including graphs needed for the xcframework for all iOS device archs (arm64). +function build_ios_frameworks_and_libraries { + local TARGET_PREFIX="//mediapipe/tasks/ios" + FULL_FRAMEWORK_TARGET="${TARGET_PREFIX}:${FRAMEWORK_NAME}_framework" + FULL_GRAPH_LIBRARY_TARGET="${TARGET_PREFIX}:${FRAMEWORK_NAME}_GraphLibrary" + + local FRAMEWORK_CQUERY_COMMAND="-c opt --define MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} --define MEDIAPIPE_AVOID_LINKING_GRAPHS=1 \ + --apple_generate_dsym=false ${FULL_FRAMEWORK_TARGET}" + IOS_FRAMEWORK_PATH="$(build_target "${FRAMEWORK_CQUERY_COMMAND}")" + + local IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_sim_fat --define MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} \ + --apple_generate_dsym=false ${FULL_GRAPH_LIBRARY_TARGET}" + IOS_GRAPHS_SIMULATOR_LIBRARY_PATH="$(build_target "${IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND}")" + + local IOS_DEVICE_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_arm64 --define MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} \ + --apple_generate_dsym=false ${FULL_GRAPH_LIBRARY_TARGET}" + IOS_GRAPHS_DEVICE_LIBRARY_PATH="$(build_target "${IOS_DEVICE_LIBRARY_CQUERY_COMMAND}")" +} + +function create_framework_archive { + # Change to the Bazel iOS output directory. + pushd "${BAZEL_IOS_OUTDIR}" + + # Create the temporary directory for the given framework. + local ARCHIVE_NAME="${FRAMEWORK_NAME}-${MPP_BUILD_VERSION}" + local MPP_TMPDIR="$(mktemp -d)" + + # Copy the license file to MPP_TMPDIR + cp "LICENSE" ${MPP_TMPDIR} + + # Unzip the iOS framework zip generated by bazel to MPP_TMPDIR + local FRAMEWORKS_DIR="${MPP_TMPDIR}/frameworks" + + echo ${IOS_FRAMEWORK_PATH} + unzip "${IOS_FRAMEWORK_PATH}" -d "${FRAMEWORKS_DIR}" + + local GRAPH_LIBRARIES_DIR="graph_libraries" + + # Create the parent folder which will hold the graph libraries of all architectures. + mkdir -p "${FRAMEWORKS_DIR}/${GRAPH_LIBRARIES_DIR}" + + local SIMULATOR_GRAPH_LIBRARY_PATH="${FRAMEWORKS_DIR}/${GRAPH_LIBRARIES_DIR}/lib${FRAMEWORK_NAME}_simulator_graph.a" + + # Copy ios simulator fat library into a separate directory. + echo ${IOS_GRAPHS_SIMULATOR_LIBRARY_PATH} + cp "${IOS_GRAPHS_SIMULATOR_LIBRARY_PATH}" "${SIMULATOR_GRAPH_LIBRARY_PATH}" + + + local IOS_DEVICE_GRAPH_LIBRARY_PATH="${FRAMEWORKS_DIR}/${GRAPH_LIBRARIES_DIR}/lib${FRAMEWORK_NAME}_device_graph.a" + + # Copy ios device library into a separate directory. + echo ${IOS_GRAPHS_DEVICE_LIBRARY_PATH} + cp "${IOS_GRAPHS_DEVICE_LIBRARY_PATH}" "${IOS_DEVICE_GRAPH_LIBRARY_PATH}" + + #----- (3) Move the framework to the destination ----- + if [[ "${ARCHIVE_FRAMEWORK}" == true ]]; then + local TARGET_DIR="$(realpath "${FRAMEWORK_NAME}")" + + # Create the framework archive directory. + + local FRAMEWORK_ARCHIVE_DIR + if [[ "${IS_RELEASE_BUILD}" == true ]]; then + # Get the first 16 bytes of the sha256 checksum of the root directory. + local SHA256_CHECKSUM=$(find "${MPP_TMPDIR}" -type f -print0 | xargs -0 shasum -a 256 | sort | shasum -a 256 | cut -c1-16) + FRAMEWORK_ARCHIVE_DIR="${TARGET_DIR}/${MPP_BUILD_VERSION}/${SHA256_CHECKSUM}" + else + FRAMEWORK_ARCHIVE_DIR="${TARGET_DIR}/${MPP_BUILD_VERSION}" + fi + mkdir -p "${FRAMEWORK_ARCHIVE_DIR}" + + # Zip up the framework and move to the archive directory. + pushd "${MPP_TMPDIR}" + local MPP_ARCHIVE_FILE="${ARCHIVE_NAME}.tar.gz" + tar -cvzf "${MPP_ARCHIVE_FILE}" . + mv "${MPP_ARCHIVE_FILE}" "${FRAMEWORK_ARCHIVE_DIR}" + popd + + # Move the target directory to the Kokoro artifacts directory. + mv "${TARGET_DIR}" "$(realpath "${DEST_DIR}")"/ + else + rsync -r "${MPP_TMPDIR}/" "$(realpath "${DEST_DIR}")/" + fi + + # Clean up the temporary directory for the framework. + rm -rf "${MPP_TMPDIR}" + echo ${MPP_TMPDIR} +} + +cd "${MPP_ROOT_DIR}" +build_ios_frameworks_and_libraries +create_framework_archive \ No newline at end of file From 49b2c7c2cc2d3fc8ea6b77f9c5168f7658de7fff Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 18 Apr 2023 23:02:58 +0530 Subject: [PATCH 023/753] Added iOS task text cocoapods podspec --- .../ios/MediaPipeTaskText.podspec.template | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 mediapipe/tasks/ios/MediaPipeTaskText.podspec.template diff --git a/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template b/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template new file mode 100644 index 000000000..ddc9a2b01 --- /dev/null +++ b/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template @@ -0,0 +1,23 @@ +Pod::Spec.new do |s| + s.name = 'MediaPipeTaskText' + s.version = '${MPP_BUILD_VERSION}' + s.authors = 'Google Inc.' + s.license = { :type => 'Apache',:file => "LICENSE" } + s.homepage = 'https://github.com/google/mediapipe' + s.source = { :http => '${MPP_DOWNLOAD_URL}' } + s.summary = 'MediaPipe Task Library - Text' + s.description = 'The Natural Language APIs of the MediaPipe Task Library' + + s.ios.deployment_target = '11.0' + + s.module_name = 'MediaPipeTaskText' + s.static_framework = true + s.user_target_xcconfig = { + 'OTHER_LDFLAGS[sdk=iphonesimulator*]' => '$(inherited) -force_load "$(PODS_ROOT)/MediaPipeTaskText/frameworks/graph_libraries/libMediaPipeTaskText_simulator_graph.a"', + 'OTHER_LDFLAGS[sdk=iphoneos*]' => '$(inherited) -force_load "$(PODS_ROOT)/MediaPipeTaskText/frameworks/graph_libraries/libMediaPipeTaskText_device_graph.a"', + 'STRIP_INSTALLED_PRODUCT' => 'NO' + } + s.library = 'c++' + s.preserve_paths = 'frameworks/graph_libraries/*.a' + s.vendored_frameworks = 'frameworks/MediaPipeTaskText.xcframework' +end \ No newline at end of file From d7c96dea6a9dda2f26506adf0149a442431502b0 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 18 Apr 2023 23:10:47 +0530 Subject: [PATCH 024/753] Updated formatting of files --- mediapipe/tasks/ios/BUILD | 2 +- mediapipe/tasks/ios/MediaPipeTaskText.podspec.template | 2 +- mediapipe/tasks/ios/build_ios_framework.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index 8786ed49f..175d674a8 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -97,4 +97,4 @@ apple_static_library( "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", "@org_tensorflow//third_party/icu/data:conversion_data", ], -) \ No newline at end of file +) diff --git a/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template b/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template index ddc9a2b01..88ec4d989 100644 --- a/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template +++ b/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template @@ -20,4 +20,4 @@ Pod::Spec.new do |s| s.library = 'c++' s.preserve_paths = 'frameworks/graph_libraries/*.a' s.vendored_frameworks = 'frameworks/MediaPipeTaskText.xcframework' -end \ No newline at end of file +end diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index c27a578aa..00eab9280 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -181,4 +181,4 @@ function create_framework_archive { cd "${MPP_ROOT_DIR}" build_ios_frameworks_and_libraries -create_framework_archive \ No newline at end of file +create_framework_archive From eb0aa5056ae9361c9605e96a77719972465caeb9 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 18 Apr 2023 23:20:11 +0530 Subject: [PATCH 025/753] Updated documentation --- mediapipe/tasks/ios/build_ios_framework.sh | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index 00eab9280..c0f0f5f1c 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -58,7 +58,7 @@ if [[ -z "${DEST_DIR+x}" || "${DEST_DIR}" == ${MPP_ROOT_DIR}* ]]; then exit 1 fi -# get_output_file_path takes one bazel target label as an argument, and prints +# This function takes one bazel target label as an argument, and prints # the path of the first output file of the specified target. function get_output_file_path { local STARLARK_OUTPUT_TMPDIR="$(mktemp -d)" @@ -76,7 +76,7 @@ EOF echo ${OUTPUT_PATH} } -# build_target builds a target using the command passed in as argument and +# This function builds a target using the command passed in as argument and # uses cquery to find the path to the output of the target. function build_target { # Build using the command passed as argument. @@ -88,23 +88,30 @@ function build_target { echo ${OUTPUT_PATH} } -# build_ios_frameworks_and_libraries builds 3 targets: +# This function builds 3 targets: # 1. The ios task library xcframework -# 2. Fat static library including graphs needed for the xcframework for all simulator archs (x86_64, arm64). +# 2. Fat static library including graphs needed for tasks in xcframework, for all simulator archs (x86_64, arm64). # 2. Static library including graphs needed for the xcframework for all iOS device archs (arm64). function build_ios_frameworks_and_libraries { local TARGET_PREFIX="//mediapipe/tasks/ios" FULL_FRAMEWORK_TARGET="${TARGET_PREFIX}:${FRAMEWORK_NAME}_framework" FULL_GRAPH_LIBRARY_TARGET="${TARGET_PREFIX}:${FRAMEWORK_NAME}_GraphLibrary" + + # .bazelrc sets --apple_generate_dsym=true by default which bloats the libraries to sizes of the order of GBs. + # All iOS framework and library build commands for distribution via CocoaPods must set + # --apple_generate_dsym=false inorder to shave down the binary size to the order of a few MBs. + # Build Text Task Library xcframework without the graph dependencies. local FRAMEWORK_CQUERY_COMMAND="-c opt --define MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} --define MEDIAPIPE_AVOID_LINKING_GRAPHS=1 \ --apple_generate_dsym=false ${FULL_FRAMEWORK_TARGET}" IOS_FRAMEWORK_PATH="$(build_target "${FRAMEWORK_CQUERY_COMMAND}")" + # Build fat static library for text task graphs for simulator archs. local IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_sim_fat --define MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} \ --apple_generate_dsym=false ${FULL_GRAPH_LIBRARY_TARGET}" IOS_GRAPHS_SIMULATOR_LIBRARY_PATH="$(build_target "${IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND}")" - + + # Build static library for text task graphs for simulator archs. local IOS_DEVICE_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_arm64 --define MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} \ --apple_generate_dsym=false ${FULL_GRAPH_LIBRARY_TARGET}" IOS_GRAPHS_DEVICE_LIBRARY_PATH="$(build_target "${IOS_DEVICE_LIBRARY_CQUERY_COMMAND}")" From 0c4d40547927a2cf0fc48761796ec35520b1da19 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 18 Apr 2023 23:21:14 +0530 Subject: [PATCH 026/753] Updated bazelrc with required config --- .bazelrc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.bazelrc b/.bazelrc index 724dd23fd..44bc3d0a1 100644 --- a/.bazelrc +++ b/.bazelrc @@ -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 From f75eb5795658ba9b8806b344da11256321c79e1b Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 18 Apr 2023 23:46:05 +0530 Subject: [PATCH 027/753] Update build_ios_framework.sh --- mediapipe/tasks/ios/build_ios_framework.sh | 28 ++++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index c0f0f5f1c..ecc1acfb4 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -16,11 +16,11 @@ # Set the following variables as appropriate. # * BAZEL: path to bazel. defaults to the first one available in PATH # * FRAMEWORK_NAME: name of the iOS framework to be built. Currently the -# * accepted values are TensorFlowLiteTaskVision, TensorFlowLiteTaskText. +# * accepted values are MediaPipeTaskText. # * MPP_BUILD_VERSION: to specify the release version. defaults to 0.0.1-dev # * IS_RELEASE_BUILD: set as true if this build should be a release build # * ARCHIVE_FRAMEWORK: set as true if the framework should be archived -# * DEST_DIR: destination directory to which the framework will be copied +# * DEST_DIR: destination directory to which the framework will be copied. set -ex @@ -32,7 +32,7 @@ fi BAZEL="${BAZEL:-$(which bazel)}" MPP_BUILD_VERSION=${MPP_BUILD_VERSION:-0.0.1-dev} MPP_ROOT_DIR=$(git rev-parse --show-toplevel) -MPP_DISABLE_GPU=true +MPP_DISABLE_GPU=1 if [[ ! -x "${BAZEL}" ]]; then echo "bazel executable is not found." @@ -97,23 +97,25 @@ function build_ios_frameworks_and_libraries { FULL_FRAMEWORK_TARGET="${TARGET_PREFIX}:${FRAMEWORK_NAME}_framework" FULL_GRAPH_LIBRARY_TARGET="${TARGET_PREFIX}:${FRAMEWORK_NAME}_GraphLibrary" - # .bazelrc sets --apple_generate_dsym=true by default which bloats the libraries to sizes of the order of GBs. - # All iOS framework and library build commands for distribution via CocoaPods must set - # --apple_generate_dsym=false inorder to shave down the binary size to the order of a few MBs. + # .bazelrc sets --apple_generate_dsym=true by default which bloats the libraries to sizes of + # the order of GBs. All iOS framework and library build commands for distribution via + # CocoaPods must set --apple_generate_dsym=false inorder to shave down the binary size to + # the order of a few MBs. # Build Text Task Library xcframework without the graph dependencies. - local FRAMEWORK_CQUERY_COMMAND="-c opt --define MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} --define MEDIAPIPE_AVOID_LINKING_GRAPHS=1 \ - --apple_generate_dsym=false ${FULL_FRAMEWORK_TARGET}" + local FRAMEWORK_CQUERY_COMMAND="-c opt --define MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} \ + --define MEDIAPIPE_AVOID_LINKING_GRAPHS=1 --apple_generate_dsym=false ${FULL_FRAMEWORK_TARGET}" IOS_FRAMEWORK_PATH="$(build_target "${FRAMEWORK_CQUERY_COMMAND}")" # Build fat static library for text task graphs for simulator archs. - local IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_sim_fat --define MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} \ - --apple_generate_dsym=false ${FULL_GRAPH_LIBRARY_TARGET}" + local IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_sim_fat --define \ + MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} --apple_generate_dsym=false ${FULL_GRAPH_LIBRARY_TARGET}" IOS_GRAPHS_SIMULATOR_LIBRARY_PATH="$(build_target "${IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND}")" - # Build static library for text task graphs for simulator archs. - local IOS_DEVICE_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_arm64 --define MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} \ - --apple_generate_dsym=false ${FULL_GRAPH_LIBRARY_TARGET}" + # Build static library for iOS devices with arch ios_arm64. We don't need to build for armv7 since + # our deployment target is iOS 11.0. iOS 11.0 d anupwards is not supported by old armv7 devices. + local IOS_DEVICE_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_arm64 --define \ + MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} --apple_generate_dsym=false ${FULL_GRAPH_LIBRARY_TARGET}" IOS_GRAPHS_DEVICE_LIBRARY_PATH="$(build_target "${IOS_DEVICE_LIBRARY_CQUERY_COMMAND}")" } From 99420d35f397a1e3c79cee5c6d29a0ae40432ba1 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 19 Apr 2023 00:25:10 +0530 Subject: [PATCH 028/753] Update build_ios_framework.sh --- mediapipe/tasks/ios/build_ios_framework.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index ecc1acfb4..48bc0419c 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -90,8 +90,10 @@ function build_target { # This function builds 3 targets: # 1. The ios task library xcframework -# 2. Fat static library including graphs needed for tasks in xcframework, for all simulator archs (x86_64, arm64). -# 2. Static library including graphs needed for the xcframework for all iOS device archs (arm64). +# 2. Fat static library including graphs needed for tasks in xcframework, for all +# simulator archs (x86_64, arm64). +# 3. Static library including graphs needed for the xcframework for all iOS device +# archs (arm64). function build_ios_frameworks_and_libraries { local TARGET_PREFIX="//mediapipe/tasks/ios" FULL_FRAMEWORK_TARGET="${TARGET_PREFIX}:${FRAMEWORK_NAME}_framework" From d7039c90dc9eebf047d099ee97c980c23c0c51ad Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Tue, 18 Apr 2023 14:02:43 -0700 Subject: [PATCH 029/753] Update WASM for Alpha 11 PiperOrigin-RevId: 525245471 --- third_party/wasm_files.bzl | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/third_party/wasm_files.bzl b/third_party/wasm_files.bzl index 148b5970f..a484d2f82 100644 --- a/third_party/wasm_files.bzl +++ b/third_party/wasm_files.bzl @@ -12,72 +12,72 @@ def wasm_files(): http_file( name = "com_google_mediapipe_wasm_audio_wasm_internal_js", - sha256 = "0eca68e2291a548b734bcab5db4c9e6b997e852ea7e19228003b9e2a78c7c646", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.js?generation=1681328323089931"], + sha256 = "b810de53d7ccf991b9c70fcdf7e88b5c3f2942ae766436f22be48159b6a7e687", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.js?generation=1681849488227617"], ) http_file( name = "com_google_mediapipe_wasm_audio_wasm_internal_wasm", - sha256 = "69bc95af5b783b510ec1842d6fb9594254907d8e1334799c5753164878a7dcac", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.wasm?generation=1681328325829340"], + sha256 = "26d91147e5c6c8a92e0a4ebf59599068a3cff6108847b793ef33ac23e98eddb9", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.wasm?generation=1681849491546937"], ) http_file( name = "com_google_mediapipe_wasm_audio_wasm_nosimd_internal_js", - sha256 = "88a0176cc80d6a1eb175a5105df705cf8b8684cf13f6db0a264af0b67b65a22a", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.js?generation=1681328328330829"], + sha256 = "b38e37b3024692558eaaba159921fedd3297d1a09bba1c16a06fed327845b0bd", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.js?generation=1681849494099698"], ) http_file( name = "com_google_mediapipe_wasm_audio_wasm_nosimd_internal_wasm", - sha256 = "1cc0c3db7d252801be4b090d8bbba61f308cc3dd5efe197319581d3af29495c7", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.wasm?generation=1681328331085637"], + sha256 = "6a8e73d2e926565046e16adf1748f0f8ec5135fafe7eb8b9c83892e64c1a449a", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.wasm?generation=1681849496451970"], ) http_file( name = "com_google_mediapipe_wasm_text_wasm_internal_js", - sha256 = "d9cd100b6d330d36f7749fe5fc64a2cdd0abb947a0376e6140784cfb0361a4e2", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.js?generation=1681328333442454"], + sha256 = "785cba67b623b1dc66dc3621e97fd6b30edccbb408184a3094d0aa68ddd5becb", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.js?generation=1681849498746265"], ) http_file( name = "com_google_mediapipe_wasm_text_wasm_internal_wasm", - sha256 = "30a2fcca630bdad6e99173ea7d0d8c5d7086aedf393d0159fa05bf9d08d4ff65", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.wasm?generation=1681328335803336"], + sha256 = "a858b8a2e8b40e9c936b66566c5aefd396536c4e936459ab9ae7e239621adc14", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.wasm?generation=1681849501370461"], ) http_file( name = "com_google_mediapipe_wasm_text_wasm_nosimd_internal_js", - sha256 = "70ca2bd15c56e0ce7bb10ff2188b4a1f9eafbb657eb9424e4cab8d7b29179871", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.js?generation=1681328338162884"], + sha256 = "5292f1442d5e5c037e7cffb78a8c2d71255348ca2c3bd759b314bdbedd5590c2", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.js?generation=1681849503379116"], ) http_file( name = "com_google_mediapipe_wasm_text_wasm_nosimd_internal_wasm", - sha256 = "8221b385905f36a769d7731a0adbe18b681bcb873561890429ca84278c67c3fd", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.wasm?generation=1681328340808115"], + sha256 = "e44b48ab29ee1d8befec804e9a63445c56266b679d19fb476d556ca621f0e493", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.wasm?generation=1681849505997020"], ) http_file( name = "com_google_mediapipe_wasm_vision_wasm_internal_js", - sha256 = "07692acd8202adafebd35dbcd7e2b8e88a76d4a0e6b9229cb3cad59503eeddc7", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.js?generation=1681328343147709"], + sha256 = "205855eba70464a92b9d00e90acac15c51a9f76192f900e697304ac6dea8f714", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.js?generation=1681849508414277"], ) http_file( name = "com_google_mediapipe_wasm_vision_wasm_internal_wasm", - sha256 = "03bf553fa6a768b0d70103a5e7d835b6b37371ff44e201c3392f22e0879737c3", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.wasm?generation=1681328345605574"], + sha256 = "c0cbd0df3adb2a9cd1331d14f522d2bae9f8adc9f1b35f92cbbc4b782b190cef", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.wasm?generation=1681849510936608"], ) http_file( name = "com_google_mediapipe_wasm_vision_wasm_nosimd_internal_js", - sha256 = "36697be14f921985eac15d1447ec8a260817b05ade1c9bb3ca7e906e0f047ec0", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.js?generation=1681328348025082"], + sha256 = "0969812de4d3573198fa2eba4f5b0a7e97e98f97bd4215d876543f4925e57b84", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.js?generation=1681849513292639"], ) http_file( name = "com_google_mediapipe_wasm_vision_wasm_nosimd_internal_wasm", - sha256 = "103fb145438d61cfecb2e8db3f06b43a5d77a7e3fcea940437fe272227cf2592", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.wasm?generation=1681328350709881"], + sha256 = "f2ab62c3f8dabab0a573dadf5c105ff81a03c29c70f091f8cf273ae030c0a86f", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.wasm?generation=1681849515999000"], ) From 1cb404bea16a4f36df8abeb583a72b9819776583 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Tue, 18 Apr 2023 21:31:14 -0700 Subject: [PATCH 030/753] Changed labels to be a property --- .../test/vision/image_segmenter_test.py | 8 +++-- .../tasks/python/vision/image_segmenter.py | 31 ++++++++++--------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/mediapipe/tasks/python/test/vision/image_segmenter_test.py b/mediapipe/tasks/python/test/vision/image_segmenter_test.py index b54b53994..3458bb504 100644 --- a/mediapipe/tasks/python/test/vision/image_segmenter_test.py +++ b/mediapipe/tasks/python/test/vision/image_segmenter_test.py @@ -247,14 +247,16 @@ class ImageSegmenterTest(parameterized.TestCase): ) ) - def test_get_labels_succeeds(self): + def test_labels_succeeds(self): expected_labels = _EXPECTED_LABELS base_options = _BaseOptions(model_asset_path=self.model_path) options = _ImageSegmenterOptions( - base_options=base_options, output_type=_OutputType.CATEGORY_MASK) + base_options=base_options, output_category_mask=True, + output_confidence_masks=False + ) with _ImageSegmenter.create_from_options(options) as segmenter: # Performs image segmentation on the input. - actual_labels = segmenter.get_labels() + actual_labels = segmenter.labels self.assertListEqual(actual_labels, expected_labels) def test_missing_result_callback(self): diff --git a/mediapipe/tasks/python/vision/image_segmenter.py b/mediapipe/tasks/python/vision/image_segmenter.py index 4119f2632..a6c9501c2 100644 --- a/mediapipe/tasks/python/vision/image_segmenter.py +++ b/mediapipe/tasks/python/vision/image_segmenter.py @@ -151,7 +151,7 @@ class ImageSegmenter(base_vision_task_api.BaseVisionTaskApi): Exception if there is an error during finding TensorsToSegmentationCalculator. :return: """ - self.labels = [] + self._labels = [] graph_config = self._runner.get_graph_config() found_tensors_to_segmentation = False @@ -170,7 +170,7 @@ class ImageSegmenter(base_vision_task_api.BaseVisionTaskApi): for i in range(len(options.label_items)): if i not in options.label_items: raise Exception(f"The labelmap has no expected key: {i}.") - self.labels.append(options.label_items[i].name) + self._labels.append(options.label_items[i].name) @classmethod def create_from_model_path(cls, model_path: str) -> 'ImageSegmenter': @@ -271,19 +271,6 @@ class ImageSegmenter(base_vision_task_api.BaseVisionTaskApi): packets_callback if options.result_callback else None, ) - def get_labels(self): - """ Get the category label list of the ImageSegmenter can recognize. - - For CATEGORY_MASK type, the index in the category mask corresponds to the - category in the label list. - For CONFIDENCE_MASK type, the output mask list at index corresponds to the - category in the label list. - - If there is no label map provided in the model file, empty label list is - returned. - """ - return self.labels - def segment( self, image: image_module.Image, @@ -427,3 +414,17 @@ class ImageSegmenter(base_vision_task_api.BaseVisionTaskApi): normalized_rect.to_pb2() ).at(timestamp_ms * _MICRO_SECONDS_PER_MILLISECOND), }) + + @property + def labels(self) -> List[str]: + """ Get the category label list of the ImageSegmenter can recognize. + + For CATEGORY_MASK type, the index in the category mask corresponds to the + category in the label list. + For CONFIDENCE_MASK type, the output mask list at index corresponds to the + category in the label list. + + If there is no label map provided in the model file, empty label list is + returned. + """ + return self._labels From 67b72e4fe9b6765c3d134d88a6ba77ac50a35a05 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Tue, 18 Apr 2023 21:43:38 -0700 Subject: [PATCH 031/753] Code cleanup --- .../python/test/vision/image_segmenter_test.py | 7 ++++--- mediapipe/tasks/python/vision/image_segmenter.py | 15 ++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/mediapipe/tasks/python/test/vision/image_segmenter_test.py b/mediapipe/tasks/python/test/vision/image_segmenter_test.py index 3458bb504..009dc685a 100644 --- a/mediapipe/tasks/python/test/vision/image_segmenter_test.py +++ b/mediapipe/tasks/python/test/vision/image_segmenter_test.py @@ -247,12 +247,13 @@ class ImageSegmenterTest(parameterized.TestCase): ) ) - def test_labels_succeeds(self): + @parameterized.parameters((True, False), (False, True)) + def test_labels_succeeds(self, output_category_mask, output_confidence_masks): expected_labels = _EXPECTED_LABELS base_options = _BaseOptions(model_asset_path=self.model_path) options = _ImageSegmenterOptions( - base_options=base_options, output_category_mask=True, - output_confidence_masks=False + base_options=base_options, output_category_mask=output_category_mask, + output_confidence_masks=output_confidence_masks ) with _ImageSegmenter.create_from_options(options) as segmenter: # Performs image segmentation on the input. diff --git a/mediapipe/tasks/python/vision/image_segmenter.py b/mediapipe/tasks/python/vision/image_segmenter.py index a6c9501c2..220d7818f 100644 --- a/mediapipe/tasks/python/vision/image_segmenter.py +++ b/mediapipe/tasks/python/vision/image_segmenter.py @@ -129,27 +129,28 @@ class ImageSegmenter(base_vision_task_api.BaseVisionTaskApi): Output tensors: (kTfLiteUInt8/kTfLiteFloat32) - list of segmented masks. - - if `output_type` is CATEGORY_MASK, uint8 Image, Image vector of size 1. - - if `output_type` is CONFIDENCE_MASK, float32 Image list of size + - if `output_category_mask` is True, uint8 Image, Image vector of size 1. + - if `output_confidence_masks` is True, float32 Image list of size `channels`. - batch is always 1 An example of such model can be found at: https://tfhub.dev/tensorflow/lite-model/deeplabv3/1/metadata/2 """ - def __init__(self, graph_config, running_mode, packet_callback): + def __init__(self, graph_config, running_mode, packet_callback) -> None: + """Initializes the `ImageSegmenter` object.""" super(ImageSegmenter, self).__init__( graph_config, running_mode, packet_callback ) self._populate_labels() - def _populate_labels(self): + def _populate_labels(self) -> None: """ Populate the labelmap in TensorsToSegmentationCalculator to labels field. - Returns: - Exception if there is an error during finding TensorsToSegmentationCalculator. - :return: + Raises: + Exception if there is an error during finding + TensorsToSegmentationCalculator. """ self._labels = [] graph_config = self._runner.get_graph_config() From a1aab66c8d0635c2f9d26f6dc41c7517c6e82dfc Mon Sep 17 00:00:00 2001 From: kinaryml Date: Tue, 18 Apr 2023 21:50:27 -0700 Subject: [PATCH 032/753] Fixed a typo in docstring --- mediapipe/tasks/python/vision/image_segmenter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/python/vision/image_segmenter.py b/mediapipe/tasks/python/vision/image_segmenter.py index 220d7818f..077f7d285 100644 --- a/mediapipe/tasks/python/vision/image_segmenter.py +++ b/mediapipe/tasks/python/vision/image_segmenter.py @@ -418,7 +418,7 @@ class ImageSegmenter(base_vision_task_api.BaseVisionTaskApi): @property def labels(self) -> List[str]: - """ Get the category label list of the ImageSegmenter can recognize. + """ Get the category label list the ImageSegmenter can recognize. For CATEGORY_MASK type, the index in the category mask corresponds to the category in the label list. From 1688d0fa7949ee5bef3fdd04287c39f3bb9cd4d2 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Tue, 18 Apr 2023 22:45:46 -0700 Subject: [PATCH 033/753] Added more pose landmarker tests and updated face landmarker tests to cover all the results --- .../test/vision/face_landmarker_test.py | 54 ++-- .../test/vision/pose_landmarker_test.py | 276 ++++++++++++++++-- .../tasks/python/vision/pose_landmarker.py | 8 +- 3 files changed, 281 insertions(+), 57 deletions(-) diff --git a/mediapipe/tasks/python/test/vision/face_landmarker_test.py b/mediapipe/tasks/python/test/vision/face_landmarker_test.py index 0cf16f3ea..5028f8545 100644 --- a/mediapipe/tasks/python/test/vision/face_landmarker_test.py +++ b/mediapipe/tasks/python/test/vision/face_landmarker_test.py @@ -58,17 +58,20 @@ _FACIAL_TRANSFORMATION_MATRIX_DIFF_MARGIN = 0.02 def _get_expected_face_landmarks(file_path: str): proto_file_path = test_utils.get_test_data_path(file_path) + face_landmarks_results = [] with open(proto_file_path, 'rb') as f: proto = landmark_pb2.NormalizedLandmarkList() text_format.Parse(f.read(), proto) face_landmarks = [] for landmark in proto.landmark: face_landmarks.append(_NormalizedLandmark.create_from_pb2(landmark)) - return face_landmarks + face_landmarks_results.append(face_landmarks) + return face_landmarks_results def _get_expected_face_blendshapes(file_path: str): proto_file_path = test_utils.get_test_data_path(file_path) + face_blendshapes_results = [] with open(proto_file_path, 'rb') as f: proto = classification_pb2.ClassificationList() text_format.Parse(f.read(), proto) @@ -84,7 +87,8 @@ def _get_expected_face_blendshapes(file_path: str): category_name=face_blendshapes.label, ) ) - return face_blendshapes_categories + face_blendshapes_results.append(face_blendshapes_categories) + return face_blendshapes_results def _get_expected_facial_transformation_matrixes(): @@ -119,13 +123,14 @@ class FaceLandmarkerTest(parameterized.TestCase): # Expects to have the same number of faces detected. self.assertLen(actual_landmarks, len(expected_landmarks)) - for i, elem in enumerate(actual_landmarks): - self.assertAlmostEqual( - elem.x, expected_landmarks[i].x, delta=_LANDMARKS_DIFF_MARGIN - ) - self.assertAlmostEqual( - elem.y, expected_landmarks[i].y, delta=_LANDMARKS_DIFF_MARGIN - ) + for i, _ in enumerate(actual_landmarks): + for j, elem in enumerate(actual_landmarks[i]): + self.assertAlmostEqual( + elem.x, expected_landmarks[i][j].x, delta=_LANDMARKS_DIFF_MARGIN + ) + self.assertAlmostEqual( + elem.y, expected_landmarks[i][j].y, delta=_LANDMARKS_DIFF_MARGIN + ) def _expect_blendshapes_correct( self, actual_blendshapes, expected_blendshapes @@ -133,13 +138,14 @@ class FaceLandmarkerTest(parameterized.TestCase): # Expects to have the same number of blendshapes. self.assertLen(actual_blendshapes, len(expected_blendshapes)) - for i, elem in enumerate(actual_blendshapes): - self.assertEqual(elem.index, expected_blendshapes[i].index) - self.assertAlmostEqual( - elem.score, - expected_blendshapes[i].score, - delta=_BLENDSHAPES_DIFF_MARGIN, - ) + for i, _ in enumerate(actual_blendshapes): + for j, elem in enumerate(actual_blendshapes[i]): + self.assertEqual(elem.index, expected_blendshapes[i][j].index) + self.assertAlmostEqual( + elem.score, + expected_blendshapes[i][j].score, + delta=_BLENDSHAPES_DIFF_MARGIN, + ) def _expect_facial_transformation_matrixes_correct( self, actual_matrix_list, expected_matrix_list @@ -236,11 +242,11 @@ class FaceLandmarkerTest(parameterized.TestCase): # Comparing results. if expected_face_landmarks is not None: self._expect_landmarks_correct( - detection_result.face_landmarks[0], expected_face_landmarks + detection_result.face_landmarks, expected_face_landmarks ) if expected_face_blendshapes is not None: self._expect_blendshapes_correct( - detection_result.face_blendshapes[0], expected_face_blendshapes + detection_result.face_blendshapes, expected_face_blendshapes ) if expected_facial_transformation_matrixes is not None: self._expect_facial_transformation_matrixes_correct( @@ -302,11 +308,11 @@ class FaceLandmarkerTest(parameterized.TestCase): # Comparing results. if expected_face_landmarks is not None: self._expect_landmarks_correct( - detection_result.face_landmarks[0], expected_face_landmarks + detection_result.face_landmarks, expected_face_landmarks ) if expected_face_blendshapes is not None: self._expect_blendshapes_correct( - detection_result.face_blendshapes[0], expected_face_blendshapes + detection_result.face_blendshapes, expected_face_blendshapes ) if expected_facial_transformation_matrixes is not None: self._expect_facial_transformation_matrixes_correct( @@ -446,11 +452,11 @@ class FaceLandmarkerTest(parameterized.TestCase): # Comparing results. if expected_face_landmarks is not None: self._expect_landmarks_correct( - detection_result.face_landmarks[0], expected_face_landmarks + detection_result.face_landmarks, expected_face_landmarks ) if expected_face_blendshapes is not None: self._expect_blendshapes_correct( - detection_result.face_blendshapes[0], expected_face_blendshapes + detection_result.face_blendshapes, expected_face_blendshapes ) if expected_facial_transformation_matrixes is not None: self._expect_facial_transformation_matrixes_correct( @@ -523,11 +529,11 @@ class FaceLandmarkerTest(parameterized.TestCase): # Comparing results. if expected_face_landmarks is not None: self._expect_landmarks_correct( - result.face_landmarks[0], expected_face_landmarks + result.face_landmarks, expected_face_landmarks ) if expected_face_blendshapes is not None: self._expect_blendshapes_correct( - result.face_blendshapes[0], expected_face_blendshapes + result.face_blendshapes, expected_face_blendshapes ) if expected_facial_transformation_matrixes is not None: self._expect_facial_transformation_matrixes_correct( diff --git a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py index a1704e7f6..974389a0b 100644 --- a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py +++ b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py @@ -14,6 +14,7 @@ """Tests for pose landmarker.""" import enum +from typing import List from unittest import mock from absl.testing import absltest @@ -49,8 +50,8 @@ _POSE_LANDMARKER_BUNDLE_ASSET_FILE = 'pose_landmarker.task' _BURGER_IMAGE = 'burger.jpg' _POSE_IMAGE = 'pose.jpg' _POSE_LANDMARKS = 'pose_landmarks.pbtxt' -_LANDMARKS_ERROR_TOLERANCE = 0.03 -_LANDMARKS_ON_VIDEO_ERROR_TOLERANCE = 0.03 +_LANDMARKS_DIFF_MARGIN = 0.03 +_LANDMARKS_ON_VIDEO_DIFF_MARGIN = 0.03 def _get_expected_pose_landmarker_result( @@ -85,33 +86,34 @@ class PoseLandmarkerTest(parameterized.TestCase): self.model_path = test_utils.get_test_data_path( _POSE_LANDMARKER_BUNDLE_ASSET_FILE) - def _expect_pose_landmarker_results_correct( - self, - actual_result: PoseLandmarkerResult, - expected_result: PoseLandmarkerResult, - error_tolerance: float + def _expect_pose_landmarks_correct( + self, + actual_landmarks: List[List[landmark_module.NormalizedLandmark]], + expected_landmarks: List[List[landmark_module.NormalizedLandmark]], + diff_margin: float ): # Expects to have the same number of poses detected. - self.assertLen(actual_result.pose_landmarks, - len(expected_result.pose_landmarks)) - self.assertLen(actual_result.pose_world_landmarks, - len(expected_result.pose_world_landmarks)) - self.assertLen(actual_result.pose_auxiliary_landmarks, - len(expected_result.pose_auxiliary_landmarks)) - # Actual landmarks match expected landmarks. - actual_landmarks = actual_result.pose_landmarks[0] - expected_landmarks = expected_result.pose_landmarks[0] - for i, pose_landmark in enumerate(actual_landmarks): - self.assertAlmostEqual( - pose_landmark.x, - expected_landmarks[i].x, - delta=error_tolerance - ) - self.assertAlmostEqual( - pose_landmark.y, - expected_landmarks[i].y, - delta=error_tolerance - ) + self.assertLen(actual_landmarks, len(expected_landmarks)) + + for i, _ in enumerate(actual_landmarks): + for j, elem in enumerate(actual_landmarks[i]): + self.assertAlmostEqual( + elem.x, expected_landmarks[i][j].x, delta=diff_margin + ) + self.assertAlmostEqual( + elem.y, expected_landmarks[i][j].y, delta=diff_margin + ) + + def _expect_pose_landmarker_results_correct( + self, + actual_result: PoseLandmarkerResult, + expected_result: PoseLandmarkerResult, + diff_margin: float + ): + self._expect_pose_landmarks_correct( + actual_result.pose_landmarks, expected_result.pose_landmarks, + diff_margin + ) def test_create_from_file_succeeds_with_valid_model_path(self): # Creates with default option and valid model file successfully. @@ -146,7 +148,8 @@ class PoseLandmarkerTest(parameterized.TestCase): (ModelFileType.FILE_NAME, _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), (ModelFileType.FILE_CONTENT, - _get_expected_pose_landmarker_result(_POSE_LANDMARKS))) + _get_expected_pose_landmarker_result(_POSE_LANDMARKS)) + ) def test_detect(self, model_file_type, expected_detection_result): # Creates pose landmarker. if model_file_type is ModelFileType.FILE_NAME: @@ -164,14 +167,229 @@ class PoseLandmarkerTest(parameterized.TestCase): # Performs pose landmarks detection on the input. detection_result = landmarker.detect(self.test_image) + # Comparing results. self._expect_pose_landmarker_results_correct( - detection_result, expected_detection_result, _LANDMARKS_ERROR_TOLERANCE + detection_result, expected_detection_result, _LANDMARKS_DIFF_MARGIN ) # Closes the pose landmarker explicitly when the pose landmarker is not used # in a context. landmarker.close() + @parameterized.parameters( + (ModelFileType.FILE_NAME, + _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), + (ModelFileType.FILE_CONTENT, + _get_expected_pose_landmarker_result(_POSE_LANDMARKS)) + ) + def test_detect_in_context(self, model_file_type, expected_detection_result): + # Creates pose landmarker. + if model_file_type is ModelFileType.FILE_NAME: + base_options = _BaseOptions(model_asset_path=self.model_path) + elif model_file_type is ModelFileType.FILE_CONTENT: + with open(self.model_path, 'rb') as f: + model_content = f.read() + base_options = _BaseOptions(model_asset_buffer=model_content) + else: + # Should never happen + raise ValueError('model_file_type is invalid.') + + options = _PoseLandmarkerOptions(base_options=base_options) + with _PoseLandmarker.create_from_options(options) as landmarker: + # Performs pose landmarks detection on the input. + detection_result = landmarker.detect(self.test_image) + + # Comparing results. + self._expect_pose_landmarker_results_correct( + detection_result, expected_detection_result, _LANDMARKS_DIFF_MARGIN + ) + + def test_detect_fails_with_region_of_interest(self): + # Creates pose landmarker. + base_options = _BaseOptions(model_asset_path=self.model_path) + options = _PoseLandmarkerOptions(base_options=base_options) + with self.assertRaisesRegex( + ValueError, "This task doesn't support region-of-interest."): + with _PoseLandmarker.create_from_options(options) as landmarker: + # Set the `region_of_interest` parameter using `ImageProcessingOptions`. + image_processing_options = _ImageProcessingOptions( + region_of_interest=_Rect(0, 0, 1, 1)) + # Attempt to perform pose landmarks detection on the cropped input. + landmarker.detect(self.test_image, image_processing_options) + + def test_empty_detection_outputs(self): + # Creates pose landmarker. + base_options = _BaseOptions(model_asset_path=self.model_path) + options = _PoseLandmarkerOptions(base_options=base_options) + with _PoseLandmarker.create_from_options(options) as landmarker: + # Load an image with no poses. + test_image = _Image.create_from_file( + test_utils.get_test_data_path(_BURGER_IMAGE)) + # Performs pose landmarks detection on the input. + detection_result = landmarker.detect(test_image) + # Comparing results. + self.assertEmpty(detection_result.pose_landmarks) + self.assertEmpty(detection_result.pose_world_landmarks) + self.assertEmpty(detection_result.pose_auxiliary_landmarks) + + def test_missing_result_callback(self): + options = _PoseLandmarkerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.LIVE_STREAM) + with self.assertRaisesRegex(ValueError, + r'result callback must be provided'): + with _PoseLandmarker.create_from_options(options) as unused_landmarker: + pass + + @parameterized.parameters((_RUNNING_MODE.IMAGE), (_RUNNING_MODE.VIDEO)) + def test_illegal_result_callback(self, running_mode): + options = _PoseLandmarkerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=running_mode, + result_callback=mock.MagicMock()) + with self.assertRaisesRegex(ValueError, + r'result callback should not be provided'): + with _PoseLandmarker.create_from_options(options) as unused_landmarker: + pass + + def test_calling_detect_for_video_in_image_mode(self): + options = _PoseLandmarkerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.IMAGE) + with _PoseLandmarker.create_from_options(options) as landmarker: + with self.assertRaisesRegex(ValueError, + r'not initialized with the video mode'): + landmarker.detect_for_video(self.test_image, 0) + + def test_calling_detect_async_in_image_mode(self): + options = _PoseLandmarkerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.IMAGE) + with _PoseLandmarker.create_from_options(options) as landmarker: + with self.assertRaisesRegex(ValueError, + r'not initialized with the live stream mode'): + landmarker.detect_async(self.test_image, 0) + + def test_calling_detect_in_video_mode(self): + options = _PoseLandmarkerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.VIDEO) + with _PoseLandmarker.create_from_options(options) as landmarker: + with self.assertRaisesRegex(ValueError, + r'not initialized with the image mode'): + landmarker.detect(self.test_image) + + def test_calling_detect_async_in_video_mode(self): + options = _PoseLandmarkerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.VIDEO) + with _PoseLandmarker.create_from_options(options) as landmarker: + with self.assertRaisesRegex(ValueError, + r'not initialized with the live stream mode'): + landmarker.detect_async(self.test_image, 0) + + def test_detect_for_video_with_out_of_order_timestamp(self): + options = _PoseLandmarkerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.VIDEO) + with _PoseLandmarker.create_from_options(options) as landmarker: + unused_result = landmarker.detect_for_video(self.test_image, 1) + with self.assertRaisesRegex( + ValueError, r'Input timestamp must be monotonically increasing'): + landmarker.detect_for_video(self.test_image, 0) + + @parameterized.parameters( + (_POSE_IMAGE, 0, + _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), + (_BURGER_IMAGE, 0, + PoseLandmarkerResult([], [], [])) + ) + def test_detect_for_video(self, image_path, rotation, expected_result): + test_image = _Image.create_from_file( + test_utils.get_test_data_path(image_path)) + # Set rotation parameters using ImageProcessingOptions. + image_processing_options = _ImageProcessingOptions( + rotation_degrees=rotation) + options = _PoseLandmarkerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.VIDEO) + with _PoseLandmarker.create_from_options(options) as landmarker: + for timestamp in range(0, 300, 30): + result = landmarker.detect_for_video(test_image, timestamp, + image_processing_options) + if result.pose_landmarks: + self._expect_pose_landmarker_results_correct( + result, expected_result, _LANDMARKS_ON_VIDEO_DIFF_MARGIN + ) + else: + self.assertEqual(result, expected_result) + + def test_calling_detect_in_live_stream_mode(self): + options = _PoseLandmarkerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.LIVE_STREAM, + result_callback=mock.MagicMock()) + with _PoseLandmarker.create_from_options(options) as landmarker: + with self.assertRaisesRegex(ValueError, + r'not initialized with the image mode'): + landmarker.detect(self.test_image) + + def test_calling_detect_for_video_in_live_stream_mode(self): + options = _PoseLandmarkerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.LIVE_STREAM, + result_callback=mock.MagicMock()) + with _PoseLandmarker.create_from_options(options) as landmarker: + with self.assertRaisesRegex(ValueError, + r'not initialized with the video mode'): + landmarker.detect_for_video(self.test_image, 0) + + def test_detect_async_calls_with_illegal_timestamp(self): + options = _PoseLandmarkerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.LIVE_STREAM, + result_callback=mock.MagicMock()) + with _PoseLandmarker.create_from_options(options) as landmarker: + landmarker.detect_async(self.test_image, 100) + with self.assertRaisesRegex( + ValueError, r'Input timestamp must be monotonically increasing'): + landmarker.detect_async(self.test_image, 0) + + @parameterized.parameters( + (_POSE_IMAGE, 0, + _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), + (_BURGER_IMAGE, 0, + PoseLandmarkerResult([], [], [])) + ) + def test_detect_async_calls(self, image_path, rotation, expected_result): + test_image = _Image.create_from_file( + test_utils.get_test_data_path(image_path)) + # Set rotation parameters using ImageProcessingOptions. + image_processing_options = _ImageProcessingOptions( + rotation_degrees=rotation) + observed_timestamp_ms = -1 + + def check_result(result: PoseLandmarkerResult, output_image: _Image, + timestamp_ms: int): + if result.pose_landmarks: + self._expect_pose_landmarker_results_correct( + result, expected_result, _LANDMARKS_DIFF_MARGIN + ) + else: + self.assertEqual(result, expected_result) + self.assertTrue( + np.array_equal(output_image.numpy_view(), test_image.numpy_view())) + self.assertLess(observed_timestamp_ms, timestamp_ms) + self.observed_timestamp_ms = timestamp_ms + + options = _PoseLandmarkerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.LIVE_STREAM, + result_callback=check_result) + with _PoseLandmarker.create_from_options(options) as landmarker: + for timestamp in range(0, 300, 30): + landmarker.detect_async(test_image, timestamp, image_processing_options) + if __name__ == '__main__': absltest.main() diff --git a/mediapipe/tasks/python/vision/pose_landmarker.py b/mediapipe/tasks/python/vision/pose_landmarker.py index 370c77256..6c347bf75 100644 --- a/mediapipe/tasks/python/vision/pose_landmarker.py +++ b/mediapipe/tasks/python/vision/pose_landmarker.py @@ -64,7 +64,7 @@ class PoseLandmarkerResult: pose_world_landmarks: Detected pose landmarks in world coordinates. pose_auxiliary_landmarks: Detected auxiliary landmarks, used for deriving ROI for next frame. - segmentation_masks: Segmentation masks for pose. + segmentation_masks: Optional segmentation masks for pose. """ pose_landmarks: List[List[landmark_module.NormalizedLandmark]] @@ -77,7 +77,7 @@ def _build_landmarker_result( output_packets: Mapping[str, packet_module.Packet] ) -> PoseLandmarkerResult: """Constructs a `PoseLandmarkerResult` from output packets.""" - pose_landmarker_result = PoseLandmarkerResult([], [], [], []) + pose_landmarker_result = PoseLandmarkerResult([], [], []) if _SEGMENTATION_MASK_STREAM_NAME in output_packets: pose_landmarker_result.segmentation_masks = packet_getter.get_image_list( @@ -356,7 +356,7 @@ class PoseLandmarker(base_vision_task_api.BaseVisionTaskApi): image_processing_options: Options for image processing. Returns: - The pose landmarks detection results. + The pose landmarker detection results. Raises: ValueError: If any of the input arguments is invalid. @@ -402,7 +402,7 @@ class PoseLandmarker(base_vision_task_api.BaseVisionTaskApi): per input image. The `result_callback` provides: - - The pose landmarks detection results. + - The pose landmarker detection results. - The input image that the pose landmarker runs on. - The input timestamp in milliseconds. From 00f966655bc49615605e5b4a1bab900f6fcbd9be Mon Sep 17 00:00:00 2001 From: kinaryml Date: Tue, 18 Apr 2023 22:48:37 -0700 Subject: [PATCH 034/753] Fixed a typo in a docstring --- mediapipe/tasks/python/vision/pose_landmarker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/python/vision/pose_landmarker.py b/mediapipe/tasks/python/vision/pose_landmarker.py index 6c347bf75..1e6945ec9 100644 --- a/mediapipe/tasks/python/vision/pose_landmarker.py +++ b/mediapipe/tasks/python/vision/pose_landmarker.py @@ -137,7 +137,7 @@ class PoseLandmarkerOptions: Attributes: base_options: Base options for the pose landmarker task. running_mode: The running mode of the task. Default to the image mode. - HandLandmarker has three running modes: 1) The image mode for detecting + PoseLandmarker has three running modes: 1) The image mode for detecting pose landmarks on single image inputs. 2) The video mode for detecting pose landmarks on the decoded frames of a video. 3) The live stream mode for detecting pose landmarks on the live stream of input data, such as From f87ffd92a0e732b536f4ea1ab818fac92451a11f Mon Sep 17 00:00:00 2001 From: kinaryml Date: Tue, 18 Apr 2023 23:28:10 -0700 Subject: [PATCH 035/753] Removed optional for defaults in some tasks and updated various tests to be consistent with that of Pose Landmarker's --- .../test/vision/face_landmarker_test.py | 14 ++-- .../test/vision/hand_landmarker_test.py | 81 +++++++++++-------- .../test/vision/pose_landmarker_test.py | 24 +++--- .../tasks/python/vision/face_detector.py | 4 +- .../tasks/python/vision/face_landmarker.py | 12 +-- .../tasks/python/vision/gesture_recognizer.py | 12 +-- .../tasks/python/vision/hand_landmarker.py | 8 +- 7 files changed, 82 insertions(+), 73 deletions(-) diff --git a/mediapipe/tasks/python/test/vision/face_landmarker_test.py b/mediapipe/tasks/python/test/vision/face_landmarker_test.py index 5028f8545..590cca750 100644 --- a/mediapipe/tasks/python/test/vision/face_landmarker_test.py +++ b/mediapipe/tasks/python/test/vision/face_landmarker_test.py @@ -51,9 +51,9 @@ _PORTRAIT_IMAGE = 'portrait.jpg' _CAT_IMAGE = 'cat.jpg' _PORTRAIT_EXPECTED_FACE_LANDMARKS = 'portrait_expected_face_landmarks.pbtxt' _PORTRAIT_EXPECTED_BLENDSHAPES = 'portrait_expected_blendshapes.pbtxt' -_LANDMARKS_DIFF_MARGIN = 0.03 -_BLENDSHAPES_DIFF_MARGIN = 0.13 -_FACIAL_TRANSFORMATION_MATRIX_DIFF_MARGIN = 0.02 +_LANDMARKS_MARGIN = 0.03 +_BLENDSHAPES_MARGIN = 0.13 +_FACIAL_TRANSFORMATION_MATRIX_MARGIN = 0.02 def _get_expected_face_landmarks(file_path: str): @@ -126,10 +126,10 @@ class FaceLandmarkerTest(parameterized.TestCase): for i, _ in enumerate(actual_landmarks): for j, elem in enumerate(actual_landmarks[i]): self.assertAlmostEqual( - elem.x, expected_landmarks[i][j].x, delta=_LANDMARKS_DIFF_MARGIN + elem.x, expected_landmarks[i][j].x, delta=_LANDMARKS_MARGIN ) self.assertAlmostEqual( - elem.y, expected_landmarks[i][j].y, delta=_LANDMARKS_DIFF_MARGIN + elem.y, expected_landmarks[i][j].y, delta=_LANDMARKS_MARGIN ) def _expect_blendshapes_correct( @@ -144,7 +144,7 @@ class FaceLandmarkerTest(parameterized.TestCase): self.assertAlmostEqual( elem.score, expected_blendshapes[i][j].score, - delta=_BLENDSHAPES_DIFF_MARGIN, + delta=_BLENDSHAPES_MARGIN, ) def _expect_facial_transformation_matrixes_correct( @@ -158,7 +158,7 @@ class FaceLandmarkerTest(parameterized.TestCase): self.assertSequenceAlmostEqual( elem.flatten(), expected_matrix_list[i].flatten(), - delta=_FACIAL_TRANSFORMATION_MATRIX_DIFF_MARGIN, + delta=_FACIAL_TRANSFORMATION_MATRIX_MARGIN, ) def test_create_from_file_succeeds_with_valid_model_path(self): diff --git a/mediapipe/tasks/python/test/vision/hand_landmarker_test.py b/mediapipe/tasks/python/test/vision/hand_landmarker_test.py index a7aea1cb2..6b8e4ec32 100644 --- a/mediapipe/tasks/python/test/vision/hand_landmarker_test.py +++ b/mediapipe/tasks/python/test/vision/hand_landmarker_test.py @@ -54,7 +54,7 @@ _POINTING_UP_IMAGE = 'pointing_up.jpg' _POINTING_UP_LANDMARKS = 'pointing_up_landmarks.pbtxt' _POINTING_UP_ROTATED_IMAGE = 'pointing_up_rotated.jpg' _POINTING_UP_ROTATED_LANDMARKS = 'pointing_up_rotated_landmarks.pbtxt' -_LANDMARKS_ERROR_TOLERANCE = 0.03 +_LANDMARKS_MARGIN = 0.03 _HANDEDNESS_MARGIN = 0.05 @@ -89,39 +89,52 @@ class HandLandmarkerTest(parameterized.TestCase): self.model_path = test_utils.get_test_data_path( _HAND_LANDMARKER_BUNDLE_ASSET_FILE) - def _assert_actual_result_approximately_matches_expected_result( - self, actual_result: _HandLandmarkerResult, - expected_result: _HandLandmarkerResult): + def _expect_hand_landmarks_correct( + self, actual_landmarks, expected_landmarks, margin + ): # Expects to have the same number of hands detected. - self.assertLen(actual_result.hand_landmarks, - len(expected_result.hand_landmarks)) - self.assertLen(actual_result.hand_world_landmarks, - len(expected_result.hand_world_landmarks)) - self.assertLen(actual_result.handedness, len(expected_result.handedness)) - # Actual landmarks match expected landmarks. - self.assertLen(actual_result.hand_landmarks[0], - len(expected_result.hand_landmarks[0])) - actual_landmarks = actual_result.hand_landmarks[0] - expected_landmarks = expected_result.hand_landmarks[0] - for i, rename_me in enumerate(actual_landmarks): - self.assertAlmostEqual( - rename_me.x, - expected_landmarks[i].x, - delta=_LANDMARKS_ERROR_TOLERANCE) - self.assertAlmostEqual( - rename_me.y, - expected_landmarks[i].y, - delta=_LANDMARKS_ERROR_TOLERANCE) - # Actual handedness matches expected handedness. - actual_top_handedness = actual_result.handedness[0][0] - expected_top_handedness = expected_result.handedness[0][0] + self.assertLen(actual_landmarks, len(expected_landmarks)) + + for i, _ in enumerate(actual_landmarks): + for j, elem in enumerate(actual_landmarks[i]): + self.assertAlmostEqual( + elem.x, + expected_landmarks[i][j].x, + delta=margin + ) + self.assertAlmostEqual( + elem.y, + expected_landmarks[i][j].y, + delta=margin + ) + + def _expect_handedness_correct( + self, actual_handedness, expected_handedness, margin + ): + # Actual top handedness matches expected top handedness. + actual_top_handedness = actual_handedness[0][0] + expected_top_handedness = expected_handedness[0][0] self.assertEqual(actual_top_handedness.index, expected_top_handedness.index) self.assertEqual(actual_top_handedness.category_name, expected_top_handedness.category_name) self.assertAlmostEqual( - actual_top_handedness.score, - expected_top_handedness.score, - delta=_HANDEDNESS_MARGIN) + actual_top_handedness.score, + expected_top_handedness.score, + delta=margin) + + def _expect_hand_landmarker_results_correct( + self, + actual_result: _HandLandmarkerResult, + expected_result: _HandLandmarkerResult + ): + self._expect_hand_landmarks_correct( + actual_result.hand_landmarks, expected_result.hand_landmarks, + _LANDMARKS_MARGIN + ) + self._expect_handedness_correct( + actual_result.handedness, expected_result.handedness, + _HANDEDNESS_MARGIN + ) def test_create_from_file_succeeds_with_valid_model_path(self): # Creates with default option and valid model file successfully. @@ -175,7 +188,7 @@ class HandLandmarkerTest(parameterized.TestCase): # Performs hand landmarks detection on the input. detection_result = landmarker.detect(self.test_image) # Comparing results. - self._assert_actual_result_approximately_matches_expected_result( + self._expect_hand_landmarker_results_correct( detection_result, expected_detection_result) # Closes the hand landmarker explicitly when the hand landmarker is not used # in a context. @@ -203,7 +216,7 @@ class HandLandmarkerTest(parameterized.TestCase): # Performs hand landmarks detection on the input. detection_result = landmarker.detect(self.test_image) # Comparing results. - self._assert_actual_result_approximately_matches_expected_result( + self._expect_hand_landmarker_results_correct( detection_result, expected_detection_result) def test_detect_succeeds_with_num_hands(self): @@ -234,7 +247,7 @@ class HandLandmarkerTest(parameterized.TestCase): expected_detection_result = _get_expected_hand_landmarker_result( _POINTING_UP_ROTATED_LANDMARKS) # Comparing results. - self._assert_actual_result_approximately_matches_expected_result( + self._expect_hand_landmarker_results_correct( detection_result, expected_detection_result) def test_detect_fails_with_region_of_interest(self): @@ -351,7 +364,7 @@ class HandLandmarkerTest(parameterized.TestCase): result = landmarker.detect_for_video(test_image, timestamp, image_processing_options) if result.hand_landmarks and result.hand_world_landmarks and result.handedness: - self._assert_actual_result_approximately_matches_expected_result( + self._expect_hand_landmarker_results_correct( result, expected_result) else: self.assertEqual(result, expected_result) @@ -406,7 +419,7 @@ class HandLandmarkerTest(parameterized.TestCase): def check_result(result: _HandLandmarkerResult, output_image: _Image, timestamp_ms: int): if result.hand_landmarks and result.hand_world_landmarks and result.handedness: - self._assert_actual_result_approximately_matches_expected_result( + self._expect_hand_landmarker_results_correct( result, expected_result) else: self.assertEqual(result, expected_result) diff --git a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py index 974389a0b..07d7f06a4 100644 --- a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py +++ b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py @@ -50,8 +50,7 @@ _POSE_LANDMARKER_BUNDLE_ASSET_FILE = 'pose_landmarker.task' _BURGER_IMAGE = 'burger.jpg' _POSE_IMAGE = 'pose.jpg' _POSE_LANDMARKS = 'pose_landmarks.pbtxt' -_LANDMARKS_DIFF_MARGIN = 0.03 -_LANDMARKS_ON_VIDEO_DIFF_MARGIN = 0.03 +_LANDMARKS_MARGIN = 0.03 def _get_expected_pose_landmarker_result( @@ -87,10 +86,7 @@ class PoseLandmarkerTest(parameterized.TestCase): _POSE_LANDMARKER_BUNDLE_ASSET_FILE) def _expect_pose_landmarks_correct( - self, - actual_landmarks: List[List[landmark_module.NormalizedLandmark]], - expected_landmarks: List[List[landmark_module.NormalizedLandmark]], - diff_margin: float + self, actual_landmarks, expected_landmarks, margin ): # Expects to have the same number of poses detected. self.assertLen(actual_landmarks, len(expected_landmarks)) @@ -98,21 +94,21 @@ class PoseLandmarkerTest(parameterized.TestCase): for i, _ in enumerate(actual_landmarks): for j, elem in enumerate(actual_landmarks[i]): self.assertAlmostEqual( - elem.x, expected_landmarks[i][j].x, delta=diff_margin + elem.x, expected_landmarks[i][j].x, delta=margin ) self.assertAlmostEqual( - elem.y, expected_landmarks[i][j].y, delta=diff_margin + elem.y, expected_landmarks[i][j].y, delta=margin ) def _expect_pose_landmarker_results_correct( self, actual_result: PoseLandmarkerResult, expected_result: PoseLandmarkerResult, - diff_margin: float + margin: float ): self._expect_pose_landmarks_correct( actual_result.pose_landmarks, expected_result.pose_landmarks, - diff_margin + margin ) def test_create_from_file_succeeds_with_valid_model_path(self): @@ -170,7 +166,7 @@ class PoseLandmarkerTest(parameterized.TestCase): # Comparing results. self._expect_pose_landmarker_results_correct( - detection_result, expected_detection_result, _LANDMARKS_DIFF_MARGIN + detection_result, expected_detection_result, _LANDMARKS_MARGIN ) # Closes the pose landmarker explicitly when the pose landmarker is not used # in a context. @@ -201,7 +197,7 @@ class PoseLandmarkerTest(parameterized.TestCase): # Comparing results. self._expect_pose_landmarker_results_correct( - detection_result, expected_detection_result, _LANDMARKS_DIFF_MARGIN + detection_result, expected_detection_result, _LANDMARKS_MARGIN ) def test_detect_fails_with_region_of_interest(self): @@ -319,7 +315,7 @@ class PoseLandmarkerTest(parameterized.TestCase): image_processing_options) if result.pose_landmarks: self._expect_pose_landmarker_results_correct( - result, expected_result, _LANDMARKS_ON_VIDEO_DIFF_MARGIN + result, expected_result, _LANDMARKS_MARGIN ) else: self.assertEqual(result, expected_result) @@ -373,7 +369,7 @@ class PoseLandmarkerTest(parameterized.TestCase): timestamp_ms: int): if result.pose_landmarks: self._expect_pose_landmarker_results_correct( - result, expected_result, _LANDMARKS_DIFF_MARGIN + result, expected_result, _LANDMARKS_MARGIN ) else: self.assertEqual(result, expected_result) diff --git a/mediapipe/tasks/python/vision/face_detector.py b/mediapipe/tasks/python/vision/face_detector.py index cf09a378d..5a9487eec 100644 --- a/mediapipe/tasks/python/vision/face_detector.py +++ b/mediapipe/tasks/python/vision/face_detector.py @@ -71,8 +71,8 @@ class FaceDetectorOptions: base_options: _BaseOptions running_mode: _RunningMode = _RunningMode.IMAGE - min_detection_confidence: Optional[float] = None - min_suppression_threshold: Optional[float] = None + min_detection_confidence: float = 0.5 + min_suppression_threshold: float = 0.3 result_callback: Optional[ Callable[ [detections_module.DetectionResult, image_module.Image, int], None diff --git a/mediapipe/tasks/python/vision/face_landmarker.py b/mediapipe/tasks/python/vision/face_landmarker.py index c5b24499f..3776637fa 100644 --- a/mediapipe/tasks/python/vision/face_landmarker.py +++ b/mediapipe/tasks/python/vision/face_landmarker.py @@ -2966,12 +2966,12 @@ class FaceLandmarkerOptions: base_options: _BaseOptions running_mode: _RunningMode = _RunningMode.IMAGE - num_faces: Optional[int] = 1 - min_face_detection_confidence: Optional[float] = 0.5 - min_face_presence_confidence: Optional[float] = 0.5 - min_tracking_confidence: Optional[float] = 0.5 - output_face_blendshapes: Optional[bool] = False - output_facial_transformation_matrixes: Optional[bool] = False + num_faces: int = 1 + min_face_detection_confidence: float = 0.5 + min_face_presence_confidence: float = 0.5 + min_tracking_confidence: float = 0.5 + output_face_blendshapes: bool = False + output_facial_transformation_matrixes: bool = False result_callback: Optional[ Callable[[FaceLandmarkerResult, image_module.Image, int], None] ] = None diff --git a/mediapipe/tasks/python/vision/gesture_recognizer.py b/mediapipe/tasks/python/vision/gesture_recognizer.py index 7d480c95f..9ae5285df 100644 --- a/mediapipe/tasks/python/vision/gesture_recognizer.py +++ b/mediapipe/tasks/python/vision/gesture_recognizer.py @@ -194,14 +194,14 @@ class GestureRecognizerOptions: base_options: _BaseOptions running_mode: _RunningMode = _RunningMode.IMAGE - num_hands: Optional[int] = 1 - min_hand_detection_confidence: Optional[float] = 0.5 - min_hand_presence_confidence: Optional[float] = 0.5 - min_tracking_confidence: Optional[float] = 0.5 - canned_gesture_classifier_options: Optional[_ClassifierOptions] = ( + num_hands: int = 1 + min_hand_detection_confidence: float = 0.5 + min_hand_presence_confidence: float = 0.5 + min_tracking_confidence: float = 0.5 + canned_gesture_classifier_options: _ClassifierOptions = ( dataclasses.field(default_factory=_ClassifierOptions) ) - custom_gesture_classifier_options: Optional[_ClassifierOptions] = ( + custom_gesture_classifier_options: _ClassifierOptions = ( dataclasses.field(default_factory=_ClassifierOptions) ) result_callback: Optional[ diff --git a/mediapipe/tasks/python/vision/hand_landmarker.py b/mediapipe/tasks/python/vision/hand_landmarker.py index e6fcca2e2..616f0b724 100644 --- a/mediapipe/tasks/python/vision/hand_landmarker.py +++ b/mediapipe/tasks/python/vision/hand_landmarker.py @@ -182,10 +182,10 @@ class HandLandmarkerOptions: base_options: _BaseOptions running_mode: _RunningMode = _RunningMode.IMAGE - num_hands: Optional[int] = 1 - min_hand_detection_confidence: Optional[float] = 0.5 - min_hand_presence_confidence: Optional[float] = 0.5 - min_tracking_confidence: Optional[float] = 0.5 + num_hands: int = 1 + min_hand_detection_confidence: float = 0.5 + min_hand_presence_confidence: float = 0.5 + min_tracking_confidence: float = 0.5 result_callback: Optional[ Callable[[HandLandmarkerResult, image_module.Image, int], None] ] = None From 8c8ba9511a471f623a5f8d4a68b181fcfba826e1 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 18 Apr 2023 23:29:39 -0700 Subject: [PATCH 036/753] Internal change PiperOrigin-RevId: 525358261 --- .../frame_annotation_to_timed_box_list_calculator.cc | 4 ++-- .../calculators/tflite_tensors_to_objects_calculator.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mediapipe/modules/objectron/calculators/frame_annotation_to_timed_box_list_calculator.cc b/mediapipe/modules/objectron/calculators/frame_annotation_to_timed_box_list_calculator.cc index 74678804f..c2bc413c5 100644 --- a/mediapipe/modules/objectron/calculators/frame_annotation_to_timed_box_list_calculator.cc +++ b/mediapipe/modules/objectron/calculators/frame_annotation_to_timed_box_list_calculator.cc @@ -91,8 +91,8 @@ absl::Status FrameAnnotationToTimedBoxListCalculator::Process( TimedBoxProto* added_box = output_objects->add_box(); ComputeBoundingRect(key_points, added_box); added_box->set_id(annotation.object_id()); - const int64 time_msec = - static_cast(std::round(frame_annotation.timestamp() / 1000)); + const int64_t time_msec = + static_cast(std::round(frame_annotation.timestamp() / 1000)); added_box->set_time_msec(time_msec); } diff --git a/mediapipe/modules/objectron/calculators/tflite_tensors_to_objects_calculator.cc b/mediapipe/modules/objectron/calculators/tflite_tensors_to_objects_calculator.cc index e3686f65e..d74b59a25 100644 --- a/mediapipe/modules/objectron/calculators/tflite_tensors_to_objects_calculator.cc +++ b/mediapipe/modules/objectron/calculators/tflite_tensors_to_objects_calculator.cc @@ -76,7 +76,7 @@ class TfLiteTensorsToObjectsCalculator : public CalculatorBase { // In a single MediaPipe session, the IDs are unique. // Also assign timestamp for the FrameAnnotation to be the input packet // timestamp. - void AssignObjectIdAndTimestamp(int64 timestamp_us, + void AssignObjectIdAndTimestamp(int64_t timestamp_us, FrameAnnotation* annotation); int num_classes_ = 0; @@ -207,7 +207,7 @@ void TfLiteTensorsToObjectsCalculator::Project3DTo2D( } void TfLiteTensorsToObjectsCalculator::AssignObjectIdAndTimestamp( - int64 timestamp_us, FrameAnnotation* annotation) { + int64_t timestamp_us, FrameAnnotation* annotation) { for (auto& ann : *annotation->mutable_annotations()) { ann.set_object_id(GetNextObjectId()); } From b83fa5b67dfba2d049baba50ee34b3935aea4c2a Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 19 Apr 2023 00:15:27 -0700 Subject: [PATCH 037/753] Internal change PiperOrigin-RevId: 525365673 --- .../fixed_size_input_stream_handler_test.cc | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/mediapipe/framework/stream_handler/fixed_size_input_stream_handler_test.cc b/mediapipe/framework/stream_handler/fixed_size_input_stream_handler_test.cc index 4f1367a9a..186d59dfe 100644 --- a/mediapipe/framework/stream_handler/fixed_size_input_stream_handler_test.cc +++ b/mediapipe/framework/stream_handler/fixed_size_input_stream_handler_test.cc @@ -30,15 +30,15 @@ namespace mediapipe { namespace { -const int64 kMaxPacketId = 100; -const int64 kSlowCalculatorRate = 10; +const int64_t kMaxPacketId = 100; +const int64_t kSlowCalculatorRate = 10; // Rate limiter for TestSlowCalculator. ABSL_CONST_INIT absl::Mutex g_source_mutex(absl::kConstInit); -int64 g_source_counter ABSL_GUARDED_BY(g_source_mutex); +int64_t g_source_counter ABSL_GUARDED_BY(g_source_mutex); // Rate limiter for TestSourceCalculator. -int64 g_slow_counter ABSL_GUARDED_BY(g_source_mutex); +int64_t g_slow_counter ABSL_GUARDED_BY(g_source_mutex); // Flag that indicates that the source is done. bool g_source_done ABSL_GUARDED_BY(g_source_mutex); @@ -47,7 +47,7 @@ class TestSourceCalculator : public CalculatorBase { public: TestSourceCalculator() : current_packet_id_(0) {} static absl::Status GetContract(CalculatorContract* cc) { - cc->Outputs().Index(0).Set(); + cc->Outputs().Index(0).Set(); return absl::OkStatus(); } absl::Status Open(CalculatorContext* cc) override { @@ -62,7 +62,7 @@ class TestSourceCalculator : public CalculatorBase { g_source_done = true; return tool::StatusStop(); } - cc->Outputs().Index(0).Add(new int64(0), Timestamp(current_packet_id_)); + cc->Outputs().Index(0).Add(new int64_t(0), Timestamp(current_packet_id_)); ++current_packet_id_; { absl::MutexLock lock(&g_source_mutex); @@ -78,7 +78,7 @@ class TestSourceCalculator : public CalculatorBase { return g_source_counter <= kSlowCalculatorRate * g_slow_counter || g_source_counter <= 1; } - int64 current_packet_id_; + int64_t current_packet_id_; }; REGISTER_CALCULATOR(TestSourceCalculator); @@ -87,8 +87,8 @@ class TestSlowCalculator : public CalculatorBase { public: TestSlowCalculator() = default; static absl::Status GetContract(CalculatorContract* cc) { - cc->Inputs().Index(0).Set(); - cc->Outputs().Index(0).Set(); + cc->Inputs().Index(0).Set(); + cc->Outputs().Index(0).Set(); return absl::OkStatus(); } absl::Status Open(CalculatorContext* cc) override { @@ -97,7 +97,7 @@ class TestSlowCalculator : public CalculatorBase { return absl::OkStatus(); } absl::Status Process(CalculatorContext* cc) override { - cc->Outputs().Index(0).Add(new int64(0), + cc->Outputs().Index(0).Add(new int64_t(0), cc->Inputs().Index(0).Value().Timestamp()); { absl::MutexLock lock(&g_source_mutex); @@ -118,8 +118,9 @@ class TestSlowCalculator : public CalculatorBase { REGISTER_CALCULATOR(TestSlowCalculator); // Return the values of the timestamps of a vector of Packets. -static std::vector TimestampValues(const std::vector& packets) { - std::vector result; +static std::vector TimestampValues( + const std::vector& packets) { + std::vector result; for (const Packet& p : packets) { result.push_back(p.Timestamp().Value()); } @@ -174,7 +175,7 @@ TEST_P(FixedSizeInputStreamHandlerTest, DropsPackets) { // consumed. In this way, the TestSlowCalculator consumes and outputs only // every tenth packet. EXPECT_EQ(output_packets.size(), 11); - std::vector expected_ts = {0, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99}; + std::vector expected_ts = {0, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99}; EXPECT_THAT(TimestampValues(output_packets), testing::ContainerEq(expected_ts)); } @@ -344,18 +345,18 @@ TEST_P(FixedSizeInputStreamHandlerTest, LateArrivalDrop) { if (GetParam()) { EXPECT_THAT(TimestampValues(output_packets[0]), - testing::ContainerEq(std::vector{1, 2, 3, 4, 5, 6})); + testing::ContainerEq(std::vector{1, 2, 3, 4, 5, 6})); EXPECT_THAT(TimestampValues(output_packets[1]), - testing::ContainerEq(std::vector{3, 4, 5, 6, 7})); + testing::ContainerEq(std::vector{3, 4, 5, 6, 7})); EXPECT_THAT(TimestampValues(output_packets[2]), - testing::ContainerEq(std::vector{4, 5, 6, 7})); + testing::ContainerEq(std::vector{4, 5, 6, 7})); } else { EXPECT_THAT(TimestampValues(output_packets[0]), - testing::ContainerEq(std::vector{5, 6})); + testing::ContainerEq(std::vector{5, 6})); EXPECT_THAT(TimestampValues(output_packets[1]), - testing::ContainerEq(std::vector{5, 6, 7})); + testing::ContainerEq(std::vector{5, 6, 7})); EXPECT_THAT(TimestampValues(output_packets[2]), - testing::ContainerEq(std::vector{5, 6, 7})); + testing::ContainerEq(std::vector{5, 6, 7})); } } From de84696be65856085e48562354d4929e7adcea83 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 19 Apr 2023 02:37:50 -0700 Subject: [PATCH 038/753] Internal change PiperOrigin-RevId: 525390694 --- .../classification_postprocessing_graph_test.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph_test.cc b/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph_test.cc index 6dff64b1b..a61ffa6b1 100644 --- a/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph_test.cc +++ b/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph_test.cc @@ -520,7 +520,7 @@ TEST_F(PostprocessingTest, SucceedsWithoutMetadata) { auto poller, BuildGraph(kQuantizedImageClassifierWithoutMetadata, options)); // Build input tensors. - std::vector tensor(kMobileNetNumClasses, 0); + std::vector tensor(kMobileNetNumClasses, 0); tensor[1] = 18; tensor[2] = 16; @@ -552,7 +552,7 @@ TEST_F(PostprocessingTest, SucceedsWithMetadata) { MP_ASSERT_OK_AND_ASSIGN( auto poller, BuildGraph(kQuantizedImageClassifierWithMetadata, options)); // Build input tensors. - std::vector tensor(kMobileNetNumClasses, 0); + std::vector tensor(kMobileNetNumClasses, 0); tensor[1] = 12; tensor[2] = 14; tensor[3] = 16; @@ -589,7 +589,7 @@ TEST_F(PostprocessingTest, SucceedsWithScoreCalibration) { auto poller, BuildGraph(kQuantizedImageClassifierWithDummyScoreCalibration, options)); // Build input tensors. - std::vector tensor(kMobileNetNumClasses, 0); + std::vector tensor(kMobileNetNumClasses, 0); tensor[1] = 12; tensor[2] = 14; tensor[3] = 16; @@ -677,11 +677,11 @@ TEST_F(PostprocessingTest, SucceedsWithTimestamps) { auto poller, BuildGraph(kQuantizedImageClassifierWithMetadata, options, /*connect_timestamps=*/true)); // Build input tensors. - std::vector tensor_0(kMobileNetNumClasses, 0); + std::vector tensor_0(kMobileNetNumClasses, 0); tensor_0[1] = 12; tensor_0[2] = 14; tensor_0[3] = 16; - std::vector tensor_1(kMobileNetNumClasses, 0); + std::vector tensor_1(kMobileNetNumClasses, 0); tensor_1[5] = 12; tensor_1[6] = 14; tensor_1[7] = 16; From 01f4439d83008b4333f6375422689eb4b679e2f5 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 19 Apr 2023 03:30:43 -0700 Subject: [PATCH 039/753] Internal change PiperOrigin-RevId: 525399975 --- .../core/matrix_to_vector_calculator_test.cc | 2 +- .../core/packet_resampler_calculator_test.cc | 20 +++++++++---------- .../core/previous_loopback_calculator_test.cc | 6 +++--- .../core/side_packet_to_stream_calculator.cc | 6 +++--- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/mediapipe/calculators/core/matrix_to_vector_calculator_test.cc b/mediapipe/calculators/core/matrix_to_vector_calculator_test.cc index 1f994cbed..8b4254cbc 100644 --- a/mediapipe/calculators/core/matrix_to_vector_calculator_test.cc +++ b/mediapipe/calculators/core/matrix_to_vector_calculator_test.cc @@ -35,7 +35,7 @@ class MatrixToVectorCalculatorTest void SetUp() override { calculator_name_ = "MatrixToVectorCalculator"; } void AppendInput(const std::vector& column_major_data, - int64 timestamp) { + int64_t timestamp) { ASSERT_EQ(num_input_samples_ * num_input_channels_, column_major_data.size()); Eigen::Map data_map(&column_major_data[0], diff --git a/mediapipe/calculators/core/packet_resampler_calculator_test.cc b/mediapipe/calculators/core/packet_resampler_calculator_test.cc index f02da0d18..d80793da4 100644 --- a/mediapipe/calculators/core/packet_resampler_calculator_test.cc +++ b/mediapipe/calculators/core/packet_resampler_calculator_test.cc @@ -51,9 +51,9 @@ class SimpleRunner : public CalculatorRunner { virtual ~SimpleRunner() {} - void SetInput(const std::vector& timestamp_list) { + void SetInput(const std::vector& 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& expected_frames, - const std::vector& expected_timestamps) const { + const std::vector& expected_frames, + const std::vector& 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_t actual_payload = arg.template Get(); 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 random_sequence; + static std::vector 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 +std::vector 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))); } diff --git a/mediapipe/calculators/core/previous_loopback_calculator_test.cc b/mediapipe/calculators/core/previous_loopback_calculator_test.cc index 563417669..d8c358909 100644 --- a/mediapipe/calculators/core/previous_loopback_calculator_test.cc +++ b/mediapipe/calculators/core/previous_loopback_calculator_test.cc @@ -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 TimestampValues(const std::vector& packets) { - std::vector result; +std::vector TimestampValues(const std::vector& packets) { + std::vector 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 ts_values = TimestampValues(outputs); + std::vector 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); diff --git a/mediapipe/calculators/core/side_packet_to_stream_calculator.cc b/mediapipe/calculators/core/side_packet_to_stream_calculator.cc index ed89889df..311f7d815 100644 --- a/mediapipe/calculators/core/side_packet_to_stream_calculator.cc +++ b/mediapipe/calculators/core/side_packet_to_stream_calculator.cc @@ -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(); + cc->InputSidePackets().Tag(kTagSideInputTimestamp).Set(); } 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_t timestamp = + cc->InputSidePackets().Tag(kTagSideInputTimestamp).Get(); for (int i = 0; i < cc->Outputs().NumEntries(output_tag_); ++i) { cc->Outputs() .Get(output_tag_, i) From 0aea6d90a8f42c9170bfef43f0a7b7f2d02963d2 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 19 Apr 2023 04:07:48 -0700 Subject: [PATCH 040/753] Internal change PiperOrigin-RevId: 525407296 --- .../processors/classification_postprocessing_graph.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.cc b/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.cc index cfb3b02cf..9f796920c 100644 --- a/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.cc +++ b/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.cc @@ -66,7 +66,7 @@ using ::mediapipe::tasks::core::ModelResources; using ::mediapipe::tasks::metadata::ModelMetadataExtractor; using ::tflite::ProcessUnit; using ::tflite::TensorMetadata; -using LabelItems = mediapipe::proto_ns::Map; +using LabelItems = mediapipe::proto_ns::Map; using TensorsSource = mediapipe::api2::builder::Source>; constexpr float kDefaultScoreThreshold = std::numeric_limits::lowest(); From 9818ebb630012f0c01fcc6c6db495179cc4930b4 Mon Sep 17 00:00:00 2001 From: Bekzhan Bekbolatuly Date: Wed, 19 Apr 2023 09:56:23 -0700 Subject: [PATCH 041/753] Internal change PiperOrigin-RevId: 525476655 --- .../tasks/cc/text/language_detector/language_detector_test.cc | 4 ++-- .../tasks/cc/vision/pose_landmarker/pose_landmarker_test.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/cc/text/language_detector/language_detector_test.cc b/mediapipe/tasks/cc/text/language_detector/language_detector_test.cc index 92dc493e0..2e9a58409 100644 --- a/mediapipe/tasks/cc/text/language_detector/language_detector_test.cc +++ b/mediapipe/tasks/cc/text/language_detector/language_detector_test.cc @@ -32,7 +32,7 @@ limitations under the License. #include "mediapipe/framework/port/gtest.h" #include "mediapipe/framework/port/status_matchers.h" #include "mediapipe/tasks/cc/common.h" -#include "tensorflow/lite/core/shims/cc/shims_test_util.h" +#include "tensorflow/lite/test_util.h" namespace mediapipe::tasks::text::language_detector { namespace { @@ -75,7 +75,7 @@ absl::Status MatchesLanguageDetectorResult( } // namespace -class LanguageDetectorTest : public tflite_shims::testing::Test {}; +class LanguageDetectorTest : public tflite::testing::Test {}; TEST_F(LanguageDetectorTest, CreateFailsWithMissingModel) { auto options = std::make_unique(); diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_test.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_test.cc index 062d0746d..87bc97274 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_test.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_test.cc @@ -38,7 +38,7 @@ limitations under the License. #include "mediapipe/tasks/cc/vision/core/image_processing_options.h" #include "mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.h" #include "mediapipe/tasks/cc/vision/utils/image_utils.h" -#include "tensorflow/lite/core/shims/cc/shims_test_util.h" +#include "tensorflow/lite/test_util.h" #include "util/tuple/dump_vars.h" namespace mediapipe { From eb6247919057785d3eb33a9f9a9664859ea967d9 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 19 Apr 2023 10:32:54 -0700 Subject: [PATCH 042/753] Internal change PiperOrigin-RevId: 525487344 --- mediapipe/tasks/cc/core/BUILD | 3 ++ mediapipe/tasks/cc/core/task_api_factory.h | 43 ++++++++++++++++++---- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/mediapipe/tasks/cc/core/BUILD b/mediapipe/tasks/cc/core/BUILD index 5aa9c9729..95cfdd15e 100644 --- a/mediapipe/tasks/cc/core/BUILD +++ b/mediapipe/tasks/cc/core/BUILD @@ -318,6 +318,9 @@ cc_library( ":model_resources", ":task_runner", ":utils", + "//mediapipe/framework:calculator_cc_proto", + "//mediapipe/framework/port:requires", + "//mediapipe/framework/port:status", "//mediapipe/tasks/cc:common", "//mediapipe/tasks/cc/core/proto:base_options_cc_proto", "//mediapipe/tasks/cc/core/proto:external_file_cc_proto", diff --git a/mediapipe/tasks/cc/core/task_api_factory.h b/mediapipe/tasks/cc/core/task_api_factory.h index 631696b4c..83c2f3207 100644 --- a/mediapipe/tasks/cc/core/task_api_factory.h +++ b/mediapipe/tasks/cc/core/task_api_factory.h @@ -23,7 +23,11 @@ limitations under the License. #include "absl/status/status.h" #include "absl/status/statusor.h" +#include "absl/strings/match.h" #include "absl/strings/str_cat.h" +#include "mediapipe/framework/calculator.pb.h" +#include "mediapipe/framework/port/requires.h" +#include "mediapipe/framework/port/status_macros.h" #include "mediapipe/tasks/cc/common.h" #include "mediapipe/tasks/cc/core/base_task_api.h" #include "mediapipe/tasks/cc/core/model_resources.h" @@ -54,6 +58,8 @@ class TaskApiFactory { std::unique_ptr resolver, PacketsCallback packets_callback = nullptr) { bool found_task_subgraph = false; + // This for-loop ensures there's only one subgraph besides + // FlowLimiterCalculator. for (const auto& node : graph_config.node()) { if (node.calculator() == "FlowLimiterCalculator") { continue; @@ -64,13 +70,7 @@ class TaskApiFactory { "Task graph config should only contain one task subgraph node.", MediaPipeTasksStatus::kInvalidTaskGraphConfigError); } else { - if (!node.options().HasExtension(Options::ext)) { - return CreateStatusWithPayload( - absl::StatusCode::kInvalidArgument, - absl::StrCat(node.calculator(), - " is missing the required task options field."), - MediaPipeTasksStatus::kInvalidTaskGraphConfigError); - } + MP_RETURN_IF_ERROR(CheckHasValidOptions(node)); found_task_subgraph = true; } } @@ -80,6 +80,35 @@ class TaskApiFactory { std::move(packets_callback))); return std::make_unique(std::move(runner)); } + + private: + template + static absl::Status CheckHasValidOptions( + const CalculatorGraphConfig::Node& node) { + if constexpr (mediapipe::Requires( + [](auto&& o) -> decltype(o.ext) {})) { + if (node.options().HasExtension(Options::ext)) { + return absl::OkStatus(); + } + } else { +#ifndef MEDIAPIPE_PROTO_LITE + for (const auto& option : node.node_options()) { + if (absl::StrContains(option.type_url(), + Options::descriptor()->full_name())) { + return absl::OkStatus(); + } + } +#else // MEDIAPIPE_PROTO_LITE + // Skip the check for proto lite, as Options::descriptor() is unavailable. + return absl::OkStatus(); +#endif // MEDIAPIPE_PROTO_LITE + } + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::StrCat(node.calculator(), + " is missing the required task options field."), + MediaPipeTasksStatus::kInvalidTaskGraphConfigError); + } }; } // namespace core From b2586e7e3bc87849704e1d993fefc4eb7ef05591 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 19 Apr 2023 10:59:00 -0700 Subject: [PATCH 043/753] Internal change PiperOrigin-RevId: 525495248 --- .../autoflip/calculators/border_detection_calculator.cc | 3 --- .../autoflip/calculators/border_detection_calculator_test.cc | 4 ---- .../autoflip/calculators/shot_boundary_calculator_test.cc | 3 --- .../desktop/autoflip/calculators/signal_fusing_calculator.cc | 2 -- mediapipe/framework/api2/node_test.cc | 2 -- mediapipe/framework/tool/options_field_util.cc | 4 ---- 6 files changed, 18 deletions(-) diff --git a/mediapipe/examples/desktop/autoflip/calculators/border_detection_calculator.cc b/mediapipe/examples/desktop/autoflip/calculators/border_detection_calculator.cc index 238bcf8be..c3c920bcf 100644 --- a/mediapipe/examples/desktop/autoflip/calculators/border_detection_calculator.cc +++ b/mediapipe/examples/desktop/autoflip/calculators/border_detection_calculator.cc @@ -28,11 +28,8 @@ #include "mediapipe/framework/port/ret_check.h" #include "mediapipe/framework/port/status.h" -using mediapipe::Adopt; -using mediapipe::CalculatorBase; using mediapipe::ImageFrame; using mediapipe::PacketTypeSet; -using mediapipe::autoflip::Border; constexpr char kDetectedBorders[] = "DETECTED_BORDERS"; constexpr int kMinBorderDistance = 5; diff --git a/mediapipe/examples/desktop/autoflip/calculators/border_detection_calculator_test.cc b/mediapipe/examples/desktop/autoflip/calculators/border_detection_calculator_test.cc index e72d54e55..431e3d161 100644 --- a/mediapipe/examples/desktop/autoflip/calculators/border_detection_calculator_test.cc +++ b/mediapipe/examples/desktop/autoflip/calculators/border_detection_calculator_test.cc @@ -28,16 +28,12 @@ #include "mediapipe/framework/port/status.h" #include "mediapipe/framework/port/status_matchers.h" -using mediapipe::Adopt; using mediapipe::CalculatorGraphConfig; using mediapipe::CalculatorRunner; using mediapipe::ImageFormat; using mediapipe::ImageFrame; using mediapipe::Packet; using mediapipe::PacketTypeSet; -using mediapipe::ParseTextProtoOrDie; -using mediapipe::Timestamp; -using mediapipe::autoflip::Border; namespace mediapipe { namespace autoflip { diff --git a/mediapipe/examples/desktop/autoflip/calculators/shot_boundary_calculator_test.cc b/mediapipe/examples/desktop/autoflip/calculators/shot_boundary_calculator_test.cc index 9ea79ba44..a45a171a4 100644 --- a/mediapipe/examples/desktop/autoflip/calculators/shot_boundary_calculator_test.cc +++ b/mediapipe/examples/desktop/autoflip/calculators/shot_boundary_calculator_test.cc @@ -31,14 +31,11 @@ #include "mediapipe/framework/port/status.h" #include "mediapipe/framework/port/status_matchers.h" -using mediapipe::Adopt; using mediapipe::CalculatorGraphConfig; using mediapipe::CalculatorRunner; using mediapipe::ImageFormat; using mediapipe::ImageFrame; using mediapipe::PacketTypeSet; -using mediapipe::ParseTextProtoOrDie; -using mediapipe::Timestamp; namespace mediapipe { namespace autoflip { diff --git a/mediapipe/examples/desktop/autoflip/calculators/signal_fusing_calculator.cc b/mediapipe/examples/desktop/autoflip/calculators/signal_fusing_calculator.cc index 85b2d96f8..ba5064a28 100644 --- a/mediapipe/examples/desktop/autoflip/calculators/signal_fusing_calculator.cc +++ b/mediapipe/examples/desktop/autoflip/calculators/signal_fusing_calculator.cc @@ -28,8 +28,6 @@ using mediapipe::Packet; using mediapipe::PacketTypeSet; using mediapipe::autoflip::DetectionSet; -using mediapipe::autoflip::SalientRegion; -using mediapipe::autoflip::SignalType; constexpr char kIsShotBoundaryTag[] = "IS_SHOT_BOUNDARY"; constexpr char kSignalInputsTag[] = "SIGNAL"; diff --git a/mediapipe/framework/api2/node_test.cc b/mediapipe/framework/api2/node_test.cc index a6c1ef7c6..152cbb0e2 100644 --- a/mediapipe/framework/api2/node_test.cc +++ b/mediapipe/framework/api2/node_test.cc @@ -19,8 +19,6 @@ namespace mediapipe { namespace api2 { namespace test { -using testing::ElementsAre; - // Returns the packet values for a vector of Packets. template std::vector PacketValues(const std::vector& packets) { diff --git a/mediapipe/framework/tool/options_field_util.cc b/mediapipe/framework/tool/options_field_util.cc index 308932d4f..248028c25 100644 --- a/mediapipe/framework/tool/options_field_util.cc +++ b/mediapipe/framework/tool/options_field_util.cc @@ -27,10 +27,6 @@ namespace options_field_util { using ::mediapipe::proto_ns::internal::WireFormatLite; using FieldType = WireFormatLite::FieldType; -using ::mediapipe::proto_ns::io::ArrayInputStream; -using ::mediapipe::proto_ns::io::CodedInputStream; -using ::mediapipe::proto_ns::io::CodedOutputStream; -using ::mediapipe::proto_ns::io::StringOutputStream; // Utility functions for OptionsFieldUtil. namespace { From 3231591f7ff2f7d5a8132c856af246d2aa707e4a Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 19 Apr 2023 11:45:24 -0700 Subject: [PATCH 044/753] draw right eye with blue color PiperOrigin-RevId: 525508840 --- mediapipe/util/pose_util.cc | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/mediapipe/util/pose_util.cc b/mediapipe/util/pose_util.cc index a9d2e6158..3a9c1e97b 100644 --- a/mediapipe/util/pose_util.cc +++ b/mediapipe/util/pose_util.cc @@ -107,6 +107,10 @@ const int kFaceMeshFaceOval[36][2] = { {152, 148}, {148, 176}, {176, 149}, {149, 150}, {150, 136}, {136, 172}, {172, 58}, {58, 132}, {132, 93}, {93, 234}, {234, 127}, {127, 162}, {162, 21}, {21, 54}, {54, 103}, {103, 67}, {67, 109}, {109, 10}}; + +const cv::Scalar kRightEyeColor = cv::Scalar(255.0, 48.0, 48.0); +const cv::Scalar kLeftEyeColor = cv::Scalar(48.0, 255.0, 48.0); +const cv::Scalar kFaceContourColor = cv::Scalar(224.0, 224.0, 224.0); } // namespace namespace mediapipe { @@ -180,49 +184,48 @@ void DrawFace(const mediapipe::NormalizedLandmarkList& face, bool flip_y, constexpr int draw_line_width = 2; for (int j = 0; j < 36; ++j) { cv::line(*image, landmarks[kFaceMeshFaceOval[j][0]], - landmarks[kFaceMeshFaceOval[j][1]], cv::Scalar(224, 224, 224), + landmarks[kFaceMeshFaceOval[j][1]], kFaceContourColor, draw_line_width); } for (int j = 0; j < 40; ++j) { cv::line(*image, landmarks[kFaceMeshLips[j][0]], - landmarks[kFaceMeshLips[j][1]], cv::Scalar(224, 224, 224), + landmarks[kFaceMeshLips[j][1]], kFaceContourColor, draw_line_width); } for (int j = 0; j < 16; ++j) { cv::line(*image, landmarks[kFaceMeshLeftEye[j][0]], - landmarks[kFaceMeshLeftEye[j][1]], cv::Scalar(48, 255, 48), - draw_line_width); + landmarks[kFaceMeshLeftEye[j][1]], kLeftEyeColor, draw_line_width); } for (int j = 0; j < 8; ++j) { cv::line(*image, landmarks[kFaceMeshLeftEyebrow[j][0]], - landmarks[kFaceMeshLeftEyebrow[j][1]], cv::Scalar(48, 255, 48), + landmarks[kFaceMeshLeftEyebrow[j][1]], kLeftEyeColor, draw_line_width); } for (int j = 0; j < 4; ++j) { cv::line(*image, landmarks[kFaceMeshLeftIris[j][0]], - landmarks[kFaceMeshLeftIris[j][1]], cv::Scalar(48, 255, 48), + landmarks[kFaceMeshLeftIris[j][1]], kLeftEyeColor, draw_line_width); } for (int j = 0; j < 16; ++j) { cv::line(*image, landmarks[kFaceMeshRightEye[j][0]], - landmarks[kFaceMeshRightEye[j][1]], cv::Scalar(48, 48, 255), + landmarks[kFaceMeshRightEye[j][1]], kRightEyeColor, draw_line_width); } for (int j = 0; j < 8; ++j) { cv::line(*image, landmarks[kFaceMeshRightEyebrow[j][0]], - landmarks[kFaceMeshRightEyebrow[j][1]], cv::Scalar(48, 48, 255), + landmarks[kFaceMeshRightEyebrow[j][1]], kRightEyeColor, draw_line_width); } for (int j = 0; j < 4; ++j) { cv::line(*image, landmarks[kFaceMeshRightIris[j][0]], - landmarks[kFaceMeshRightIris[j][1]], cv::Scalar(48, 48, 255), + landmarks[kFaceMeshRightIris[j][1]], kRightEyeColor, draw_line_width); } } From 5bd3282515214529639ee0b0f869320372328439 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 19 Apr 2023 12:03:30 -0700 Subject: [PATCH 045/753] Internal change PiperOrigin-RevId: 525513792 --- .../cc/vision/hand_landmarker/hand_landmarks_detector_graph.cc | 1 - .../cc/vision/interactive_segmenter/interactive_segmenter.cc | 1 - mediapipe/util/tracking/tracked_detection_manager.cc | 1 - 3 files changed, 3 deletions(-) diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarks_detector_graph.cc b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarks_detector_graph.cc index f7fa83a11..9409303ba 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarks_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarks_detector_graph.cc @@ -59,7 +59,6 @@ using ::mediapipe::api2::Output; using ::mediapipe::api2::builder::Graph; using ::mediapipe::api2::builder::Source; using ::mediapipe::tasks::components::utils::AllowIf; -using ::mediapipe::tasks::core::ModelResources; using ::mediapipe::tasks::vision::hand_landmarker::proto:: HandLandmarksDetectorGraphOptions; using LabelItems = mediapipe::proto_ns::Map; diff --git a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc index 9d7111e75..b17b3b0d3 100644 --- a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc +++ b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc @@ -64,7 +64,6 @@ using ::mediapipe::CalculatorGraphConfig; using ::mediapipe::Image; using ::mediapipe::NormalizedRect; using ::mediapipe::tasks::vision::image_segmenter::ImageSegmenterResult; -using ::mediapipe::tasks::vision::image_segmenter::proto::SegmenterOptions; using ImageSegmenterGraphOptionsProto = ::mediapipe::tasks::vision:: image_segmenter::proto::ImageSegmenterGraphOptions; diff --git a/mediapipe/util/tracking/tracked_detection_manager.cc b/mediapipe/util/tracking/tracked_detection_manager.cc index 7da207682..77aab3107 100644 --- a/mediapipe/util/tracking/tracked_detection_manager.cc +++ b/mediapipe/util/tracking/tracked_detection_manager.cc @@ -21,7 +21,6 @@ namespace { -using ::mediapipe::NormalizedRect; using mediapipe::TrackedDetection; // Checks if a point is out of view. From 476c7efc181b58e608d2953a6307e1b0c2a164a1 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 19 Apr 2023 13:24:47 -0700 Subject: [PATCH 046/753] 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 --- mediapipe/framework/scheduler.h | 2 +- mediapipe/gpu/gl_context.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mediapipe/framework/scheduler.h b/mediapipe/framework/scheduler.h index b59467b9f..8a6d079e3 100644 --- a/mediapipe/framework/scheduler.h +++ b/mediapipe/framework/scheduler.h @@ -310,7 +310,7 @@ class Scheduler { absl::Mutex state_mutex_; // Current state of the scheduler. - std::atomic state_ = ATOMIC_VAR_INIT(STATE_NOT_STARTED); + std::atomic state_ = STATE_NOT_STARTED; // True if all graph input streams are closed. bool graph_input_streams_closed_ ABSL_GUARDED_BY(state_mutex_) = false; diff --git a/mediapipe/gpu/gl_context.h b/mediapipe/gpu/gl_context.h index 4f2390404..fba0267a8 100644 --- a/mediapipe/gpu/gl_context.h +++ b/mediapipe/gpu/gl_context.h @@ -454,8 +454,8 @@ class GlContext : public std::enable_shared_from_this { // Number of glFinish calls completed on the GL thread. // Changes should be guarded by mutex_. However, we use simple atomic // loads for efficiency on the fast path. - std::atomic gl_finish_count_ = ATOMIC_VAR_INIT(0); - std::atomic gl_finish_count_target_ = ATOMIC_VAR_INIT(0); + std::atomic gl_finish_count_ = 0; + std::atomic gl_finish_count_target_ = 0; GlContext* context_waiting_on_ ABSL_GUARDED_BY(mutex_) = nullptr; From ffbd799b8d7d0eee201ede0fbc4c9314848c890b Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 19 Apr 2023 15:34:07 -0700 Subject: [PATCH 047/753] Extract shared types to create and test landmarks PiperOrigin-RevId: 525568412 --- .../tasks/web/components/processors/BUILD | 24 +++++++++ .../processors/landmark_result.test.ts | 52 +++++++++++++++++++ .../components/processors/landmark_result.ts | 45 ++++++++++++++++ .../processors/landmark_result_test_lib.ts | 44 ++++++++++++++++ .../tasks/web/vision/face_landmarker/BUILD | 3 +- .../vision/face_landmarker/face_landmarker.ts | 12 +---- .../face_landmarker/face_landmarker_test.ts | 46 ++++++++-------- .../tasks/web/vision/hand_landmarker/BUILD | 3 +- .../vision/hand_landmarker/hand_landmarker.ts | 23 ++------ .../hand_landmarker_result.d.ts | 2 +- .../hand_landmarker/hand_landmarker_test.ts | 50 +++++++----------- 11 files changed, 217 insertions(+), 87 deletions(-) create mode 100644 mediapipe/tasks/web/components/processors/landmark_result.test.ts create mode 100644 mediapipe/tasks/web/components/processors/landmark_result.ts create mode 100644 mediapipe/tasks/web/components/processors/landmark_result_test_lib.ts diff --git a/mediapipe/tasks/web/components/processors/BUILD b/mediapipe/tasks/web/components/processors/BUILD index a5f93a147..d81fbc79a 100644 --- a/mediapipe/tasks/web/components/processors/BUILD +++ b/mediapipe/tasks/web/components/processors/BUILD @@ -125,3 +125,27 @@ jasmine_node_test( name = "embedder_options_test", deps = [":embedder_options_test_lib"], ) + +mediapipe_ts_library( + name = "landmark_result", + srcs = [ + "landmark_result.ts", + "landmark_result_test_lib.ts", + ], + deps = [ + "//mediapipe/framework/formats:landmark_jspb_proto", + "//mediapipe/tasks/web/components/containers:landmark", + ], +) + +mediapipe_ts_library( + name = "landmark_result_test_lib", + testonly = True, + srcs = ["landmark_result.test.ts"], + deps = [":landmark_result"], +) + +jasmine_node_test( + name = "landmark_result_test", + deps = [":landmark_result_test_lib"], +) diff --git a/mediapipe/tasks/web/components/processors/landmark_result.test.ts b/mediapipe/tasks/web/components/processors/landmark_result.test.ts new file mode 100644 index 000000000..3a2635107 --- /dev/null +++ b/mediapipe/tasks/web/components/processors/landmark_result.test.ts @@ -0,0 +1,52 @@ +/** + * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'jasmine'; + +import {convertToLandmarks, convertToWorldLandmarks} from '../../../../tasks/web/components/processors/landmark_result'; +import {createLandmarks, createWorldLandmarks} from '../../../../tasks/web/components/processors/landmark_result_test_lib'; + + +// The OSS JS API does not support the builder pattern. +// tslint:disable:jspb-use-builder-pattern + +describe('convertToLandmarks()', () => { + it('transforms custom values', () => { + const landmarkListProto = createLandmarks(0.1, 0.2, 0.3); + const result = convertToLandmarks(landmarkListProto); + expect(result).toEqual([{x: 0.1, y: 0.2, z: 0.3}]); + }); + + it('transforms default values', () => { + const landmarkListProto = createLandmarks(); + const result = convertToLandmarks(landmarkListProto); + expect(result).toEqual([{x: 0, y: 0, z: 0}]); + }); +}); + +describe('convertToWorldLandmarks()', () => { + it('transforms custom values', () => { + const worldLandmarkListProto = createWorldLandmarks(10, 20, 30); + const result = convertToWorldLandmarks(worldLandmarkListProto); + expect(result).toEqual([{x: 10, y: 20, z: 30}]); + }); + + it('transforms default values', () => { + const worldLandmarkListProto = createWorldLandmarks(); + const result = convertToWorldLandmarks(worldLandmarkListProto); + expect(result).toEqual([{x: 0, y: 0, z: 0}]); + }); +}); diff --git a/mediapipe/tasks/web/components/processors/landmark_result.ts b/mediapipe/tasks/web/components/processors/landmark_result.ts new file mode 100644 index 000000000..3a4fa0245 --- /dev/null +++ b/mediapipe/tasks/web/components/processors/landmark_result.ts @@ -0,0 +1,45 @@ +/** + * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {LandmarkList as LandmarkListProto, NormalizedLandmarkList as NormalizedLandmarkListProto} from '../../../../framework/formats/landmark_pb'; +import {Landmark, NormalizedLandmark} from '../../../../tasks/web/components/containers/landmark'; + +/** Converts raw data into a landmark. */ +export function convertToLandmarks(proto: NormalizedLandmarkListProto): + NormalizedLandmark[] { + const landmarks: NormalizedLandmark[] = []; + for (const landmark of proto.getLandmarkList()) { + landmarks.push({ + x: landmark.getX() ?? 0, + y: landmark.getY() ?? 0, + z: landmark.getZ() ?? 0, + }); + } + return landmarks; +} + +/** Converts raw data into a world landmark. */ +export function convertToWorldLandmarks(proto: LandmarkListProto): Landmark[] { + const worldLandmarks: Landmark[] = []; + for (const worldLandmark of proto.getLandmarkList()) { + worldLandmarks.push({ + x: worldLandmark.getX() ?? 0, + y: worldLandmark.getY() ?? 0, + z: worldLandmark.getZ() ?? 0, + }); + } + return worldLandmarks; +} diff --git a/mediapipe/tasks/web/components/processors/landmark_result_test_lib.ts b/mediapipe/tasks/web/components/processors/landmark_result_test_lib.ts new file mode 100644 index 000000000..318ab2f63 --- /dev/null +++ b/mediapipe/tasks/web/components/processors/landmark_result_test_lib.ts @@ -0,0 +1,44 @@ +/** + * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {Landmark as LandmarkProto, LandmarkList as LandmarkListProto, NormalizedLandmark as NormalizedLandmarkProto, NormalizedLandmarkList as NormalizedLandmarkListProto} from '../../../../framework/formats/landmark_pb'; + +// The OSS JS API does not support the builder pattern. +// tslint:disable:jspb-use-builder-pattern + +/** Creates a normalized landmark list with one entrry. */ +export function createLandmarks( + x?: number, y?: number, z?: number): NormalizedLandmarkListProto { + const landmarksProto = new NormalizedLandmarkListProto(); + const landmark = new NormalizedLandmarkProto(); + if (x !== undefined) landmark.setX(x); + if (y !== undefined) landmark.setY(y); + if (z !== undefined) landmark.setZ(z); + landmarksProto.addLandmark(landmark); + return landmarksProto; +} + +/** Creates a world landmark list with one entry. */ +export function createWorldLandmarks( + x?: number, y?: number, z?: number): LandmarkListProto { + const worldLandmarksProto = new LandmarkListProto(); + const landmark = new LandmarkProto(); + if (x !== undefined) landmark.setX(x); + if (y !== undefined) landmark.setY(y); + if (z !== undefined) landmark.setZ(z); + worldLandmarksProto.addLandmark(landmark); + return worldLandmarksProto; +} diff --git a/mediapipe/tasks/web/vision/face_landmarker/BUILD b/mediapipe/tasks/web/vision/face_landmarker/BUILD index 19108be3a..01f26bdad 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/BUILD +++ b/mediapipe/tasks/web/vision/face_landmarker/BUILD @@ -31,6 +31,7 @@ mediapipe_ts_library( "//mediapipe/tasks/web/components/containers:landmark", "//mediapipe/tasks/web/components/containers:matrix", "//mediapipe/tasks/web/components/processors:classifier_result", + "//mediapipe/tasks/web/components/processors:landmark_result", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/vision/core:image_processing_options", "//mediapipe/tasks/web/vision/core:vision_task_runner", @@ -73,9 +74,9 @@ mediapipe_ts_library( ":face_landmarker_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/framework/formats:classification_jspb_proto", - "//mediapipe/framework/formats:landmark_jspb_proto", "//mediapipe/framework/formats:matrix_data_jspb_proto", "//mediapipe/tasks/cc/vision/face_geometry/proto:face_geometry_jspb_proto", + "//mediapipe/tasks/web/components/processors:landmark_result", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", "//mediapipe/tasks/web/vision/core:vision_task_runner", diff --git a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts index 2e6ec5d10..2a30f0606 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts +++ b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts @@ -23,8 +23,8 @@ import {FaceDetectorGraphOptions} from '../../../../tasks/cc/vision/face_detecto import {FaceGeometry as FaceGeometryProto} from '../../../../tasks/cc/vision/face_geometry/proto/face_geometry_pb'; import {FaceLandmarkerGraphOptions} from '../../../../tasks/cc/vision/face_landmarker/proto/face_landmarker_graph_options_pb'; import {FaceLandmarksDetectorGraphOptions} from '../../../../tasks/cc/vision/face_landmarker/proto/face_landmarks_detector_graph_options_pb'; -import {NormalizedLandmark} from '../../../../tasks/web/components/containers/landmark'; import {convertFromClassifications} from '../../../../tasks/web/components/processors/classifier_result'; +import {convertToLandmarks} from '../../../../tasks/web/components/processors/landmark_result'; import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; import {VisionGraphRunner, VisionTaskRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; @@ -243,15 +243,7 @@ export class FaceLandmarker extends VisionTaskRunner { for (const binaryProto of data) { const faceLandmarksProto = NormalizedLandmarkListProto.deserializeBinary(binaryProto); - const landmarks: NormalizedLandmark[] = []; - for (const faceLandmarkProto of faceLandmarksProto.getLandmarkList()) { - landmarks.push({ - x: faceLandmarkProto.getX() ?? 0, - y: faceLandmarkProto.getY() ?? 0, - z: faceLandmarkProto.getZ() ?? 0, - }); - } - this.result.faceLandmarks.push(landmarks); + this.result.faceLandmarks.push(convertToLandmarks(faceLandmarksProto)); } } diff --git a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_test.ts b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_test.ts index 92012a6f3..b590b4a4a 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_test.ts @@ -17,9 +17,9 @@ import 'jasmine'; import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; import {Classification, ClassificationList} from '../../../../framework/formats/classification_pb'; -import {NormalizedLandmark, NormalizedLandmarkList} from '../../../../framework/formats/landmark_pb'; import {MatrixData as MatrixDataProto} from '../../../../framework/formats/matrix_data_pb'; import {FaceGeometry as FaceGeometryProto} from '../../../../tasks/cc/vision/face_geometry/proto/face_geometry_pb'; +import {createLandmarks} from '../../../../tasks/web/components/processors/landmark_result_test_lib'; import {addJasmineCustomFloatEqualityTester, createSpyWasmModule, MediapipeTasksFake, SpyWasmModule, verifyGraph, verifyListenersRegistered} from '../../../../tasks/web/core/task_runner_test_utils'; import {VisionGraphRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; @@ -31,7 +31,7 @@ import {FaceLandmarkerOptions} from './face_landmarker_options'; type ProtoListener = ((binaryProtos: Uint8Array[], timestamp: number) => void); -function createBlendshapes(): Uint8Array[] { +function createBlendshapes(): ClassificationList { const blendshapesProto = new ClassificationList(); const classification = new Classification(); classification.setScore(0.1); @@ -39,27 +39,17 @@ function createBlendshapes(): Uint8Array[] { classification.setLabel('face_label'); classification.setDisplayName('face_display_name'); blendshapesProto.addClassification(classification); - return [blendshapesProto.serializeBinary()]; + return blendshapesProto; } -function createFacialTransformationMatrixes(): Uint8Array[] { +function createFacialTransformationMatrixes(): FaceGeometryProto { const faceGeometryProto = new FaceGeometryProto(); const posteTransformationMatrix = new MatrixDataProto(); posteTransformationMatrix.setRows(1); posteTransformationMatrix.setCols(1); posteTransformationMatrix.setPackedDataList([1.0]); faceGeometryProto.setPoseTransformMatrix(posteTransformationMatrix); - return [faceGeometryProto.serializeBinary()]; -} - -function createLandmarks(): Uint8Array[] { - const faceLandmarksProto = new NormalizedLandmarkList(); - const landmark = new NormalizedLandmark(); - landmark.setX(0.3); - landmark.setY(0.4); - landmark.setZ(0.5); - faceLandmarksProto.addLandmark(landmark); - return [faceLandmarksProto.serializeBinary()]; + return faceGeometryProto; } class FaceLandmarkerFake extends FaceLandmarker implements MediapipeTasksFake { @@ -243,13 +233,17 @@ describe('FaceLandmarker', () => { }); it('transforms results', async () => { + const landmarksProto = [createLandmarks().serializeBinary()]; + const blendshapesProto = [createBlendshapes().serializeBinary()]; + const faceGeometryProto = + [createFacialTransformationMatrixes().serializeBinary()]; + // Pass the test data to our listener faceLandmarker.fakeWasmModule._waitUntilIdle.and.callFake(() => { verifyListenersRegistered(faceLandmarker); - faceLandmarker.listeners.get('face_landmarks')!(createLandmarks(), 1337); - faceLandmarker.listeners.get('blendshapes')!(createBlendshapes(), 1337); - faceLandmarker.listeners.get('face_geometry')! - (createFacialTransformationMatrixes(), 1337); + faceLandmarker.listeners.get('face_landmarks')!(landmarksProto, 1337); + faceLandmarker.listeners.get('blendshapes')!(blendshapesProto, 1337); + faceLandmarker.listeners.get('face_geometry')!(faceGeometryProto, 1337); }); await faceLandmarker.setOptions({ @@ -266,7 +260,7 @@ describe('FaceLandmarker', () => { expect(faceLandmarker.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); expect(landmarks).toEqual({ - faceLandmarks: [[{x: 0.3, y: 0.4, z: 0.5}]], + faceLandmarks: [[{x: 0, y: 0, z: 0}]], faceBlendshapes: [{ categories: [{ index: 1, @@ -282,12 +276,16 @@ describe('FaceLandmarker', () => { }); it('clears results between invoations', async () => { + const landmarksProto = [createLandmarks().serializeBinary()]; + const blendshapesProto = [createBlendshapes().serializeBinary()]; + const faceGeometryProto = + [createFacialTransformationMatrixes().serializeBinary()]; + // Pass the test data to our listener faceLandmarker.fakeWasmModule._waitUntilIdle.and.callFake(() => { - faceLandmarker.listeners.get('face_landmarks')!(createLandmarks(), 1337); - faceLandmarker.listeners.get('blendshapes')!(createBlendshapes(), 1337); - faceLandmarker.listeners.get('face_geometry')! - (createFacialTransformationMatrixes(), 1337); + faceLandmarker.listeners.get('face_landmarks')!(landmarksProto, 1337); + faceLandmarker.listeners.get('blendshapes')!(blendshapesProto, 1337); + faceLandmarker.listeners.get('face_geometry')!(faceGeometryProto, 1337); }); await faceLandmarker.setOptions({ diff --git a/mediapipe/tasks/web/vision/hand_landmarker/BUILD b/mediapipe/tasks/web/vision/hand_landmarker/BUILD index 948d56927..cd6f39f7d 100644 --- a/mediapipe/tasks/web/vision/hand_landmarker/BUILD +++ b/mediapipe/tasks/web/vision/hand_landmarker/BUILD @@ -27,6 +27,7 @@ mediapipe_ts_library( "//mediapipe/tasks/cc/vision/hand_landmarker/proto:hand_landmarks_detector_graph_options_jspb_proto", "//mediapipe/tasks/web/components/containers:category", "//mediapipe/tasks/web/components/containers:landmark", + "//mediapipe/tasks/web/components/processors:landmark_result", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/vision/core:image_processing_options", "//mediapipe/tasks/web/vision/core:vision_task_runner", @@ -61,7 +62,7 @@ mediapipe_ts_library( ":hand_landmarker_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/framework/formats:classification_jspb_proto", - "//mediapipe/framework/formats:landmark_jspb_proto", + "//mediapipe/tasks/web/components/processors:landmark_result", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", "//mediapipe/tasks/web/vision/core:vision_task_runner", diff --git a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker.ts b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker.ts index 62928536d..2d2d05f9f 100644 --- a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker.ts +++ b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker.ts @@ -24,6 +24,7 @@ import {HandLandmarkerGraphOptions} from '../../../../tasks/cc/vision/hand_landm import {HandLandmarksDetectorGraphOptions} from '../../../../tasks/cc/vision/hand_landmarker/proto/hand_landmarks_detector_graph_options_pb'; import {Category} from '../../../../tasks/web/components/containers/category'; import {Landmark, NormalizedLandmark} from '../../../../tasks/web/components/containers/landmark'; +import {convertToLandmarks, convertToWorldLandmarks} from '../../../../tasks/web/components/processors/landmark_result'; import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; import {VisionGraphRunner, VisionTaskRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; @@ -259,15 +260,7 @@ export class HandLandmarker extends VisionTaskRunner { for (const binaryProto of data) { const handLandmarksProto = NormalizedLandmarkList.deserializeBinary(binaryProto); - const landmarks: NormalizedLandmark[] = []; - for (const handLandmarkProto of handLandmarksProto.getLandmarkList()) { - landmarks.push({ - x: handLandmarkProto.getX() ?? 0, - y: handLandmarkProto.getY() ?? 0, - z: handLandmarkProto.getZ() ?? 0, - }); - } - this.landmarks.push(landmarks); + this.landmarks.push(convertToLandmarks(handLandmarksProto)); } } @@ -279,16 +272,8 @@ export class HandLandmarker extends VisionTaskRunner { for (const binaryProto of data) { const handWorldLandmarksProto = LandmarkList.deserializeBinary(binaryProto); - const worldLandmarks: Landmark[] = []; - for (const handWorldLandmarkProto of - handWorldLandmarksProto.getLandmarkList()) { - worldLandmarks.push({ - x: handWorldLandmarkProto.getX() ?? 0, - y: handWorldLandmarkProto.getY() ?? 0, - z: handWorldLandmarkProto.getZ() ?? 0, - }); - } - this.worldLandmarks.push(worldLandmarks); + this.worldLandmarks.push( + convertToWorldLandmarks(handWorldLandmarksProto)); } } diff --git a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_result.d.ts b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_result.d.ts index 8a6d9bfa6..dc0f2fe0f 100644 --- a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_result.d.ts +++ b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_result.d.ts @@ -26,7 +26,7 @@ export declare interface HandLandmarkerResult { /** Hand landmarks of detected hands. */ landmarks: NormalizedLandmark[][]; - /** Hand landmarks in world coordniates of detected hands. */ + /** Hand landmarks in world coordinates of detected hands. */ worldLandmarks: Landmark[][]; /** Handedness of detected hands. */ diff --git a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_test.ts b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_test.ts index 5fd493424..f439e66e6 100644 --- a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_test.ts @@ -17,7 +17,7 @@ import 'jasmine'; import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; import {Classification, ClassificationList} from '../../../../framework/formats/classification_pb'; -import {Landmark, LandmarkList, NormalizedLandmark, NormalizedLandmarkList} from '../../../../framework/formats/landmark_pb'; +import {createLandmarks, createWorldLandmarks} from '../../../../tasks/web/components/processors/landmark_result_test_lib'; import {addJasmineCustomFloatEqualityTester, createSpyWasmModule, MediapipeTasksFake, SpyWasmModule, verifyGraph, verifyListenersRegistered} from '../../../../tasks/web/core/task_runner_test_utils'; import {VisionGraphRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; @@ -30,7 +30,7 @@ import {HandLandmarkerOptions} from './hand_landmarker_options'; type ProtoListener = ((binaryProtos: Uint8Array[], timestamp: number) => void); -function createHandednesses(): Uint8Array[] { +function createHandednesses(): ClassificationList { const handsProto = new ClassificationList(); const classification = new Classification(); classification.setScore(0.1); @@ -38,27 +38,7 @@ function createHandednesses(): Uint8Array[] { classification.setLabel('handedness_label'); classification.setDisplayName('handedness_display_name'); handsProto.addClassification(classification); - return [handsProto.serializeBinary()]; -} - -function createLandmarks(): Uint8Array[] { - const handLandmarksProto = new NormalizedLandmarkList(); - const landmark = new NormalizedLandmark(); - landmark.setX(0.3); - landmark.setY(0.4); - landmark.setZ(0.5); - handLandmarksProto.addLandmark(landmark); - return [handLandmarksProto.serializeBinary()]; -} - -function createWorldLandmarks(): Uint8Array[] { - const handLandmarksProto = new LandmarkList(); - const landmark = new Landmark(); - landmark.setX(21); - landmark.setY(22); - landmark.setZ(23); - handLandmarksProto.addLandmark(landmark); - return [handLandmarksProto.serializeBinary()]; + return handsProto; } class HandLandmarkerFake extends HandLandmarker implements MediapipeTasksFake { @@ -212,13 +192,17 @@ describe('HandLandmarker', () => { }); it('transforms results', async () => { + const landmarksProto = [createLandmarks().serializeBinary()]; + const worldLandmarksProto = [createWorldLandmarks().serializeBinary()]; + const handednessProto = [createHandednesses().serializeBinary()]; + // Pass the test data to our listener handLandmarker.fakeWasmModule._waitUntilIdle.and.callFake(() => { verifyListenersRegistered(handLandmarker); - handLandmarker.listeners.get('hand_landmarks')!(createLandmarks(), 1337); + handLandmarker.listeners.get('hand_landmarks')!(landmarksProto, 1337); handLandmarker.listeners.get('world_hand_landmarks')! - (createWorldLandmarks(), 1337); - handLandmarker.listeners.get('handedness')!(createHandednesses(), 1337); + (worldLandmarksProto, 1337); + handLandmarker.listeners.get('handedness')!(handednessProto, 1337); }); // Invoke the hand landmarker @@ -230,8 +214,8 @@ describe('HandLandmarker', () => { expect(handLandmarker.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); expect(landmarks).toEqual({ - 'landmarks': [[{'x': 0.3, 'y': 0.4, 'z': 0.5}]], - 'worldLandmarks': [[{'x': 21, 'y': 22, 'z': 23}]], + 'landmarks': [[{'x': 0, 'y': 0, 'z': 0}]], + 'worldLandmarks': [[{'x': 0, 'y': 0, 'z': 0}]], 'handednesses': [[{ 'score': 0.1, 'index': 1, @@ -242,12 +226,16 @@ describe('HandLandmarker', () => { }); it('clears results between invoations', async () => { + const landmarks = [createLandmarks().serializeBinary()]; + const worldLandmarks = [createWorldLandmarks().serializeBinary()]; + const handedness = [createHandednesses().serializeBinary()]; + // Pass the test data to our listener handLandmarker.fakeWasmModule._waitUntilIdle.and.callFake(() => { - handLandmarker.listeners.get('hand_landmarks')!(createLandmarks(), 1337); + handLandmarker.listeners.get('hand_landmarks')!(landmarks, 1337); handLandmarker.listeners.get('world_hand_landmarks')! - (createWorldLandmarks(), 1337); - handLandmarker.listeners.get('handedness')!(createHandednesses(), 1337); + (worldLandmarks, 1337); + handLandmarker.listeners.get('handedness')!(handedness, 1337); }); // Invoke the hand landmarker twice From 331692577e8f9bd77d239519ca28657ce4148d83 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 19 Apr 2023 23:45:26 -0700 Subject: [PATCH 048/753] Internal change PiperOrigin-RevId: 525660743 --- .../tensorflow_inference_calculator.cc | 18 +++++++++--------- .../unpack_media_sequence_calculator.cc | 14 +++++++------- .../vector_float_to_tensor_calculator_test.cc | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/mediapipe/calculators/tensorflow/tensorflow_inference_calculator.cc b/mediapipe/calculators/tensorflow/tensorflow_inference_calculator.cc index 4a47b7d7f..2608b1c5b 100644 --- a/mediapipe/calculators/tensorflow/tensorflow_inference_calculator.cc +++ b/mediapipe/calculators/tensorflow/tensorflow_inference_calculator.cc @@ -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 inference_state) { - const int64 start_time = absl::ToUnixMicros(clock_->TimeNow()); + const int64_t start_time = absl::ToUnixMicros(clock_->TimeNow()); std::vector> 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; diff --git a/mediapipe/calculators/tensorflow/unpack_media_sequence_calculator.cc b/mediapipe/calculators/tensorflow/unpack_media_sequence_calculator.cc index 0d1d4ca26..a14c6bd95 100644 --- a/mediapipe/calculators/tensorflow/unpack_media_sequence_calculator.cc +++ b/mediapipe/calculators/tensorflow/unpack_media_sequence_calculator.cc @@ -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> timestamps_; + std::map> 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 keypoint_names_; // Default keypoint location when missing. diff --git a/mediapipe/calculators/tensorflow/vector_float_to_tensor_calculator_test.cc b/mediapipe/calculators/tensorflow/vector_float_to_tensor_calculator_test.cc index aadce3615..a4f98d2e9 100644 --- a/mediapipe/calculators/tensorflow/vector_float_to_tensor_calculator_test.cc +++ b/mediapipe/calculators/tensorflow/vector_float_to_tensor_calculator_test.cc @@ -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(1 << i); } - const int64 time = 1234; + const int64_t time = 1234; runner_->MutableInputs()->Index(0).packets.push_back( Adopt(input.release()).At(Timestamp(time))); From 21ddba0d60d14d84b2a8c8995fb977ba97a794dc Mon Sep 17 00:00:00 2001 From: Kinar R <42828719+kinaryml@users.noreply.github.com> Date: Thu, 20 Apr 2023 13:21:31 +0530 Subject: [PATCH 049/753] Update copyright --- mediapipe/tasks/python/vision/pose_landmarker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/python/vision/pose_landmarker.py b/mediapipe/tasks/python/vision/pose_landmarker.py index 1e6945ec9..f5ebd1fd9 100644 --- a/mediapipe/tasks/python/vision/pose_landmarker.py +++ b/mediapipe/tasks/python/vision/pose_landmarker.py @@ -1,4 +1,4 @@ -# Copyright 2022 The MediaPipe Authors. All Rights Reserved. +# Copyright 2023 The MediaPipe Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 9032bce577c88315f1c55aa4dea4d8e4b79b8bd9 Mon Sep 17 00:00:00 2001 From: Kinar R <42828719+kinaryml@users.noreply.github.com> Date: Thu, 20 Apr 2023 13:21:56 +0530 Subject: [PATCH 050/753] Update copyright --- mediapipe/tasks/python/test/vision/pose_landmarker_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py index 07d7f06a4..fb5ad86e6 100644 --- a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py +++ b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The MediaPipe Authors. All Rights Reserved. +# Copyright 2023 The MediaPipe Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From a89ec882b06c7c9a631ec04cbbc5f5874e2d4d77 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 20 Apr 2023 09:51:35 -0700 Subject: [PATCH 051/753] Internal change PiperOrigin-RevId: 525774601 --- mediapipe/calculators/util/annotation_overlay_calculator.cc | 2 +- mediapipe/util/BUILD | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediapipe/calculators/util/annotation_overlay_calculator.cc b/mediapipe/calculators/util/annotation_overlay_calculator.cc index 6e0dc769b..34093702c 100644 --- a/mediapipe/calculators/util/annotation_overlay_calculator.cc +++ b/mediapipe/calculators/util/annotation_overlay_calculator.cc @@ -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); diff --git a/mediapipe/util/BUILD b/mediapipe/util/BUILD index cd82a850a..19aa6c1c7 100644 --- a/mediapipe/util/BUILD +++ b/mediapipe/util/BUILD @@ -163,12 +163,12 @@ cc_library( hdrs = ["annotation_renderer.h"], visibility = ["//visibility:public"], deps = [ + ":color_cc_proto", ":render_data_cc_proto", "//mediapipe/framework/port:logging", "//mediapipe/framework/port:opencv_core", "//mediapipe/framework/port:opencv_imgproc", "//mediapipe/framework/port:vector", - "//mediapipe/util:color_cc_proto", ], ) From d4c7ad0411a8b2583652dc8c7d3b3d9f197a44e3 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 20 Apr 2023 09:56:24 -0700 Subject: [PATCH 052/753] Internal change PiperOrigin-RevId: 525775875 --- mediapipe/modules/objectron/calculators/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/mediapipe/modules/objectron/calculators/BUILD b/mediapipe/modules/objectron/calculators/BUILD index 14cea526f..2e33ebf6c 100644 --- a/mediapipe/modules/objectron/calculators/BUILD +++ b/mediapipe/modules/objectron/calculators/BUILD @@ -298,6 +298,7 @@ cc_library( ":tensors_to_objects_calculator_cc_proto", "//mediapipe/framework:calculator_framework", "//mediapipe/framework/deps:file_path", + "//mediapipe/framework/formats:tensor", "//mediapipe/framework/port:opencv_core", "//mediapipe/framework/port:ret_check", "@com_google_absl//absl/memory", From 983932b6dde393c6bc86be8e42f44aa046087145 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 20 Apr 2023 10:40:58 -0700 Subject: [PATCH 053/753] This will fix the multiple typos in the new tasks internal files PiperOrigin-RevId: 525788850 --- .../face_landmarker/face_landmarker_test.cc | 4 ++-- .../utils/sources/MPPCategory+Helpers.mm | 14 +++++++------- mediapipe/tasks/web/audio/README.md | 2 +- mediapipe/tasks/web/text/README.md | 2 +- .../vision/image_segmenter/image_segmenter.ts | 18 +++++++++--------- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_test.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_test.cc index 411693ecf..97af42da7 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_test.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_test.cc @@ -67,7 +67,7 @@ constexpr char kPortraitExpectedFaceLandmarksName[] = "portrait_expected_face_landmarks.pbtxt"; constexpr char kPortraitExpectedBlendshapesName[] = "portrait_expected_blendshapes.pbtxt"; -constexpr char kPortaitExpectedFaceGeomertyName[] = +constexpr char kPortraitExpectedFaceGeometryName[] = "portrait_expected_face_geometry.pbtxt"; constexpr float kLandmarksDiffMargin = 0.03; @@ -100,7 +100,7 @@ struct FaceLandmarkerTestParams { mediapipe::MatrixData MakePortraitExpectedFacialTransformationMatrix() { auto face_geometry = GetExpectedProto( - kPortaitExpectedFaceGeomertyName); + kPortraitExpectedFaceGeometryName); return face_geometry.pose_transform_matrix(); } diff --git a/mediapipe/tasks/ios/components/containers/utils/sources/MPPCategory+Helpers.mm b/mediapipe/tasks/ios/components/containers/utils/sources/MPPCategory+Helpers.mm index ff0983139..12cfa5627 100644 --- a/mediapipe/tasks/ios/components/containers/utils/sources/MPPCategory+Helpers.mm +++ b/mediapipe/tasks/ios/components/containers/utils/sources/MPPCategory+Helpers.mm @@ -21,20 +21,20 @@ using ClassificationProto = ::mediapipe::Classification; @implementation MPPCategory (Helpers) -+ (MPPCategory *)categoryWithProto:(const ClassificationProto &)clasificationProto { ++ (MPPCategory *)categoryWithProto:(const ClassificationProto &)classificationProto { NSString *categoryName; NSString *displayName; - if (clasificationProto.has_label()) { - categoryName = [NSString stringWithCppString:clasificationProto.label()]; + if (classificationProto.has_label()) { + categoryName = [NSString stringWithCppString:classificationProto.label()]; } - if (clasificationProto.has_display_name()) { - displayName = [NSString stringWithCppString:clasificationProto.display_name()]; + if (classificationProto.has_display_name()) { + displayName = [NSString stringWithCppString:classificationProto.display_name()]; } - return [[MPPCategory alloc] initWithIndex:clasificationProto.index() - score:clasificationProto.score() + return [[MPPCategory alloc] initWithIndex:classificationProto.index() + score:classificationProto.score() categoryName:categoryName displayName:displayName]; } diff --git a/mediapipe/tasks/web/audio/README.md b/mediapipe/tasks/web/audio/README.md index 834785709..ed2543c7a 100644 --- a/mediapipe/tasks/web/audio/README.md +++ b/mediapipe/tasks/web/audio/README.md @@ -13,7 +13,7 @@ const audio = await FilesetResolver.forAudioTasks( const audioClassifier = await AudioClassifier.createFromModelPath(audio, "https://storage.googleapis.com/mediapipe-tasks/audio_classifier/yamnet_audio_classifier_with_metadata.tflite" ); -const classifications = audioClassifier.classifiy(audioData); +const classifications = audioClassifier.classify(audioData); ``` ## Audio Embedding diff --git a/mediapipe/tasks/web/text/README.md b/mediapipe/tasks/web/text/README.md index 089894653..4a26f5b9d 100644 --- a/mediapipe/tasks/web/text/README.md +++ b/mediapipe/tasks/web/text/README.md @@ -28,7 +28,7 @@ const text = await FilesetResolver.forTextTasks( const textClassifier = await TextClassifier.createFromModelPath(text, "https://storage.googleapis.com/mediapipe-tasks/text_classifier/bert_text_classifier.tflite" ); -const classifications = textClassifier.classifiy(textData); +const classifications = textClassifier.classify(textData); ``` For more information, refer to the [Text Classification](https://developers.google.com/mediapipe/solutions/text/text_classifier/web_js) documentation. diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts index 740047762..c32423e12 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts @@ -56,7 +56,7 @@ const DEFAULT_OUTPUT_CONFIDENCE_MASKS = true; * asynchronous processing is needed, all data needs to be copied before the * callback returns. */ -export type ImageSegmenterCallack = (result: ImageSegmenterResult) => void; +export type ImageSegmenterCallback = (result: ImageSegmenterResult) => void; /** Performs image segmentation on images. */ export class ImageSegmenter extends VisionTaskRunner { @@ -208,7 +208,7 @@ export class ImageSegmenter extends VisionTaskRunner { * lifetime of the returned data is only guaranteed for the duration of the * callback. */ - segment(image: ImageSource, callback: ImageSegmenterCallack): void; + segment(image: ImageSource, callback: ImageSegmenterCallback): void; /** * Performs image segmentation on the provided single image and invokes the * callback with the response. The method returns synchronously once the @@ -224,12 +224,12 @@ export class ImageSegmenter extends VisionTaskRunner { */ segment( image: ImageSource, imageProcessingOptions: ImageProcessingOptions, - callback: ImageSegmenterCallack): void; + callback: ImageSegmenterCallback): void; segment( image: ImageSource, imageProcessingOptionsOrCallback: ImageProcessingOptions| - ImageSegmenterCallack, - callback?: ImageSegmenterCallack): void { + ImageSegmenterCallback, + callback?: ImageSegmenterCallback): void { const imageProcessingOptions = typeof imageProcessingOptionsOrCallback !== 'function' ? imageProcessingOptionsOrCallback : @@ -258,7 +258,7 @@ export class ImageSegmenter extends VisionTaskRunner { */ segmentForVideo( videoFrame: ImageSource, timestamp: number, - callback: ImageSegmenterCallack): void; + callback: ImageSegmenterCallback): void; /** * Performs image segmentation on the provided video frame and invokes the * callback with the response. The method returns synchronously once the @@ -275,12 +275,12 @@ export class ImageSegmenter extends VisionTaskRunner { */ segmentForVideo( videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, - timestamp: number, callback: ImageSegmenterCallack): void; + timestamp: number, callback: ImageSegmenterCallback): void; segmentForVideo( videoFrame: ImageSource, timestampOrImageProcessingOptions: number|ImageProcessingOptions, - timestampOrCallback: number|ImageSegmenterCallack, - callback?: ImageSegmenterCallack): void { + timestampOrCallback: number|ImageSegmenterCallback, + callback?: ImageSegmenterCallback): void { const imageProcessingOptions = typeof timestampOrImageProcessingOptions !== 'number' ? timestampOrImageProcessingOptions : From 02bdb9aba076653769f6ade84a99f8b8a2434e55 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 20 Apr 2023 14:11:21 -0700 Subject: [PATCH 054/753] Internal change PiperOrigin-RevId: 525845988 --- mediapipe/calculators/util/annotation_overlay_calculator.cc | 2 +- mediapipe/util/BUILD | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediapipe/calculators/util/annotation_overlay_calculator.cc b/mediapipe/calculators/util/annotation_overlay_calculator.cc index 34093702c..6e0dc769b 100644 --- a/mediapipe/calculators/util/annotation_overlay_calculator.cc +++ b/mediapipe/calculators/util/annotation_overlay_calculator.cc @@ -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::COLOR_GRAY2RGB); + cv::cvtColor(input_mat, rgb_mat, CV_GRAY2RGB); rgb_mat.copyTo(*image_mat); } else { input_mat.copyTo(*image_mat); diff --git a/mediapipe/util/BUILD b/mediapipe/util/BUILD index 19aa6c1c7..cd82a850a 100644 --- a/mediapipe/util/BUILD +++ b/mediapipe/util/BUILD @@ -163,12 +163,12 @@ cc_library( hdrs = ["annotation_renderer.h"], visibility = ["//visibility:public"], deps = [ - ":color_cc_proto", ":render_data_cc_proto", "//mediapipe/framework/port:logging", "//mediapipe/framework/port:opencv_core", "//mediapipe/framework/port:opencv_imgproc", "//mediapipe/framework/port:vector", + "//mediapipe/util:color_cc_proto", ], ) From bd73617e5c080dec851c1ff929f5f2ea48f32190 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 20 Apr 2023 14:45:08 -0700 Subject: [PATCH 055/753] Internal change PiperOrigin-RevId: 525854969 --- mediapipe/web/graph_runner/graph_runner.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mediapipe/web/graph_runner/graph_runner.ts b/mediapipe/web/graph_runner/graph_runner.ts index 578577cf0..0115312b4 100644 --- a/mediapipe/web/graph_runner/graph_runner.ts +++ b/mediapipe/web/graph_runner/graph_runner.ts @@ -14,6 +14,7 @@ import {isWebKit} from '../../web/graph_runner/platform_utils'; */ export declare interface FileLocator { locateFile: (filename: string) => string; + mainScriptUrlOrBlob?: string; } /** @@ -1222,7 +1223,11 @@ export async function createMediaPipeLib( // self.Module and a fileLocator, we manually merge them into self.Module and // use that. TODO: Remove this when asset scripts are fixed. if (self.Module && fileLocator) { - (self.Module as FileLocator).locateFile = fileLocator.locateFile; + const moduleFileLocator = self.Module as FileLocator; + moduleFileLocator.locateFile = fileLocator.locateFile; + if (fileLocator.mainScriptUrlOrBlob) { + moduleFileLocator.mainScriptUrlOrBlob = fileLocator.mainScriptUrlOrBlob; + } } // TODO: Ensure that fileLocator is passed in by all users // and make it required From e9bb84950319da52b86e9f61ac6b3f03c1b71622 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 20 Apr 2023 15:12:14 -0700 Subject: [PATCH 056/753] Fix Typo PiperOrigin-RevId: 525861968 --- .../interactive_segmenter/interactive_segmenter.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts index 16841bd7f..df00b2cee 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts @@ -55,7 +55,7 @@ const DEFAULT_OUTPUT_CONFIDENCE_MASKS = true; * asynchronous processing is needed, all data needs to be copied before the * callback returns. */ -export type InteractiveSegmenterCallack = +export type InteractiveSegmenterCallback = (result: InteractiveSegmenterResult) => void; /** @@ -202,7 +202,7 @@ export class InteractiveSegmenter extends VisionTaskRunner { */ segment( image: ImageSource, roi: RegionOfInterest, - callback: InteractiveSegmenterCallack): void; + callback: InteractiveSegmenterCallback): void; /** * Performs interactive segmentation on the provided single image and invokes * the callback with the response. The `roi` parameter is used to represent a @@ -231,12 +231,12 @@ export class InteractiveSegmenter extends VisionTaskRunner { segment( image: ImageSource, roi: RegionOfInterest, imageProcessingOptions: ImageProcessingOptions, - callback: InteractiveSegmenterCallack): void; + callback: InteractiveSegmenterCallback): void; segment( image: ImageSource, roi: RegionOfInterest, imageProcessingOptionsOrCallback: ImageProcessingOptions| - InteractiveSegmenterCallack, - callback?: InteractiveSegmenterCallack): void { + InteractiveSegmenterCallback, + callback?: InteractiveSegmenterCallback): void { const imageProcessingOptions = typeof imageProcessingOptionsOrCallback !== 'function' ? imageProcessingOptionsOrCallback : From 9be748db00e3f7e0c85b30403b8a40094fe7afeb Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 20 Apr 2023 15:58:54 -0700 Subject: [PATCH 057/753] Create MPImage type for Web PiperOrigin-RevId: 525873209 --- mediapipe/tasks/web/vision/BUILD | 1 + mediapipe/tasks/web/vision/core/BUILD | 17 + mediapipe/tasks/web/vision/core/image.test.ts | 287 +++++++++ mediapipe/tasks/web/vision/core/image.ts | 595 ++++++++++++++++++ mediapipe/tasks/web/vision/index.ts | 3 + mediapipe/tasks/web/vision/types.ts | 1 + 6 files changed, 904 insertions(+) create mode 100644 mediapipe/tasks/web/vision/core/image.test.ts create mode 100644 mediapipe/tasks/web/vision/core/image.ts diff --git a/mediapipe/tasks/web/vision/BUILD b/mediapipe/tasks/web/vision/BUILD index c86801955..fa1ed32da 100644 --- a/mediapipe/tasks/web/vision/BUILD +++ b/mediapipe/tasks/web/vision/BUILD @@ -20,6 +20,7 @@ mediapipe_files(srcs = [ VISION_LIBS = [ "//mediapipe/tasks/web/core:fileset_resolver", "//mediapipe/tasks/web/vision/core:drawing_utils", + "//mediapipe/tasks/web/vision/core:image", "//mediapipe/tasks/web/vision/face_detector", "//mediapipe/tasks/web/vision/face_landmarker", "//mediapipe/tasks/web/vision/face_stylizer", diff --git a/mediapipe/tasks/web/vision/core/BUILD b/mediapipe/tasks/web/vision/core/BUILD index 8f53dc2cb..f010a8bdd 100644 --- a/mediapipe/tasks/web/vision/core/BUILD +++ b/mediapipe/tasks/web/vision/core/BUILD @@ -39,6 +39,23 @@ mediapipe_ts_library( ], ) +mediapipe_ts_library( + name = "image", + srcs = ["image.ts"], +) + +mediapipe_ts_library( + name = "image_test_lib", + testonly = True, + srcs = ["image.test.ts"], + deps = [":image"], +) + +jasmine_node_test( + name = "image_test", + deps = [":image_test_lib"], +) + mediapipe_ts_library( name = "vision_task_runner", srcs = ["vision_task_runner.ts"], diff --git a/mediapipe/tasks/web/vision/core/image.test.ts b/mediapipe/tasks/web/vision/core/image.test.ts new file mode 100644 index 000000000..7373ea385 --- /dev/null +++ b/mediapipe/tasks/web/vision/core/image.test.ts @@ -0,0 +1,287 @@ +/** + * Copyright 2022 The MediaPipe Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'jasmine'; + +import {MPImage, MPImageShaderContext, MPImageStorageType} from './image'; + +const WIDTH = 2; +const HEIGHT = 2; + +const skip = typeof document === 'undefined'; +if (skip) { + console.log('These tests must be run in a browser.'); +} + +/** The image types supported by MPImage. */ +type ImageType = ImageData|ImageBitmap|WebGLTexture; + +async function createTestData( + gl: WebGL2RenderingContext, data: number[], width: number, + height: number): Promise<[ImageData, ImageBitmap, WebGLTexture]> { + const imageData = new ImageData(new Uint8ClampedArray(data), width, height); + const imageBitmap = await createImageBitmap(imageData); + const webGlTexture = gl.createTexture()!; + + gl.bindTexture(gl.TEXTURE_2D, webGlTexture); + gl.texImage2D( + gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imageBitmap); + gl.bindTexture(gl.TEXTURE_2D, null); + + return [imageData, imageBitmap, webGlTexture]; +} + +(skip ? xdescribe : describe)('MPImage', () => { + let canvas: OffscreenCanvas; + let gl: WebGL2RenderingContext; + let imageData: ImageData; + let imageBitmap: ImageBitmap; + let webGlTexture: WebGLTexture; + + beforeEach(async () => { + canvas = new OffscreenCanvas(WIDTH, HEIGHT); + gl = canvas.getContext('webgl2') as WebGL2RenderingContext; + + const images = await createTestData( + gl, [1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, 4, 0, 0, 255], WIDTH, + HEIGHT); + imageData = images[0]; + imageBitmap = images[1]; + webGlTexture = images[2]; + }); + + afterEach(() => { + gl.deleteTexture(webGlTexture); + imageBitmap.close(); + }); + + function readPixelsFromImageBitmap(imageBitmap: ImageBitmap): ImageData { + const canvas = new OffscreenCanvas(imageBitmap.width, imageBitmap.height); + const ctx = canvas.getContext('2d') as OffscreenCanvasRenderingContext2D; + ctx.drawImage(imageBitmap, 0, 0); + return ctx.getImageData(0, 0, imageBitmap.width, imageBitmap.height); + } + + function readPixelsFromWebGLTexture(texture: WebGLTexture): Uint8Array { + const pixels = new Uint8Array(WIDTH * WIDTH * 4); + + gl.bindTexture(gl.TEXTURE_2D, texture); + + const framebuffer = gl.createFramebuffer()!; + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + gl.readPixels(0, 0, WIDTH, HEIGHT, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteFramebuffer(framebuffer); + + gl.bindTexture(gl.TEXTURE_2D, null); + + return pixels; + } + + function assertEquality(image: MPImage, expected: ImageType): void { + if (expected instanceof ImageData) { + const result = image.getImage(MPImageStorageType.IMAGE_DATA); + expect(result).toEqual(expected); + } else if (expected instanceof ImageBitmap) { + const result = image.getImage(MPImageStorageType.IMAGE_BITMAP); + expect(readPixelsFromImageBitmap(result)) + .toEqual(readPixelsFromImageBitmap(expected)); + } else { // WebGLTexture + const result = image.getImage(MPImageStorageType.WEBGL_TEXTURE); + expect(readPixelsFromWebGLTexture(result)) + .toEqual(readPixelsFromWebGLTexture(expected)); + } + } + + function createImage( + shaderContext: MPImageShaderContext, input: ImageType, width: number, + height: number): MPImage { + return new MPImage( + input instanceof ImageData ? input : null, + input instanceof ImageBitmap ? input : null, + input instanceof WebGLTexture ? input : null, + /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, canvas, + shaderContext, width, height); + } + + function runConversionTest( + input: ImageType, output: ImageType, width = WIDTH, + height = HEIGHT): void { + const shaderContext = new MPImageShaderContext(); + const image = createImage(shaderContext, input, width, height); + assertEquality(image, output); + image.close(); + shaderContext.close(); + } + + function runCloneTest(input: ImageType): void { + const shaderContext = new MPImageShaderContext(); + const image = createImage(shaderContext, input, WIDTH, HEIGHT); + const clone = image.clone(); + assertEquality(clone, input); + clone.close(); + shaderContext.close(); + } + + it(`converts from ImageData to ImageData`, () => { + runConversionTest(imageData, imageData); + }); + + it(`converts from ImageData to ImageBitmap`, () => { + runConversionTest(imageData, imageBitmap); + }); + + it(`converts from ImageData to WebGLTexture`, () => { + runConversionTest(imageData, webGlTexture); + }); + + it(`converts from ImageBitmap to ImageData`, () => { + runConversionTest(imageBitmap, imageData); + }); + + it(`converts from ImageBitmap to ImageBitmap`, () => { + runConversionTest(imageBitmap, imageBitmap); + }); + + it(`converts from ImageBitmap to WebGLTexture`, () => { + runConversionTest(imageBitmap, webGlTexture); + }); + + it(`converts from WebGLTexture to ImageData`, () => { + runConversionTest(webGlTexture, imageData); + }); + + it(`converts from WebGLTexture to ImageBitmap`, () => { + runConversionTest(webGlTexture, imageBitmap); + }); + + it(`converts from WebGLTexture to WebGLTexture`, () => { + runConversionTest(webGlTexture, webGlTexture); + }); + + it(`clones ImageData`, () => { + runCloneTest(imageData); + }); + + it(`clones ImageBitmap`, () => { + runCloneTest(imageBitmap); + }); + + it(`clones WebGLTextures`, () => { + runCloneTest(webGlTexture); + }); + + it(`does not flip textures twice`, async () => { + const [imageData, , webGlTexture] = await createTestData( + gl, [1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, 4, 0, 0, 255], WIDTH, + HEIGHT); + + const shaderContext = new MPImageShaderContext(); + const image = new MPImage( + /* imageData= */ null, /* imageBitmap= */ null, webGlTexture, + /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, canvas, + shaderContext, WIDTH, HEIGHT); + + const result = image.clone().getImage(MPImageStorageType.IMAGE_DATA); + expect(result).toEqual(imageData); + + gl.deleteTexture(webGlTexture); + shaderContext.close(); + }); + + it(`can clone and get image`, async () => { + const [imageData, , webGlTexture] = await createTestData( + gl, [1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, 4, 0, 0, 255], WIDTH, + HEIGHT); + + const shaderContext = new MPImageShaderContext(); + const image = new MPImage( + /* imageData= */ null, /* imageBitmap= */ null, webGlTexture, + /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, canvas, + shaderContext, WIDTH, HEIGHT); + + // Verify that we can mix the different shader modes by running them out of + // order. + let result = image.getImage(MPImageStorageType.IMAGE_DATA); + expect(result).toEqual(imageData); + + result = image.clone().getImage(MPImageStorageType.IMAGE_DATA); + expect(result).toEqual(imageData); + + result = image.getImage(MPImageStorageType.IMAGE_DATA); + expect(result).toEqual(imageData); + + gl.deleteTexture(webGlTexture); + shaderContext.close(); + }); + + it('supports hasType()', async () => { + const shaderContext = new MPImageShaderContext(); + const image = createImage(shaderContext, imageData, WIDTH, HEIGHT); + + expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); + expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(false); + expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false); + + image.getImage(MPImageStorageType.WEBGL_TEXTURE); + + expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); + expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(true); + expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false); + + await image.getImage(MPImageStorageType.IMAGE_BITMAP); + + expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); + expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(true); + expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(true); + + image.close(); + shaderContext.close(); + }); + + it('supports image that is smaller than the canvas', async () => { + const [imageData, imageBitmap, webGlTexture] = await createTestData( + gl, [1, 0, 0, 255, 2, 0, 0, 255], /* width= */ 2, /* height= */ 1); + + runConversionTest(imageData, webGlTexture, /* width= */ 2, /* height= */ 1); + runConversionTest( + webGlTexture, imageBitmap, /* width= */ 2, /* height= */ 1); + runConversionTest(imageBitmap, imageData, /* width= */ 2, /* height= */ 1); + + gl.deleteTexture(webGlTexture); + imageBitmap.close(); + }); + + it('supports image that is larger than the canvas', async () => { + const [imageData, imageBitmap, webGlTexture] = await createTestData( + gl, + [ + 1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, + 4, 0, 0, 255, 5, 0, 0, 255, 6, 0, 0, 255 + ], + /* width= */ 2, /* height= */ 3); + + runConversionTest(imageData, webGlTexture, /* width= */ 2, /* height= */ 3); + runConversionTest( + webGlTexture, imageBitmap, /* width= */ 2, /* height= */ 3); + runConversionTest(imageBitmap, imageData, /* width= */ 2, /* height= */ 3); + + gl.deleteTexture(webGlTexture); + imageBitmap.close(); + }); +}); diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts new file mode 100644 index 000000000..a4bbdfe1e --- /dev/null +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -0,0 +1,595 @@ +/** + * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** The underlying type of the image. */ +export enum MPImageStorageType { + /** Represents the native `ImageData` type. */ + IMAGE_DATA, + /** Represents the native `ImageBitmap` type. */ + IMAGE_BITMAP, + /** Represents the native `WebGLTexture` type. */ + WEBGL_TEXTURE +} + +type MPImageNativeContainer = ImageData|ImageBitmap|WebGLTexture; + +const VERTEX_SHADER = ` + attribute vec2 aVertex; + attribute vec2 aTex; + varying vec2 vTex; + void main(void) { + gl_Position = vec4(aVertex, 0.0, 1.0); + vTex = aTex; + }`; + +const FRAGMENT_SHADER = ` + precision mediump float; + varying vec2 vTex; + uniform sampler2D inputTexture; + void main() { + gl_FragColor = texture2D(inputTexture, vTex); + } + `; + +function assertNotNull(value: T|null, msg: string): T { + if (value === null) { + throw new Error(`Unable to obtain required WebGL resource: ${msg}`); + } + return value; +} + +/** + * Utility class that encapsulates the buffers used by `MPImageShaderContext`. + */ +class MPImageShaderBuffers { + constructor( + private readonly gl: WebGL2RenderingContext, + private readonly vertexArrayObject: WebGLVertexArrayObject, + private readonly vertexBuffer: WebGLBuffer, + private readonly textureBuffer: WebGLBuffer) {} + + bind() { + this.gl.bindVertexArray(this.vertexArrayObject); + } + + unbind() { + this.gl.bindVertexArray(null); + } + + close() { + this.gl.deleteVertexArray(this.vertexArrayObject); + this.gl.deleteBuffer(this.vertexBuffer); + this.gl.deleteBuffer(this.textureBuffer); + } +} + +/** + * A class that encapsulates the shaders used by an MPImage. Can be re-used + * across MPImages that use the same WebGL2Rendering context. + */ +export class MPImageShaderContext { + private gl?: WebGL2RenderingContext; + private framebuffer?: WebGLFramebuffer; + private program?: WebGLProgram; + private vertexShader?: WebGLShader; + private fragmentShader?: WebGLShader; + private aVertex?: GLint; + private aTex?: GLint; + + /** + * The shader buffers used for passthrough renders that don't modify the + * input texture. + */ + private shaderBuffersPassthrough?: MPImageShaderBuffers; + + /** + * The shader buffers used for passthrough renders that flip the input texture + * vertically before conversion to a different type. This is used to flip the + * texture to the expected orientation for drawing in the browser. + */ + private shaderBuffersFlipVertically?: MPImageShaderBuffers; + + private compileShader(source: string, type: number): WebGLShader { + const gl = this.gl!; + const shader = + assertNotNull(gl.createShader(type), 'Failed to create WebGL shader'); + gl.shaderSource(shader, source); + gl.compileShader(shader); + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + const info = gl.getShaderInfoLog(shader); + throw new Error(`Could not compile WebGL shader: ${info}`); + } + gl.attachShader(this.program!, shader); + return shader; + } + + private setupShaders(): void { + const gl = this.gl!; + this.program = + assertNotNull(gl.createProgram()!, 'Failed to create WebGL program'); + + this.vertexShader = this.compileShader(VERTEX_SHADER, gl.VERTEX_SHADER); + this.fragmentShader = + this.compileShader(FRAGMENT_SHADER, gl.FRAGMENT_SHADER); + + gl.linkProgram(this.program); + const linked = gl.getProgramParameter(this.program, gl.LINK_STATUS); + if (!linked) { + const info = gl.getProgramInfoLog(this.program); + throw new Error(`Error during program linking: ${info}`); + } + + this.aVertex = gl.getAttribLocation(this.program, 'aVertex'); + this.aTex = gl.getAttribLocation(this.program, 'aTex'); + } + + private createBuffers(flipVertically: boolean): MPImageShaderBuffers { + const gl = this.gl!; + const vertexArrayObject = + assertNotNull(gl.createVertexArray(), 'Failed to create vertex array'); + gl.bindVertexArray(vertexArrayObject); + + const vertexBuffer = + assertNotNull(gl.createBuffer(), 'Failed to create buffer'); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.enableVertexAttribArray(this.aVertex!); + gl.vertexAttribPointer(this.aVertex!, 2, gl.FLOAT, false, 0, 0); + gl.bufferData( + gl.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), + gl.STATIC_DRAW); + + const textureBuffer = + assertNotNull(gl.createBuffer(), 'Failed to create buffer'); + gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer); + gl.enableVertexAttribArray(this.aTex!); + gl.vertexAttribPointer(this.aTex!, 2, gl.FLOAT, false, 0, 0); + + const bufferData = + flipVertically ? [0, 1, 0, 0, 1, 0, 1, 1] : [0, 0, 0, 1, 1, 1, 1, 0]; + gl.bufferData( + gl.ARRAY_BUFFER, new Float32Array(bufferData), gl.STATIC_DRAW); + + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.bindVertexArray(null); + + return new MPImageShaderBuffers( + gl, vertexArrayObject, vertexBuffer, textureBuffer); + } + + private getShaderBuffers(flipVertically: boolean): MPImageShaderBuffers { + if (flipVertically) { + if (!this.shaderBuffersFlipVertically) { + this.shaderBuffersFlipVertically = + this.createBuffers(/* flipVertically= */ true); + } + return this.shaderBuffersFlipVertically; + } else { + if (!this.shaderBuffersPassthrough) { + this.shaderBuffersPassthrough = + this.createBuffers(/* flipVertically= */ false); + } + return this.shaderBuffersPassthrough; + } + } + + private maybeInitGL(gl: WebGL2RenderingContext): void { + if (!this.gl) { + this.gl = gl; + } else if (gl !== this.gl) { + throw new Error('Cannot change GL context once initialized'); + } + } + + /** Runs the callback using the shader. */ + run( + gl: WebGL2RenderingContext, flipVertically: boolean, + callback: () => T): T { + this.maybeInitGL(gl); + + if (!this.program) { + this.setupShaders(); + } + + const shaderBuffers = this.getShaderBuffers(flipVertically); + gl.useProgram(this.program!); + shaderBuffers.bind(); + const result = callback(); + shaderBuffers.unbind(); + + return result; + } + /** + * Binds a framebuffer to the canvas. If the framebuffer does not yet exist, + * creates it first. Binds the provided texture to the framebuffer. + */ + bindFramebuffer(gl: WebGL2RenderingContext, texture: WebGLTexture): void { + this.maybeInitGL(gl); + if (!this.framebuffer) { + this.framebuffer = + assertNotNull(gl.createFramebuffer(), 'Failed to create framebuffe.'); + } + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + } + + unbindFramebuffer(): void { + this.gl?.bindFramebuffer(this.gl.FRAMEBUFFER, null); + } + + close() { + if (this.program) { + const gl = this.gl!; + gl.deleteProgram(this.program); + gl.deleteShader(this.vertexShader!); + gl.deleteShader(this.fragmentShader!); + } + if (this.framebuffer) { + this.gl!.deleteFramebuffer(this.framebuffer); + } + if (this.shaderBuffersPassthrough) { + this.shaderBuffersPassthrough.close(); + } + if (this.shaderBuffersFlipVertically) { + this.shaderBuffersFlipVertically.close(); + } + } +} + +/** + * The wrapper class for MediaPipe Image objects. + * + * Images are stored as `ImageData`, `ImageBitmap` or `WebGLTexture` objects. + * You can convert the underlying type to any other type by passing the + * desired type to `getImage()`. As type conversions can be expensive, it is + * recommended to limit these conversions. You can verify what underlying + * types are already available by invoking `hasType()`. + * + * Images that are returned from a MediaPipe Tasks are owned by by the + * underlying C++ Task. If you need to extend the lifetime of these objects, + * you can invoke the `clone()` method. To free up the resources obtained + * during any clone or type conversion operation, it is important to invoke + * `close()` on the `MPImage` instance. + * + * Converting to and from ImageBitmap requires that the MediaPipe task is + * initialized with an `OffscreenCanvas`. As we require WebGL2 support, this + * places some limitations on Browser support as outlined here: + * https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas/getContext + */ +export class MPImage { + private gl?: WebGL2RenderingContext; + + /** @hideconstructor */ + constructor( + private imageData: ImageData|null, + private imageBitmap: ImageBitmap|null, + private webGLTexture: WebGLTexture|null, + private ownsImageBitmap: boolean, + private ownsWebGLTexture: boolean, + /** Returns the canvas element that the image is bound to. */ + readonly canvas: HTMLCanvasElement|OffscreenCanvas|undefined, + private shaderContext: MPImageShaderContext|undefined, + /** Returns the width of the image. */ + readonly width: number, + /** Returns the height of the image. */ + readonly height: number, + ) {} + + /** + * Returns whether this `MPImage` stores the image in the desired format. + * This method can be called to reduce expensive conversion before invoking + * `getType()`. + */ + hasType(type: MPImageStorageType): boolean { + if (type === MPImageStorageType.IMAGE_DATA) { + return !!this.imageData; + } else if (type === MPImageStorageType.IMAGE_BITMAP) { + return !!this.imageBitmap; + } else if (type === MPImageStorageType.WEBGL_TEXTURE) { + return !!this.webGLTexture; + } else { + throw new Error(`Type is not supported: ${type}`); + } + } + + /** + * Returns the underlying image as an `ImageData` object. Note that this + * involves an expensive GPU to CPU transfer if the current image is only + * available as an `ImageBitmap` or `WebGLTexture`. + * + * @return The current image as an ImageData object. + */ + getImage(type: MPImageStorageType.IMAGE_DATA): ImageData; + /** + * Returns the underlying image as an `ImageBitmap`. Note that + * conversions to `ImageBitmap` are expensive, especially if the data + * currently resides on CPU. + * + * Processing with `ImageBitmap`s requires that the MediaPipe Task was + * initialized with an `OffscreenCanvas` with WebGL2 support. See + * https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas/getContext + * for a list of supported platforms. + * + * @return The current image as an ImageBitmap object. + */ + getImage(type: MPImageStorageType.IMAGE_BITMAP): ImageBitmap; + /** + * Returns the underlying image as a `WebGLTexture` object. Note that this + * involves a CPU to GPU transfer if the current image is only available as + * an `ImageData` object. The returned texture is bound to the current + * canvas (see `.canvas`). + * + * @return The current image as a WebGLTexture. + */ + getImage(type: MPImageStorageType.WEBGL_TEXTURE): WebGLTexture; + getImage(type?: MPImageStorageType): MPImageNativeContainer { + if (type === MPImageStorageType.IMAGE_DATA) { + return this.convertToImageData(); + } else if (type === MPImageStorageType.IMAGE_BITMAP) { + return this.convertToImageBitmap(); + } else if (type === MPImageStorageType.WEBGL_TEXTURE) { + return this.convertToWebGLTexture(); + } else { + throw new Error(`Type is not supported: ${type}`); + } + } + + /** + * Creates a copy of the resources stored in this `MPImage`. You can invoke + * this method to extend the lifetime of an image returned by a MediaPipe + * Task. Note that performance critical applications should aim to only use + * the `MPImage` within the MediaPipe Task callback so that copies can be + * avoided. + */ + clone(): MPImage { + // TODO: We might only want to clone one backing datastructure + // even if multiple are defined. + let destinationImageData: ImageData|null = null; + let destinationImageBitmap: ImageBitmap|null = null; + let destinationWebGLTexture: WebGLTexture|null = null; + + if (this.imageData) { + destinationImageData = + new ImageData(this.imageData.data, this.width, this.height); + } + + if (this.webGLTexture) { + const gl = this.getGL(); + const shaderContext = this.getShaderContext(); + + // Create a new texture and use it to back a framebuffer + gl.activeTexture(gl.TEXTURE1); + destinationWebGLTexture = + assertNotNull(gl.createTexture(), 'Failed to create texture'); + gl.bindTexture(gl.TEXTURE_2D, destinationWebGLTexture); + + gl.texImage2D( + gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, + gl.UNSIGNED_BYTE, null); + + shaderContext.bindFramebuffer(gl, destinationWebGLTexture); + shaderContext.run(gl, /* flipVertically= */ false, () => { + this.bindTexture(); // This activates gl.TEXTURE0 + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + gl.drawArrays(gl.TRIANGLE_FAN, 0, 4); + this.unbindTexture(); + }); + shaderContext.unbindFramebuffer(); + + this.unbindTexture(); + } + + if (this.imageBitmap) { + this.convertToWebGLTexture(); + this.bindTexture(); + destinationImageBitmap = this.copyTextureToBitmap(); + this.unbindTexture(); + } + + return new MPImage( + destinationImageData, destinationImageBitmap, destinationWebGLTexture, + !!destinationImageBitmap, !!destinationWebGLTexture, this.canvas, + this.shaderContext, this.width, this.height); + } + + + private getOffscreenCanvas(): OffscreenCanvas { + if (!(this.canvas instanceof OffscreenCanvas)) { + throw new Error( + 'Conversion to ImageBitmap requires that the MediaPipe Tasks is ' + + 'initialized with an OffscreenCanvas'); + } + return this.canvas; + } + + private getGL(): WebGL2RenderingContext { + if (!this.canvas) { + throw new Error( + 'Conversion to different image formats require that a canvas ' + + 'is passed when iniitializing the image.'); + } + if (!this.gl) { + this.gl = assertNotNull( + this.canvas.getContext('webgl2') as WebGL2RenderingContext | null, + 'You cannot use a canvas that is already bound to a different ' + + 'type of rendering context.'); + } + return this.gl; + } + + private getShaderContext(): MPImageShaderContext { + if (!this.shaderContext) { + this.shaderContext = new MPImageShaderContext(); + } + return this.shaderContext; + } + + private convertToImageBitmap(): ImageBitmap { + if (!this.imageBitmap) { + if (!this.webGLTexture) { + this.webGLTexture = this.convertToWebGLTexture(); + } + this.imageBitmap = this.convertWebGLTextureToImageBitmap(); + this.ownsImageBitmap = true; + } + + return this.imageBitmap; + } + + private convertToImageData(): ImageData { + if (!this.imageData) { + const gl = this.getGL(); + const shaderContext = this.getShaderContext(); + const pixels = new Uint8Array(this.width * this.height * 4); + + // Create texture if needed + this.convertToWebGLTexture(); + + // Create a framebuffer from the texture and read back pixels + shaderContext.bindFramebuffer(gl, this.webGLTexture!); + gl.readPixels( + 0, 0, this.width, this.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + shaderContext.unbindFramebuffer(); + + this.imageData = new ImageData( + new Uint8ClampedArray(pixels.buffer), this.width, this.height); + } + + return this.imageData; + } + + private convertToWebGLTexture(): WebGLTexture { + if (!this.webGLTexture) { + const gl = this.getGL(); + this.bindTexture(); + const source = (this.imageBitmap || this.imageData)!; + gl.texImage2D( + gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source); + this.unbindTexture(); + } + + return this.webGLTexture!; + } + + /** + * Binds the backing texture to the canvas. If the texture does not yet + * exist, creates it first. + */ + private bindTexture() { + const gl = this.getGL(); + + gl.viewport(0, 0, this.width, this.height); + + gl.activeTexture(gl.TEXTURE0); + if (!this.webGLTexture) { + this.webGLTexture = + assertNotNull(gl.createTexture(), 'Failed to create texture'); + this.ownsWebGLTexture = true; + } + + gl.bindTexture(gl.TEXTURE_2D, this.webGLTexture); + // TODO: Ideally, we would only set these once per texture and + // not once every frame. + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + } + + private unbindTexture(): void { + this.gl!.bindTexture(this.gl!.TEXTURE_2D, null); + } + + /** + * Invokes a shader to render the current texture and return it as an + * ImageBitmap + */ + private copyTextureToBitmap(): ImageBitmap { + const gl = this.getGL(); + const shaderContext = this.getShaderContext(); + + return shaderContext.run(gl, /* flipVertically= */ true, () => { + return this.runWithResizedCanvas(() => { + // Unbind any framebuffer that may be bound since + // `transferToImageBitmap()` requires rendering into the display (null) + // framebuffer. + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + gl.drawArrays(gl.TRIANGLE_FAN, 0, 4); + return this.getOffscreenCanvas().transferToImageBitmap(); + }); + }); + } + + private convertWebGLTextureToImageBitmap(): ImageBitmap { + this.bindTexture(); + const result = this.copyTextureToBitmap(); + this.unbindTexture(); + return result; + } + + /** + * Temporarily resizes the underlying canvas to match the dimensions of the + * image. Runs the provided callback on the resized canvas. + * + * Note that while resizing is an expensive operation, it allows us to use + * the synchronous `transferToImageBitmap()` API. + */ + private runWithResizedCanvas(callback: () => T): T { + const canvas = this.canvas!; + + if (canvas.width === this.width && canvas.height === this.height) { + return callback(); + } + + const originalWidth = canvas.width; + const originalHeight = canvas.height; + canvas.width = this.width; + canvas.height = this.height; + + const result = callback(); + + canvas.width = originalWidth; + canvas.height = originalHeight; + + return result; + } + + /** + * Frees up any resources owned by this `MPImage` instance. + * + * Note that this method does not free images that are owned by the C++ + * Task, as these are freed automatically once you leave the MediaPipe + * callback. Additionally, some shared state is freed only once you invoke the + * Task's `close()` method. + */ + close(): void { + if (this.ownsImageBitmap) { + this.imageBitmap!.close(); + } + + if (!this.gl) { + return; + } + + if (this.ownsWebGLTexture) { + this.gl.deleteTexture(this.webGLTexture!); + } + } +} diff --git a/mediapipe/tasks/web/vision/index.ts b/mediapipe/tasks/web/vision/index.ts index 3b3757bbd..c4adab7e6 100644 --- a/mediapipe/tasks/web/vision/index.ts +++ b/mediapipe/tasks/web/vision/index.ts @@ -16,6 +16,7 @@ import {FilesetResolver as FilesetResolverImpl} from '../../../tasks/web/core/fileset_resolver'; import {DrawingUtils as DrawingUtilsImpl} from '../../../tasks/web/vision/core/drawing_utils'; +import {MPImage as MPImageImpl} from '../../../tasks/web/vision/core/image'; import {FaceDetector as FaceDetectorImpl} from '../../../tasks/web/vision/face_detector/face_detector'; import {FaceLandmarker as FaceLandmarkerImpl, FaceLandmarksConnections as FaceLandmarksConnectionsImpl} from '../../../tasks/web/vision/face_landmarker/face_landmarker'; import {FaceStylizer as FaceStylizerImpl} from '../../../tasks/web/vision/face_stylizer/face_stylizer'; @@ -31,6 +32,7 @@ import {ObjectDetector as ObjectDetectorImpl} from '../../../tasks/web/vision/ob // as exports. const DrawingUtils = DrawingUtilsImpl; const FilesetResolver = FilesetResolverImpl; +const MPImage = MPImageImpl; const FaceDetector = FaceDetectorImpl; const FaceLandmarker = FaceLandmarkerImpl; const FaceLandmarksConnections = FaceLandmarksConnectionsImpl; @@ -46,6 +48,7 @@ const ObjectDetector = ObjectDetectorImpl; export { DrawingUtils, FilesetResolver, + MPImage, FaceDetector, FaceLandmarker, FaceLandmarksConnections, diff --git a/mediapipe/tasks/web/vision/types.ts b/mediapipe/tasks/web/vision/types.ts index 3db579f59..92cae43fb 100644 --- a/mediapipe/tasks/web/vision/types.ts +++ b/mediapipe/tasks/web/vision/types.ts @@ -16,6 +16,7 @@ export * from '../../../tasks/web/core/fileset_resolver'; export * from '../../../tasks/web/vision/core/drawing_utils'; +export * from '../../../tasks/web/vision/core/image'; export * from '../../../tasks/web/vision/face_detector/face_detector'; export * from '../../../tasks/web/vision/face_landmarker/face_landmarker'; export * from '../../../tasks/web/vision/face_stylizer/face_stylizer'; From a6c35e9ba5b7b877b8d907d0bf5b5c09d8dab6f3 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Fri, 21 Apr 2023 09:44:27 -0700 Subject: [PATCH 058/753] Fixes the typos in tasks internal files. PiperOrigin-RevId: 526063515 --- mediapipe/tasks/python/audio/core/audio_record.py | 6 +++--- .../tasks/python/test/audio/audio_classifier_test.py | 4 ++-- .../tasks/python/test/audio/audio_embedder_test.py | 4 ++-- .../tasks/python/vision/core/base_vision_task_api.py | 2 +- .../tasks/web/vision/core/vision_task_runner.ts | 2 +- .../vision/image_classifier/image_classifier_test.ts | 12 ++++++------ 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/mediapipe/tasks/python/audio/core/audio_record.py b/mediapipe/tasks/python/audio/core/audio_record.py index 91e394584..bc12e3755 100644 --- a/mediapipe/tasks/python/audio/core/audio_record.py +++ b/mediapipe/tasks/python/audio/core/audio_record.py @@ -47,11 +47,11 @@ class AudioRecord(object): raise sd_error if channels <= 0: - raise ValueError('channels must be postive.') + raise ValueError('channels must be positive.') if sampling_rate <= 0: - raise ValueError('sampling_rate must be postive.') + raise ValueError('sampling_rate must be positive.') if buffer_size <= 0: - raise ValueError('buffer_size must be postive.') + raise ValueError('buffer_size must be positive.') self._audio_buffer = [] self._buffer_size = buffer_size diff --git a/mediapipe/tasks/python/test/audio/audio_classifier_test.py b/mediapipe/tasks/python/test/audio/audio_classifier_test.py index fbd96ad3e..33f66786d 100644 --- a/mediapipe/tasks/python/test/audio/audio_classifier_test.py +++ b/mediapipe/tasks/python/test/audio/audio_classifier_test.py @@ -47,7 +47,7 @@ _TEST_DATA_DIR = 'mediapipe/tasks/testdata/audio' _TWO_HEADS_WAV_16K_MONO = 'two_heads_16000_hz_mono.wav' _TWO_HEADS_WAV_44K_MONO = 'two_heads_44100_hz_mono.wav' _YAMNET_NUM_OF_SAMPLES = 15600 -_MILLSECONDS_PER_SECOND = 1000 +_MILLISECONDS_PER_SECOND = 1000 class AudioClassifierTest(parameterized.TestCase): @@ -75,7 +75,7 @@ class AudioClassifierTest(parameterized.TestCase): end = min(start + (int)(step_size), len(buffer)) audio_data_list.append((_AudioData.create_from_array( buffer[start:end].astype(float) / np.iinfo(np.int16).max, - sample_rate), (int)(start / sample_rate * _MILLSECONDS_PER_SECOND))) + sample_rate), (int)(start / sample_rate * _MILLISECONDS_PER_SECOND))) start = end return audio_data_list diff --git a/mediapipe/tasks/python/test/audio/audio_embedder_test.py b/mediapipe/tasks/python/test/audio/audio_embedder_test.py index 0fc01ee7b..e5735b6b5 100644 --- a/mediapipe/tasks/python/test/audio/audio_embedder_test.py +++ b/mediapipe/tasks/python/test/audio/audio_embedder_test.py @@ -45,7 +45,7 @@ _SPEECH_WAV_48K_MONO = 'speech_48000_hz_mono.wav' _TWO_HEADS_WAV_16K_MONO = 'two_heads_16000_hz_mono.wav' _TEST_DATA_DIR = 'mediapipe/tasks/testdata/audio' _YAMNET_NUM_OF_SAMPLES = 15600 -_MILLSECONDS_PER_SECOND = 1000 +_MILLISECONDS_PER_SECOND = 1000 # Tolerance for embedding vector coordinate values. _EPSILON = 3e-6 @@ -78,7 +78,7 @@ class AudioEmbedderTest(parameterized.TestCase): end = min(start + (int)(step_size), len(buffer)) audio_data_list.append((_AudioData.create_from_array( buffer[start:end].astype(float) / np.iinfo(np.int16).max, - sample_rate), (int)(start / sample_rate * _MILLSECONDS_PER_SECOND))) + sample_rate), (int)(start / sample_rate * _MILLISECONDS_PER_SECOND))) start = end return audio_data_list diff --git a/mediapipe/tasks/python/vision/core/base_vision_task_api.py b/mediapipe/tasks/python/vision/core/base_vision_task_api.py index d9195d3ce..3775f2232 100644 --- a/mediapipe/tasks/python/vision/core/base_vision_task_api.py +++ b/mediapipe/tasks/python/vision/core/base_vision_task_api.py @@ -188,7 +188,7 @@ class BaseVisionTaskApi(object): # For 90° and 270° rotations, we need to swap width and height. # This is due to the internal behavior of ImageToTensorCalculator, which: # - first denormalizes the provided rect by multiplying the rect width or - # height by the image width or height, repectively. + # height by the image width or height, respectively. # - then rotates this by denormalized rect by the provided rotation, and # uses this for cropping, # - then finally rotates this back. diff --git a/mediapipe/tasks/web/vision/core/vision_task_runner.ts b/mediapipe/tasks/web/vision/core/vision_task_runner.ts index 2a5c3f0e2..b815a24d2 100644 --- a/mediapipe/tasks/web/vision/core/vision_task_runner.ts +++ b/mediapipe/tasks/web/vision/core/vision_task_runner.ts @@ -186,7 +186,7 @@ export abstract class VisionTaskRunner extends TaskRunner { // For 90° and 270° rotations, we need to swap width and height. // This is due to the internal behavior of ImageToTensorCalculator, which: // - first denormalizes the provided rect by multiplying the rect width or - // height by the image width or height, repectively. + // height by the image width or height, respectively. // - then rotates this by denormalized rect by the provided rotation, and // uses this for cropping, // - then finally rotates this back. diff --git a/mediapipe/tasks/web/vision/image_classifier/image_classifier_test.ts b/mediapipe/tasks/web/vision/image_classifier/image_classifier_test.ts index 60595310e..7058e2a5b 100644 --- a/mediapipe/tasks/web/vision/image_classifier/image_classifier_test.ts +++ b/mediapipe/tasks/web/vision/image_classifier/image_classifier_test.ts @@ -117,12 +117,12 @@ describe('ImageClassifier', () => { classifcations.setHeadIndex(1); classifcations.setHeadName('headName'); const classificationList = new ClassificationList(); - const clasification = new Classification(); - clasification.setIndex(1); - clasification.setScore(0.2); - clasification.setDisplayName('displayName'); - clasification.setLabel('categoryName'); - classificationList.addClassification(clasification); + const classification = new Classification(); + classification.setIndex(1); + classification.setScore(0.2); + classification.setDisplayName('displayName'); + classification.setLabel('categoryName'); + classificationList.addClassification(classification); classifcations.setClassificationList(classificationList); classificationResult.addClassifications(classifcations); From 2a2a55d1b84c908120fe237b9e892c708d05c532 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Fri, 21 Apr 2023 11:46:21 -0700 Subject: [PATCH 059/753] Added Language Detector Python API and fixed a typo in Interactive Segmenter Options' docstring --- mediapipe/tasks/python/test/text/BUILD | 15 ++ .../test/text/language_detector_test.py | 225 ++++++++++++++++++ mediapipe/tasks/python/text/BUILD | 20 ++ .../tasks/python/text/language_detector.py | 205 ++++++++++++++++ .../python/vision/interactive_segmenter.py | 2 +- mediapipe/tasks/testdata/text/BUILD | 6 + 6 files changed, 472 insertions(+), 1 deletion(-) create mode 100644 mediapipe/tasks/python/test/text/language_detector_test.py create mode 100644 mediapipe/tasks/python/text/language_detector.py diff --git a/mediapipe/tasks/python/test/text/BUILD b/mediapipe/tasks/python/test/text/BUILD index 5f2d18bc5..5f8551636 100644 --- a/mediapipe/tasks/python/test/text/BUILD +++ b/mediapipe/tasks/python/test/text/BUILD @@ -49,3 +49,18 @@ py_test( "//mediapipe/tasks/python/text:text_embedder", ], ) + +py_test( + name = "language_detector_test", + srcs = ["language_detector_test.py"], + data = [ + "//mediapipe/tasks/testdata/text:language_detector_model", + ], + deps = [ + "//mediapipe/tasks/python/components/containers:category", + "//mediapipe/tasks/python/components/containers:classification_result", + "//mediapipe/tasks/python/core:base_options", + "//mediapipe/tasks/python/test:test_utils", + "//mediapipe/tasks/python/text:language_detector", + ], +) diff --git a/mediapipe/tasks/python/test/text/language_detector_test.py b/mediapipe/tasks/python/test/text/language_detector_test.py new file mode 100644 index 000000000..2443d4312 --- /dev/null +++ b/mediapipe/tasks/python/test/text/language_detector_test.py @@ -0,0 +1,225 @@ +# Copyright 2022 The MediaPipe Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for language detector.""" + +import enum +import os + +from absl.testing import absltest +from absl.testing import parameterized + +from mediapipe.tasks.python.components.containers import category +from mediapipe.tasks.python.components.containers import classification_result as classification_result_module +from mediapipe.tasks.python.core import base_options as base_options_module +from mediapipe.tasks.python.test import test_utils +from mediapipe.tasks.python.text import language_detector + +LanguageDetectorResult = language_detector.LanguageDetectorResult +LanguageDetectorPrediction = language_detector.LanguageDetectorResult.LanguageDetectorPrediction +_BaseOptions = base_options_module.BaseOptions +_Category = category.Category +_Classifications = classification_result_module.Classifications +_LanguageDetector = language_detector.LanguageDetector +_LanguageDetectorOptions = language_detector.LanguageDetectorOptions + +_LANGUAGE_DETECTOR_MODEL = 'language_detector.tflite' +_TEST_DATA_DIR = 'mediapipe/tasks/testdata/text' + +_SCORE_THRESHOLD = 0.3 +_EN_TEXT = "To be, or not to be, that is the question" +_EN_EXPECTED_RESULT = LanguageDetectorResult( + [ + LanguageDetectorPrediction("en", 0.999856) + ] +) +_FR_TEXT = ( + "Il y a beaucoup de bouches qui parlent et fort peu de têtes qui pensent." +) +_FR_EXPECTED_RESULT = LanguageDetectorResult( + [ + LanguageDetectorPrediction("fr", 0.999781) + ] +) +_RU_TEXT = "Ñто какой-то английÑкий Ñзык" +_RU_EXPECTED_RESULT = LanguageDetectorResult( + [ + LanguageDetectorPrediction("ru", 0.993362) + ] +) +_MIXED_TEXT = "分久必åˆåˆä¹…必分" +_MIXED_EXPECTED_RESULT = LanguageDetectorResult( + [ + LanguageDetectorPrediction("zh", 0.505424), + LanguageDetectorPrediction("ja", 0.481617) + ] +) +_TOLERANCE = 1e-6 + + +class ModelFileType(enum.Enum): + FILE_CONTENT = 1 + FILE_NAME = 2 + + +class LanguageDetectorTest(parameterized.TestCase): + + def setUp(self): + super().setUp() + self.model_path = test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, _LANGUAGE_DETECTOR_MODEL)) + + def _expect_language_detector_result_correct( + self, + actual_result: LanguageDetectorResult, + expect_result: LanguageDetectorResult + ): + for i, prediction in enumerate(actual_result.languages_and_scores): + expected_prediction = expect_result.languages_and_scores[i] + self.assertEqual( + prediction.language_code, expected_prediction.language_code, + ) + self.assertAlmostEqual( + prediction.probability, expected_prediction.probability, + delta=_TOLERANCE + ) + + def test_create_from_file_succeeds_with_valid_model_path(self): + # Creates with default option and valid model file successfully. + with _LanguageDetector.create_from_model_path(self.model_path) as detector: + self.assertIsInstance(detector, _LanguageDetector) + + def test_create_from_options_succeeds_with_valid_model_path(self): + # Creates with options containing model file successfully. + base_options = _BaseOptions(model_asset_path=self.model_path) + options = _LanguageDetectorOptions(base_options=base_options) + with _LanguageDetector.create_from_options(options) as detector: + self.assertIsInstance(detector, _LanguageDetector) + + def test_create_from_options_fails_with_invalid_model_path(self): + with self.assertRaisesRegex( + RuntimeError, 'Unable to open file at /path/to/invalid/model.tflite'): + base_options = _BaseOptions( + model_asset_path='/path/to/invalid/model.tflite') + options = _LanguageDetectorOptions(base_options=base_options) + _LanguageDetector.create_from_options(options) + + def test_create_from_options_succeeds_with_valid_model_content(self): + # Creates with options containing model content successfully. + with open(self.model_path, 'rb') as f: + base_options = _BaseOptions(model_asset_buffer=f.read()) + options = _LanguageDetectorOptions(base_options=base_options) + detector = _LanguageDetector.create_from_options(options) + self.assertIsInstance(detector, _LanguageDetector) + + @parameterized.parameters( + (ModelFileType.FILE_NAME, _EN_TEXT, _EN_EXPECTED_RESULT), + (ModelFileType.FILE_CONTENT, _EN_TEXT, _EN_EXPECTED_RESULT), + (ModelFileType.FILE_NAME, _FR_TEXT, _FR_EXPECTED_RESULT), + (ModelFileType.FILE_CONTENT, _FR_TEXT, _FR_EXPECTED_RESULT), + (ModelFileType.FILE_NAME, _RU_TEXT, _RU_EXPECTED_RESULT), + (ModelFileType.FILE_CONTENT, _RU_TEXT, _RU_EXPECTED_RESULT), + (ModelFileType.FILE_NAME, _MIXED_TEXT, _MIXED_EXPECTED_RESULT), + (ModelFileType.FILE_CONTENT, _MIXED_TEXT, _MIXED_EXPECTED_RESULT) + ) + def test_detect(self, model_file_type, text, expected_result): + # Creates detector. + if model_file_type is ModelFileType.FILE_NAME: + base_options = _BaseOptions(model_asset_path=self.model_path) + elif model_file_type is ModelFileType.FILE_CONTENT: + with open(self.model_path, 'rb') as f: + model_content = f.read() + base_options = _BaseOptions(model_asset_buffer=model_content) + else: + # Should never happen + raise ValueError('model_file_type is invalid.') + + options = _LanguageDetectorOptions( + base_options=base_options, score_threshold=_SCORE_THRESHOLD + ) + detector = _LanguageDetector.create_from_options(options) + + # Performs language detection on the input. + text_result = detector.detect(text) + # Comparing results. + self._expect_language_detector_result_correct(text_result, expected_result) + # Closes the detector explicitly when the detector is not used in + # a context. + detector.close() + + @parameterized.parameters( + (ModelFileType.FILE_NAME, _EN_TEXT, _EN_EXPECTED_RESULT), + (ModelFileType.FILE_NAME, _FR_TEXT, _FR_EXPECTED_RESULT), + (ModelFileType.FILE_NAME, _RU_TEXT, _RU_EXPECTED_RESULT), + (ModelFileType.FILE_CONTENT, _MIXED_TEXT, _MIXED_EXPECTED_RESULT) + ) + def test_detect_in_context(self, model_file_type, text, expected_result): + # Creates detector. + if model_file_type is ModelFileType.FILE_NAME: + base_options = _BaseOptions(model_asset_path=self.model_path) + elif model_file_type is ModelFileType.FILE_CONTENT: + with open(self.model_path, 'rb') as f: + model_content = f.read() + base_options = _BaseOptions(model_asset_buffer=model_content) + else: + # Should never happen + raise ValueError('model_file_type is invalid.') + + options = _LanguageDetectorOptions( + base_options=base_options, score_threshold=_SCORE_THRESHOLD + ) + with _LanguageDetector.create_from_options(options) as detector: + # Performs language detection on the input. + text_result = detector.detect(text) + # Comparing results. + self._expect_language_detector_result_correct(text_result, expected_result) + + def test_allowlist_option(self): + # Creates detector. + base_options = _BaseOptions(model_asset_path=self.model_path) + options = _LanguageDetectorOptions( + base_options=base_options, score_threshold=_SCORE_THRESHOLD, + category_allowlist=["ja"] + ) + with _LanguageDetector.create_from_options(options) as detector: + # Performs language detection on the input. + text_result = detector.detect(_MIXED_TEXT) + # Comparing results. + expected_result = LanguageDetectorResult( + [ + LanguageDetectorPrediction("ja", 0.481617) + ] + ) + self._expect_language_detector_result_correct(text_result, expected_result) + + def test_denylist_option(self): + # Creates detector. + base_options = _BaseOptions(model_asset_path=self.model_path) + options = _LanguageDetectorOptions( + base_options=base_options, score_threshold=_SCORE_THRESHOLD, + category_denylist=["ja"] + ) + with _LanguageDetector.create_from_options(options) as detector: + # Performs language detection on the input. + text_result = detector.detect(_MIXED_TEXT) + # Comparing results. + expected_result = LanguageDetectorResult( + [ + LanguageDetectorPrediction("zh", 0.505424) + ] + ) + self._expect_language_detector_result_correct(text_result, expected_result) + + +if __name__ == '__main__': + absltest.main() diff --git a/mediapipe/tasks/python/text/BUILD b/mediapipe/tasks/python/text/BUILD index 9d5d23261..b1dd3feb9 100644 --- a/mediapipe/tasks/python/text/BUILD +++ b/mediapipe/tasks/python/text/BUILD @@ -57,3 +57,23 @@ py_library( "//mediapipe/tasks/python/text/core:base_text_task_api", ], ) + +py_library( + name = "language_detector", + srcs = [ + "language_detector.py", + ], + visibility = ["//mediapipe/tasks:users"], + deps = [ + "//mediapipe/python:packet_creator", + "//mediapipe/python:packet_getter", + "//mediapipe/tasks/cc/components/containers/proto:classifications_py_pb2", + "//mediapipe/tasks/cc/components/processors/proto:classifier_options_py_pb2", + "//mediapipe/tasks/cc/text/text_classifier/proto:text_classifier_graph_options_py_pb2", + "//mediapipe/tasks/python/components/containers:classification_result", + "//mediapipe/tasks/python/core:base_options", + "//mediapipe/tasks/python/core:optional_dependencies", + "//mediapipe/tasks/python/core:task_info", + "//mediapipe/tasks/python/text/core:base_text_task_api", + ], +) diff --git a/mediapipe/tasks/python/text/language_detector.py b/mediapipe/tasks/python/text/language_detector.py new file mode 100644 index 000000000..8d933dd59 --- /dev/null +++ b/mediapipe/tasks/python/text/language_detector.py @@ -0,0 +1,205 @@ +# Copyright 2022 The MediaPipe Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""MediaPipe language detector task.""" + +import dataclasses +from typing import Optional, List + +from mediapipe.python import packet_creator +from mediapipe.python import packet_getter +from mediapipe.tasks.cc.components.containers.proto import classifications_pb2 +from mediapipe.tasks.cc.components.processors.proto import classifier_options_pb2 +from mediapipe.tasks.cc.text.text_classifier.proto import text_classifier_graph_options_pb2 +from mediapipe.tasks.python.components.containers import classification_result as classification_result_module +from mediapipe.tasks.python.core import base_options as base_options_module +from mediapipe.tasks.python.core import task_info as task_info_module +from mediapipe.tasks.python.core.optional_dependencies import doc_controls +from mediapipe.tasks.python.text.core import base_text_task_api + +_ClassificationResult = classification_result_module.ClassificationResult +_BaseOptions = base_options_module.BaseOptions +_TextClassifierGraphOptionsProto = text_classifier_graph_options_pb2.TextClassifierGraphOptions +_ClassifierOptionsProto = classifier_options_pb2.ClassifierOptions +_TaskInfo = task_info_module.TaskInfo + +_CLASSIFICATIONS_STREAM_NAME = 'classifications_out' +_CLASSIFICATIONS_TAG = 'CLASSIFICATIONS' +_TEXT_IN_STREAM_NAME = 'text_in' +_TEXT_TAG = 'TEXT' +_TASK_GRAPH_NAME = 'mediapipe.tasks.text.text_classifier.TextClassifierGraph' + + +@dataclasses.dataclass +class LanguageDetectorResult: + + @dataclasses.dataclass + class LanguageDetectorPrediction: + """A language code and its probability.""" + language_code: str + probability: float + + languages_and_scores: List[LanguageDetectorPrediction] + + +def _extract_language_detector_result( + classification_result: classification_result_module.ClassificationResult +) -> LanguageDetectorResult: + if len(classification_result.classifications) != 1: + raise ValueError( + "The LanguageDetector TextClassifierGraph should have exactly one " + "classification head." + ) + languages_and_scores = classification_result.classifications[0] + language_detector_result = LanguageDetectorResult([]) + for category in languages_and_scores.categories: + if category.category_name is None: + raise ValueError( + "LanguageDetector ClassificationResult has a missing language code.") + prediction = LanguageDetectorResult.LanguageDetectorPrediction( + category.category_name, category.score + ) + language_detector_result.languages_and_scores.append(prediction) + return language_detector_result + + +@dataclasses.dataclass +class LanguageDetectorOptions: + """Options for the language detector task. + + Attributes: + base_options: Base options for the language detector task. + display_names_locale: The locale to use for display names specified through + the TFLite Model Metadata. + max_results: The maximum number of top-scored classification results to + return. + score_threshold: Overrides the ones provided in the model metadata. Results + below this value are rejected. + category_allowlist: Allowlist of category names. If non-empty, + classification results whose category name is not in this set will be + filtered out. Duplicate or unknown category names are ignored. Mutually + exclusive with `category_denylist`. + category_denylist: Denylist of category names. If non-empty, classification + results whose category name is in this set will be filtered out. Duplicate + or unknown category names are ignored. Mutually exclusive with + `category_allowlist`. + """ + base_options: _BaseOptions + display_names_locale: Optional[str] = None + max_results: Optional[int] = None + score_threshold: Optional[float] = None + category_allowlist: Optional[List[str]] = None + category_denylist: Optional[List[str]] = None + + @doc_controls.do_not_generate_docs + def to_pb2(self) -> _TextClassifierGraphOptionsProto: + """Generates an TextClassifierOptions protobuf object.""" + base_options_proto = self.base_options.to_pb2() + classifier_options_proto = _ClassifierOptionsProto( + score_threshold=self.score_threshold, + category_allowlist=self.category_allowlist, + category_denylist=self.category_denylist, + display_names_locale=self.display_names_locale, + max_results=self.max_results) + + return _TextClassifierGraphOptionsProto( + base_options=base_options_proto, + classifier_options=classifier_options_proto) + + +class LanguageDetector(base_text_task_api.BaseTextTaskApi): + """Class that predicts the language of an input text. + + This API expects a TFLite model with TFLite Model Metadata that contains the + mandatory (described below) input tensors, output tensor, and the language + codes in an AssociatedFile. + + Input tensors: + (kTfLiteString) + - 1 input tensor that is scalar or has shape [1] containing the input + string. + Output tensor: + (kTfLiteFloat32) + - 1 output tensor of shape`[1 x N]` where `N` is the number of languages. + """ + + @classmethod + def create_from_model_path(cls, model_path: str) -> 'LanguageDetector': + """Creates an `LanguageDetector` object from a TensorFlow Lite model and the default `LanguageDetectorOptions`. + + Args: + model_path: Path to the model. + + Returns: + `LanguageDetector` object that's created from the model file and the + default `LanguageDetectorOptions`. + + Raises: + ValueError: If failed to create `LanguageDetector` object from the provided + file such as invalid file path. + RuntimeError: If other types of error occurred. + """ + base_options = _BaseOptions(model_asset_path=model_path) + options = LanguageDetectorOptions(base_options=base_options) + return cls.create_from_options(options) + + @classmethod + def create_from_options(cls, + options: LanguageDetectorOptions) -> 'LanguageDetector': + """Creates the `LanguageDetector` object from language detector options. + + Args: + options: Options for the language detector task. + + Returns: + `LanguageDetector` object that's created from `options`. + + Raises: + ValueError: If failed to create `LanguageDetector` object from + `LanguageDetectorOptions` such as missing the model. + RuntimeError: If other types of error occurred. + """ + task_info = _TaskInfo( + task_graph=_TASK_GRAPH_NAME, + input_streams=[':'.join([_TEXT_TAG, _TEXT_IN_STREAM_NAME])], + output_streams=[ + ':'.join([_CLASSIFICATIONS_TAG, _CLASSIFICATIONS_STREAM_NAME]) + ], + task_options=options) + return cls(task_info.generate_graph_config()) + + def detect(self, text: str) -> LanguageDetectorResult: + """Predicts the language of the input `text`. + + Args: + text: The input text. + + Returns: + A `LanguageDetectorResult` object that contains a list of languages and + scores. + + Raises: + ValueError: If any of the input arguments is invalid. + RuntimeError: If language detection failed to run. + """ + output_packets = self._runner.process( + {_TEXT_IN_STREAM_NAME: packet_creator.create_string(text)}) + + classification_result_proto = classifications_pb2.ClassificationResult() + classification_result_proto.CopyFrom( + packet_getter.get_proto(output_packets[_CLASSIFICATIONS_STREAM_NAME])) + + classification_result = _ClassificationResult.create_from_pb2( + classification_result_proto + ) + return _extract_language_detector_result(classification_result) diff --git a/mediapipe/tasks/python/vision/interactive_segmenter.py b/mediapipe/tasks/python/vision/interactive_segmenter.py index ad93c798c..1d9f5cf1a 100644 --- a/mediapipe/tasks/python/vision/interactive_segmenter.py +++ b/mediapipe/tasks/python/vision/interactive_segmenter.py @@ -88,7 +88,7 @@ class InteractiveSegmenterOptions: @doc_controls.do_not_generate_docs def to_pb2(self) -> _ImageSegmenterGraphOptionsProto: - """Generates an InteractiveSegmenterOptions protobuf object.""" + """Generates an ImageSegmenterGraphOptions protobuf object.""" base_options_proto = self.base_options.to_pb2() base_options_proto.use_stream_mode = False segmenter_options_proto = _SegmenterOptionsProto() diff --git a/mediapipe/tasks/testdata/text/BUILD b/mediapipe/tasks/testdata/text/BUILD index 9813b6543..62251ed8b 100644 --- a/mediapipe/tasks/testdata/text/BUILD +++ b/mediapipe/tasks/testdata/text/BUILD @@ -31,6 +31,7 @@ mediapipe_files(srcs = [ "bert_text_classifier.tflite", "mobilebert_embedding_with_metadata.tflite", "mobilebert_with_metadata.tflite", + "language_detector.tflite", "regex_one_embedding_with_metadata.tflite", "test_model_text_classifier_bool_output.tflite", "test_model_text_classifier_with_regex_tokenizer.tflite", @@ -78,6 +79,11 @@ filegroup( ], ) +filegroup( + name = "language_detector_model", + srcs = ["language_detector.tflite"], +) + filegroup( name = "text_classifier_models", srcs = [ From 0b1eb39870ea6b61e6805f15262ebe7fd2241c8e Mon Sep 17 00:00:00 2001 From: kinaryml Date: Fri, 21 Apr 2023 11:48:06 -0700 Subject: [PATCH 060/753] Updated copyright --- mediapipe/tasks/python/test/text/language_detector_test.py | 2 +- mediapipe/tasks/python/text/language_detector.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/python/test/text/language_detector_test.py b/mediapipe/tasks/python/test/text/language_detector_test.py index 2443d4312..69a9c092b 100644 --- a/mediapipe/tasks/python/test/text/language_detector_test.py +++ b/mediapipe/tasks/python/test/text/language_detector_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The MediaPipe Authors. All Rights Reserved. +# Copyright 2023 The MediaPipe Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/mediapipe/tasks/python/text/language_detector.py b/mediapipe/tasks/python/text/language_detector.py index 8d933dd59..1cc363d98 100644 --- a/mediapipe/tasks/python/text/language_detector.py +++ b/mediapipe/tasks/python/text/language_detector.py @@ -1,4 +1,4 @@ -# Copyright 2022 The MediaPipe Authors. All Rights Reserved. +# Copyright 2023 The MediaPipe Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 58dcbc9833b821fc5b701ab06f96949f95709a57 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Fri, 21 Apr 2023 13:10:10 -0700 Subject: [PATCH 061/753] Internal change PiperOrigin-RevId: 526117263 --- mediapipe/framework/api2/port.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mediapipe/framework/api2/port.h b/mediapipe/framework/api2/port.h index f6abe75ed..18a786075 100644 --- a/mediapipe/framework/api2/port.h +++ b/mediapipe/framework/api2/port.h @@ -467,6 +467,11 @@ class SideFallbackT : public Base { // CalculatorContext (e.g. kOut(cc)), and provides a type-safe interface to // OutputStreamShard. Like that class, this class will not be usually named in // calculator code, but used as a temporary object (e.g. kOut(cc).Send(...)). +// +// If not connected (!IsConnected()) SetNextTimestampBound is safe to call and +// does nothing. +// All the sub-classes that define Send should implement it to be safe to to +// call if not connected and do nothing in such case. class OutputShardAccessBase { public: OutputShardAccessBase(const CalculatorContext& cc, OutputStreamShard* output) From a6c1bb6324c61f5988c9bcb63f61f402b3c18b64 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Sat, 22 Apr 2023 00:26:56 -0700 Subject: [PATCH 062/753] Internal change PiperOrigin-RevId: 526235882 --- mediapipe/model_maker/python/core/utils/BUILD | 7 + .../python/core/utils/loss_functions.py | 217 +++++++++++++++++- .../python/core/utils/loss_functions_test.py | 183 ++++++++++++++- 3 files changed, 403 insertions(+), 4 deletions(-) diff --git a/mediapipe/model_maker/python/core/utils/BUILD b/mediapipe/model_maker/python/core/utils/BUILD index 43c3d42f9..907706b3a 100644 --- a/mediapipe/model_maker/python/core/utils/BUILD +++ b/mediapipe/model_maker/python/core/utils/BUILD @@ -67,11 +67,18 @@ py_library( name = "loss_functions", srcs = ["loss_functions.py"], srcs_version = "PY3", + deps = [ + ":file_util", + ":model_util", + ], ) py_test( name = "loss_functions_test", srcs = ["loss_functions_test.py"], + tags = [ + "requires-net:external", + ], deps = [":loss_functions"], ) diff --git a/mediapipe/model_maker/python/core/utils/loss_functions.py b/mediapipe/model_maker/python/core/utils/loss_functions.py index 5b0aa32bf..e05cf6f59 100644 --- a/mediapipe/model_maker/python/core/utils/loss_functions.py +++ b/mediapipe/model_maker/python/core/utils/loss_functions.py @@ -13,10 +13,21 @@ # limitations under the License. """Loss function utility library.""" -from typing import Optional, Sequence +import abc +from typing import Mapping, Sequence +import dataclasses +from typing import Optional +import numpy as np import tensorflow as tf +from mediapipe.model_maker.python.core.utils import file_util +from mediapipe.model_maker.python.core.utils import model_util +from official.modeling import tf_utils + + +_VGG_IMAGENET_PERCEPTUAL_MODEL_URL = 'https://storage.googleapis.com/mediapipe-assets/vgg_feature_extractor.tar.gz' + class FocalLoss(tf.keras.losses.Loss): """Implementation of focal loss (https://arxiv.org/pdf/1708.02002.pdf). @@ -45,7 +56,6 @@ class FocalLoss(tf.keras.losses.Loss): ```python model.compile(optimizer='sgd', loss=FocalLoss(gamma)) ``` - """ def __init__(self, gamma, class_weight: Optional[Sequence[float]] = None): @@ -103,3 +113,206 @@ class FocalLoss(tf.keras.losses.Loss): # By default, this function uses "sum_over_batch_size" reduction for the # loss per batch. return tf.reduce_sum(losses) / batch_size + + +@dataclasses.dataclass +class PerceptualLossWeight: + """The weight for each perceptual loss. + + Attributes: + l1: weight for L1 loss. + content: weight for content loss. + style: weight for style loss. + """ + + l1: float = 1.0 + content: float = 1.0 + style: float = 1.0 + + +class PerceptualLoss(tf.keras.Model, metaclass=abc.ABCMeta): + """Base class for perceptual loss model.""" + + def __init__( + self, + feature_weight: Optional[Sequence[float]] = None, + loss_weight: Optional[PerceptualLossWeight] = None, + ): + """Instantiates perceptual loss. + + Args: + feature_weight: The weight coeffcients of multiple model extracted + features used for calculating the perceptual loss. + loss_weight: The weight coefficients between `style_loss` and + `content_loss`. + """ + super().__init__() + self._loss_op = lambda x, y: tf.math.reduce_mean(tf.abs(x - y)) + self._loss_style = tf.constant(0.0) + self._loss_content = tf.constant(0.0) + self._feature_weight = feature_weight + self._loss_weight = loss_weight + + def __call__( + self, + img1: tf.Tensor, + img2: tf.Tensor, + ) -> Mapping[str, tf.Tensor]: + """Computes perceptual loss between two images. + + Args: + img1: First batch of images. The pixel values should be normalized to [-1, + 1]. + img2: Second batch of images. The pixel values should be normalized to + [-1, 1]. + + Returns: + A mapping between loss name and loss tensors. + """ + x_features = self._compute_features(img1) + y_features = self._compute_features(img2) + + if self._loss_weight is None: + self._loss_weight = PerceptualLossWeight() + + # If the _feature_weight is not initialized, then initialize it as a list of + # all the element equals to 1.0. + if self._feature_weight is None: + self._feature_weight = [1.0] * len(x_features) + + # If the length of _feature_weight smallert than the length of the feature, + # raise a ValueError. Otherwise, only use the first len(x_features) weight + # for computing the loss. + if len(self._feature_weight) < len(x_features): + raise ValueError( + f'Input feature weight length {len(self._feature_weight)} is smaller' + f' than feature length {len(x_features)}' + ) + + if self._loss_weight.style > 0.0: + self._loss_style = tf_utils.safe_mean( + self._loss_weight.style + * self._get_style_loss(x_feats=x_features, y_feats=y_features) + ) + if self._loss_weight.content > 0.0: + self._loss_content = tf_utils.safe_mean( + self._loss_weight.content + * self._get_content_loss(x_feats=x_features, y_feats=y_features) + ) + + return {'style_loss': self._loss_style, 'content_loss': self._loss_content} + + @abc.abstractmethod + def _compute_features(self, img: tf.Tensor) -> Sequence[tf.Tensor]: + """Computes features from the given image tensor. + + Args: + img: Image tensor. + + Returns: + A list of multi-scale feature maps. + """ + + def _get_content_loss( + self, x_feats: Sequence[tf.Tensor], y_feats: Sequence[tf.Tensor] + ) -> tf.Tensor: + """Gets weighted multi-scale content loss. + + Args: + x_feats: Reconstructed face image. + y_feats: Target face image. + + Returns: + A scalar tensor for the content loss. + """ + content_losses = [] + for coef, x_feat, y_feat in zip(self._feature_weight, x_feats, y_feats): + content_loss = self._loss_op(x_feat, y_feat) * coef + content_losses.append(content_loss) + return tf.math.reduce_sum(content_losses) + + def _get_style_loss( + self, x_feats: Sequence[tf.Tensor], y_feats: Sequence[tf.Tensor] + ) -> tf.Tensor: + """Gets weighted multi-scale style loss. + + Args: + x_feats: Reconstructed face image. + y_feats: Target face image. + + Returns: + A scalar tensor for the style loss. + """ + style_losses = [] + i = 0 + for coef, x_feat, y_feat in zip(self._feature_weight, x_feats, y_feats): + x_feat_g = _compute_gram_matrix(x_feat) + y_feat_g = _compute_gram_matrix(y_feat) + style_loss = self._loss_op(x_feat_g, y_feat_g) * coef + style_losses.append(style_loss) + i = i + 1 + + return tf.math.reduce_sum(style_loss) + + +class VGGPerceptualLoss(PerceptualLoss): + """Perceptual loss based on VGG19 pretrained on the ImageNet dataset. + + Reference: + - [Perceptual Losses for Real-Time Style Transfer and Super-Resolution]( + https://arxiv.org/abs/1603.08155) (ECCV 2016) + + Perceptual loss measures high-level perceptual and semantic differences + between images. + """ + + def __init__( + self, + loss_weight: Optional[PerceptualLossWeight] = None, + ): + """Initializes image quality loss essentials. + + Args: + loss_weight: Loss weight coefficients. + """ + super().__init__( + feature_weight=np.array([0.1, 0.1, 1.0, 1.0, 1.0]), + loss_weight=loss_weight, + ) + + rgb_mean = tf.constant([0.485, 0.456, 0.406]) + rgb_std = tf.constant([0.229, 0.224, 0.225]) + + self._rgb_mean = tf.reshape(rgb_mean, (1, 1, 1, 3)) + self._rgb_std = tf.reshape(rgb_std, (1, 1, 1, 3)) + + model_path = file_util.DownloadedFiles( + 'vgg_feature_extractor', + _VGG_IMAGENET_PERCEPTUAL_MODEL_URL, + is_folder=True, + ) + self._vgg19 = model_util.load_keras_model(model_path.get_path()) + + def _compute_features(self, img: tf.Tensor) -> Sequence[tf.Tensor]: + """Computes VGG19 features.""" + img = (img + 1) / 2.0 + norm_img = (img - self._rgb_mean) / self._rgb_std + # no grad, as it only serves as a frozen feature extractor. + return self._vgg19(norm_img) + + +def _compute_gram_matrix(feature: tf.Tensor) -> tf.Tensor: + """Computes gram matrix for the feature map. + + Args: + feature: [B, H, W, C] feature map. + + Returns: + [B, C, C] gram matrix. + """ + h, w, c = feature.shape[1:].as_list() + feat_reshaped = tf.reshape(feature, shape=(-1, h * w, c)) + feat_gram = tf.matmul( + tf.transpose(feat_reshaped, perm=[0, 2, 1]), feat_reshaped + ) + return feat_gram / (c * h * w) diff --git a/mediapipe/model_maker/python/core/utils/loss_functions_test.py b/mediapipe/model_maker/python/core/utils/loss_functions_test.py index 716c329ef..a3d9a8aa7 100644 --- a/mediapipe/model_maker/python/core/utils/loss_functions_test.py +++ b/mediapipe/model_maker/python/core/utils/loss_functions_test.py @@ -13,7 +13,9 @@ # limitations under the License. import math -from typing import Optional +import tempfile +from typing import Dict, Optional, Sequence +from unittest import mock as unittest_mock from absl.testing import parameterized import tensorflow as tf @@ -21,7 +23,7 @@ import tensorflow as tf from mediapipe.model_maker.python.core.utils import loss_functions -class LossFunctionsTest(tf.test.TestCase, parameterized.TestCase): +class FocalLossTest(tf.test.TestCase, parameterized.TestCase): @parameterized.named_parameters( dict(testcase_name='no_sample_weight', sample_weight=None), @@ -99,5 +101,182 @@ class LossFunctionsTest(tf.test.TestCase, parameterized.TestCase): self.assertNear(loss, expected_loss, 1e-4) +class MockPerceptualLoss(loss_functions.PerceptualLoss): + """A mock class with implementation of abstract methods for testing.""" + + def __init__( + self, + use_mock_loss_op: bool = False, + feature_weight: Optional[Sequence[float]] = None, + loss_weight: Optional[loss_functions.PerceptualLossWeight] = None, + ): + super().__init__(feature_weight=feature_weight, loss_weight=loss_weight) + if use_mock_loss_op: + self._loss_op = lambda x, y: tf.math.reduce_mean(x - y) + + def _compute_features(self, img: tf.Tensor) -> Sequence[tf.Tensor]: + return [tf.random.normal(shape=(1, 8, 8, 3))] * 5 + + +class PerceptualLossTest(tf.test.TestCase, parameterized.TestCase): + + def setUp(self): + super().setUp() + self._img1 = tf.fill(dims=(8, 8), value=0.2) + self._img2 = tf.fill(dims=(8, 8), value=0.8) + + def test_invalid_feature_weight_raise_value_error(self): + with self.assertRaisesRegex( + ValueError, + 'Input feature weight length 2 is smaller than feature length 5', + ): + MockPerceptualLoss(feature_weight=[1.0, 2.0])( + img1=self._img1, img2=self._img2 + ) + + @parameterized.named_parameters( + dict( + testcase_name='default_loss_weight_and_loss_op', + use_mock_loss_op=False, + feature_weight=None, + loss_weight=None, + loss_values={ + 'style_loss': 0.032839, + 'content_loss': 5.639870, + }, + ), + dict( + testcase_name='style_loss_weight_is_0_default_loss_op', + use_mock_loss_op=False, + feature_weight=None, + loss_weight=loss_functions.PerceptualLossWeight(style=0), + loss_values={ + 'style_loss': 0, + 'content_loss': 5.639870, + }, + ), + dict( + testcase_name='content_loss_weight_is_0_default_loss_op', + use_mock_loss_op=False, + feature_weight=None, + loss_weight=loss_functions.PerceptualLossWeight(content=0), + loss_values={ + 'style_loss': 0.032839, + 'content_loss': 0, + }, + ), + dict( + testcase_name='customized_loss_weight_default_loss_op', + use_mock_loss_op=False, + feature_weight=None, + loss_weight=loss_functions.PerceptualLossWeight( + style=1.0, content=2.0 + ), + loss_values={'style_loss': 0.032839, 'content_loss': 11.279739}, + ), + dict( + testcase_name=( + 'customized_feature_weight_and_loss_weight_default_loss_op' + ), + use_mock_loss_op=False, + feature_weight=[1.0, 2.0, 3.0, 4.0, 5.0], + loss_weight=loss_functions.PerceptualLossWeight( + style=1.0, content=2.0 + ), + loss_values={'style_loss': 0.164193, 'content_loss': 33.839218}, + ), + dict( + testcase_name='no_loss_change_if_extra_feature_weight_provided', + use_mock_loss_op=False, + feature_weight=[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0], + loss_weight=loss_functions.PerceptualLossWeight( + style=1.0, content=2.0 + ), + loss_values={ + 'style_loss': 0.164193, + 'content_loss': 33.839218, + }, + ), + dict( + testcase_name='customized_loss_weight_custom_loss_op', + use_mock_loss_op=True, + feature_weight=None, + loss_weight=loss_functions.PerceptualLossWeight( + style=1.0, content=2.0 + ), + loss_values={'style_loss': 0.000395, 'content_loss': -1.533469}, + ), + ) + def test_weighted_perceptul_loss( + self, + use_mock_loss_op: bool, + feature_weight: Sequence[float], + loss_weight: loss_functions.PerceptualLossWeight, + loss_values: Dict[str, float], + ): + perceptual_loss = MockPerceptualLoss( + use_mock_loss_op=use_mock_loss_op, + feature_weight=feature_weight, + loss_weight=loss_weight, + ) + loss = perceptual_loss(img1=self._img1, img2=self._img2) + self.assertEqual(list(loss.keys()), ['style_loss', 'content_loss']) + self.assertNear(loss['style_loss'], loss_values['style_loss'], 1e-4) + self.assertNear(loss['content_loss'], loss_values['content_loss'], 1e-4) + + +class VGGPerceptualLossTest(tf.test.TestCase, parameterized.TestCase): + + def setUp(self): + super().setUp() + # Mock tempfile.gettempdir() to be unique for each test to avoid race + # condition when downloading model since these tests may run in parallel. + mock_gettempdir = unittest_mock.patch.object( + tempfile, + 'gettempdir', + return_value=self.create_tempdir(), + autospec=True, + ) + self.mock_gettempdir = mock_gettempdir.start() + self.addCleanup(mock_gettempdir.stop) + self._img1 = tf.fill(dims=(1, 256, 256, 3), value=0.1) + self._img2 = tf.fill(dims=(1, 256, 256, 3), value=0.9) + + @parameterized.named_parameters( + dict( + testcase_name='default_loss_weight', + loss_weight=None, + loss_values={ + 'style_loss': 5.8363257e-06, + 'content_loss': 1.7016045, + }, + ), + dict( + testcase_name='customized_loss_weight', + loss_weight=loss_functions.PerceptualLossWeight( + style=10.0, content=20.0 + ), + loss_values={ + 'style_loss': 5.8363257e-05, + 'content_loss': 34.03208, + }, + ), + ) + def test_vgg_perceptual_loss(self, loss_weight, loss_values): + vgg_loss = loss_functions.VGGPerceptualLoss(loss_weight=loss_weight) + loss = vgg_loss(img1=self._img1, img2=self._img2) + self.assertEqual(list(loss.keys()), ['style_loss', 'content_loss']) + self.assertNear( + loss['style_loss'], + loss_values['style_loss'], + loss_values['style_loss'] / 1e5, + ) + self.assertNear( + loss['content_loss'], + loss_values['content_loss'], + loss_values['content_loss'] / 1e5, + ) + + if __name__ == '__main__': tf.test.main() From abded49e5be7165566391567eaec0c4d024ed856 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Sat, 22 Apr 2023 10:50:10 -0700 Subject: [PATCH 063/753] Internal change PiperOrigin-RevId: 526300079 --- .../python/core/utils/loss_functions.py | 47 ++++++++++++++++++- .../python/core/utils/loss_functions_test.py | 46 ++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/mediapipe/model_maker/python/core/utils/loss_functions.py b/mediapipe/model_maker/python/core/utils/loss_functions.py index e05cf6f59..7e7c4c5ea 100644 --- a/mediapipe/model_maker/python/core/utils/loss_functions.py +++ b/mediapipe/model_maker/python/core/utils/loss_functions.py @@ -16,7 +16,7 @@ import abc from typing import Mapping, Sequence import dataclasses -from typing import Optional +from typing import Any, Optional import numpy as np import tensorflow as tf @@ -130,6 +130,51 @@ class PerceptualLossWeight: style: float = 1.0 +class ImagePerceptualQualityLoss(tf.keras.losses.Loss): + """Image perceptual quality loss. + + It obtains a weighted loss between the VGGPerceptualLoss and L1 loss. + """ + + def __init__( + self, + loss_weight: Optional[PerceptualLossWeight] = None, + reduction: tf.keras.losses.Reduction = tf.keras.losses.Reduction.NONE, + ): + """Initializes ImagePerceptualQualityLoss.""" + self._loss_weight = loss_weight + self._losses = {} + self._reduction = reduction + + def _l1_loss( + self, + reduction: tf.keras.losses.Reduction = tf.keras.losses.Reduction.NONE, + ) -> Any: + """Calculates L1 loss.""" + return tf.keras.losses.MeanAbsoluteError(reduction) + + def __call__( + self, + img1: tf.Tensor, + img2: tf.Tensor, + ) -> tf.Tensor: + """Computes image perceptual quality loss.""" + loss_value = [] + if self._loss_weight is None: + self._loss_weight = PerceptualLossWeight() + + if self._loss_weight.content > 0 or self._loss_weight.style > 0: + vgg_loss = VGGPerceptualLoss(self._loss_weight)(img1, img2) + vgg_loss_value = tf.math.add_n(vgg_loss.values()) + loss_value.append(vgg_loss_value) + if self._loss_weight.l1 > 0: + l1_loss = self._l1_loss(reduction=self._reduction)(img1, img2) + l1_loss_value = tf_utils.safe_mean(l1_loss * self._loss_weight.l1) + loss_value.append(l1_loss_value) + total_loss = tf.math.add_n(loss_value) + return total_loss + + class PerceptualLoss(tf.keras.Model, metaclass=abc.ABCMeta): """Base class for perceptual loss model.""" diff --git a/mediapipe/model_maker/python/core/utils/loss_functions_test.py b/mediapipe/model_maker/python/core/utils/loss_functions_test.py index a3d9a8aa7..1c921779f 100644 --- a/mediapipe/model_maker/python/core/utils/loss_functions_test.py +++ b/mediapipe/model_maker/python/core/utils/loss_functions_test.py @@ -278,5 +278,51 @@ class VGGPerceptualLossTest(tf.test.TestCase, parameterized.TestCase): ) +class ImagePerceptualQualityLossTest(tf.test.TestCase, parameterized.TestCase): + + def setUp(self): + super().setUp() + # Mock tempfile.gettempdir() to be unique for each test to avoid race + # condition when downloading model since these tests may run in parallel. + mock_gettempdir = unittest_mock.patch.object( + tempfile, + 'gettempdir', + return_value=self.create_tempdir(), + autospec=True, + ) + self.mock_gettempdir = mock_gettempdir.start() + self.addCleanup(mock_gettempdir.stop) + self._img1 = tf.fill(dims=(1, 256, 256, 3), value=0.1) + self._img2 = tf.fill(dims=(1, 256, 256, 3), value=0.9) + + @parameterized.named_parameters( + dict( + testcase_name='default_loss_weight', + loss_weight=None, + loss_value=2.501612, + ), + dict( + testcase_name='customized_loss_weight_zero_l1', + loss_weight=loss_functions.PerceptualLossWeight( + l1=0.0, style=10.0, content=20.0 + ), + loss_value=34.032139, + ), + dict( + testcase_name='customized_loss_weight_nonzero_l1', + loss_weight=loss_functions.PerceptualLossWeight( + l1=10.0, style=10.0, content=20.0 + ), + loss_value=42.032139, + ), + ) + def test_image_perceptual_quality_loss(self, loss_weight, loss_value): + image_quality_loss = loss_functions.ImagePerceptualQualityLoss( + loss_weight=loss_weight + ) + loss = image_quality_loss(img1=self._img1, img2=self._img2) + self.assertNear(loss, loss_value, 1e-4) + + if __name__ == '__main__': tf.test.main() From 35cf8c35f2a5e4ef95318b3e7cff0117ee1f4c6f Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Mon, 24 Apr 2023 08:59:16 -0700 Subject: [PATCH 064/753] Internal change PiperOrigin-RevId: 526658482 --- .../audio/spectrogram_calculator.cc | 6 +- mediapipe/tasks/cc/core/BUILD | 6 +- .../tasks/cc/core/external_file_handler.cc | 29 +----- mediapipe/tasks/cc/text/utils/BUILD | 1 + mediapipe/tasks/cc/text/utils/vocab_utils.cc | 13 ++- mediapipe/util/BUILD | 5 + mediapipe/util/resource_util_windows.cc | 91 +++++++++++++++++++ 7 files changed, 113 insertions(+), 38 deletions(-) create mode 100644 mediapipe/util/resource_util_windows.cc diff --git a/mediapipe/calculators/audio/spectrogram_calculator.cc b/mediapipe/calculators/audio/spectrogram_calculator.cc index 939e721ab..fbdbbab0a 100644 --- a/mediapipe/calculators/audio/spectrogram_calculator.cc +++ b/mediapipe/calculators/audio/spectrogram_calculator.cc @@ -433,9 +433,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, diff --git a/mediapipe/tasks/cc/core/BUILD b/mediapipe/tasks/cc/core/BUILD index 95cfdd15e..6f1daa580 100644 --- a/mediapipe/tasks/cc/core/BUILD +++ b/mediapipe/tasks/cc/core/BUILD @@ -61,15 +61,13 @@ cc_library( "//mediapipe/framework/port:status", "//mediapipe/tasks/cc:common", "//mediapipe/tasks/cc/core/proto:external_file_cc_proto", + "//mediapipe/util:resource_util", "@com_google_absl//absl/memory", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", - ] + select({ - "//mediapipe:windows": ["@bazel_tools//tools/cpp/runfiles"], - "//conditions:default": [], - }), + ], ) cc_library( diff --git a/mediapipe/tasks/cc/core/external_file_handler.cc b/mediapipe/tasks/cc/core/external_file_handler.cc index a56f03d55..27b579f97 100644 --- a/mediapipe/tasks/cc/core/external_file_handler.cc +++ b/mediapipe/tasks/cc/core/external_file_handler.cc @@ -43,10 +43,7 @@ limitations under the License. #include "mediapipe/framework/port/status_macros.h" #include "mediapipe/tasks/cc/common.h" #include "mediapipe/tasks/cc/core/proto/external_file.pb.h" - -#ifdef _WIN32 -#include "tools/cpp/runfiles/runfiles.h" -#endif // _WIN32 +#include "mediapipe/util/resource_util.h" namespace mediapipe { namespace tasks { @@ -96,30 +93,6 @@ ExternalFileHandler::CreateFromExternalFile( return handler; } -absl::StatusOr PathToResourceAsFile(std::string path) { -#ifndef _WIN32 - return path; -#else - std::string qualified_path = path; - if (absl::StartsWith(qualified_path, "./")) { - qualified_path = "mediapipe" + qualified_path.substr(1); - } else if (path[0] != '/') { - qualified_path = "mediapipe/" + qualified_path; - } - - std::string error; - // TODO: We should ideally use `CreateForTests` when this is - // accessed from unit tests. - std::unique_ptr<::bazel::tools::cpp::runfiles::Runfiles> runfiles( - ::bazel::tools::cpp::runfiles::Runfiles::Create("", &error)); - if (!runfiles) { - // Return the original path when Runfiles is not available (e.g. for Python) - return path; - } - return runfiles->Rlocation(qualified_path); -#endif // _WIN32 -} - absl::Status ExternalFileHandler::MapExternalFile() { if (!external_file_.file_content().empty()) { return absl::OkStatus(); diff --git a/mediapipe/tasks/cc/text/utils/BUILD b/mediapipe/tasks/cc/text/utils/BUILD index 15af7683b..cd8c7512c 100644 --- a/mediapipe/tasks/cc/text/utils/BUILD +++ b/mediapipe/tasks/cc/text/utils/BUILD @@ -25,6 +25,7 @@ cc_library( "vocab_utils.h", ], deps = [ + "//mediapipe/util:resource_util", "@com_google_absl//absl/container:node_hash_map", "@com_google_absl//absl/strings", ], diff --git a/mediapipe/tasks/cc/text/utils/vocab_utils.cc b/mediapipe/tasks/cc/text/utils/vocab_utils.cc index 068272f7f..a006da6d1 100644 --- a/mediapipe/tasks/cc/text/utils/vocab_utils.cc +++ b/mediapipe/tasks/cc/text/utils/vocab_utils.cc @@ -18,6 +18,7 @@ limitations under the License. #include #include "absl/strings/str_split.h" +#include "mediapipe/util/resource_util.h" namespace mediapipe { namespace tasks { @@ -34,7 +35,11 @@ void ReadIStreamLineByLine( std::string str; while (std::getline(*istream, str)) { if (!str.empty()) { - line_processor(str); + if (str.back() == '\r') { // Remove \r on Windows + line_processor(str.substr(0, str.length() - 1)); + } else { + line_processor(str); + } } } } @@ -64,7 +69,8 @@ std::vector ReadIStreamByLine(std::istream* istream) { std::vector LoadVocabFromFile(const std::string& path_to_vocab) { std::vector vocab_from_file; - std::ifstream in(path_to_vocab.c_str()); + std::string file_name = *PathToResourceAsFile(path_to_vocab); + std::ifstream in(file_name.c_str()); return ReadIStreamByLine(&in); } @@ -79,7 +85,8 @@ std::vector LoadVocabFromBuffer(const char* vocab_buffer_data, absl::node_hash_map LoadVocabAndIndexFromFile( const std::string& path_to_vocab) { absl::node_hash_map vocab_index_map; - std::ifstream in(path_to_vocab.c_str()); + std::string file_name = *PathToResourceAsFile(path_to_vocab); + std::ifstream in(file_name.c_str()); return ReadIStreamLineSplits(&in); } diff --git a/mediapipe/util/BUILD b/mediapipe/util/BUILD index cd82a850a..b0b7f3468 100644 --- a/mediapipe/util/BUILD +++ b/mediapipe/util/BUILD @@ -194,6 +194,7 @@ cc_library( "//mediapipe/framework:android_no_jni": ["resource_util_loonix.cc"], "//mediapipe:ios": ["resource_util_apple.cc"], "//mediapipe:macos": ["resource_util_default.cc"], + "//mediapipe:windows": ["resource_util_windows.cc"], }), hdrs = [ "resource_util.h", @@ -232,6 +233,10 @@ cc_library( "//mediapipe:macos": [ "@com_google_absl//absl/flags:flag", ], + "//mediapipe:windows": [ + "@bazel_tools//tools/cpp/runfiles", + "@com_google_absl//absl/flags:flag", + ], }), ) diff --git a/mediapipe/util/resource_util_windows.cc b/mediapipe/util/resource_util_windows.cc new file mode 100644 index 000000000..34806da49 --- /dev/null +++ b/mediapipe/util/resource_util_windows.cc @@ -0,0 +1,91 @@ +// Copyright 2019 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 + +#include "absl/flags/flag.h" +#include "mediapipe/framework/deps/file_path.h" +#include "mediapipe/framework/port/file_helpers.h" +#include "mediapipe/framework/port/singleton.h" +#include "mediapipe/framework/port/statusor.h" +#include "tools/cpp/runfiles/runfiles.h" + +ABSL_FLAG( + std::string, resource_root_dir, "", + "The absolute path to the resource directory." + "If specified, resource_root_dir will be prepended to the original path."); + +namespace mediapipe { + +using mediapipe::file::GetContents; +using mediapipe::file::JoinPath; + +namespace { + +class RunfilesHolder { + public: + // TODO: We should ideally use `CreateForTests` when this is + // accessed from unit tests. + RunfilesHolder() + : runfiles_( + ::bazel::tools::cpp::runfiles::Runfiles::Create("", nullptr)) {} + + std::string Rlocation(const std::string& path) { + if (!runfiles_) { + // Return the original path when Runfiles is not available (e.g. for + // Python) + return JoinPath(absl::GetFlag(FLAGS_resource_root_dir), path); + } + return runfiles_->Rlocation(path); + } + + private: + std::unique_ptr<::bazel::tools::cpp::runfiles::Runfiles> runfiles_; +}; + +} // namespace + +namespace internal { + +std::string PathToResourceAsFileInternal(const std::string& path) { + return Singleton::get()->Rlocation(path); +} + +absl::Status DefaultGetResourceContents(const std::string& path, + std::string* output, + bool read_as_binary) { + std::string resource_path = PathToResourceAsFileInternal(path); + return GetContents(path, output, read_as_binary); +} + +} // namespace internal + +absl::StatusOr PathToResourceAsFile(const std::string& path) { + std::string qualified_path = path; + if (absl::StartsWith(qualified_path, "./")) { + qualified_path = "mediapipe" + qualified_path.substr(1); + } else if (path[0] != '/') { + qualified_path = "mediapipe/" + qualified_path; + } + + // Try to load the file from bazel-bin. If it does not exist, fall back to the + // resource folder. + auto bazel_path = internal::PathToResourceAsFileInternal(qualified_path); + if (file::Exists(bazel_path).ok()) { + return bazel_path; + } + return JoinPath(absl::GetFlag(FLAGS_resource_root_dir), path); +} + +} // namespace mediapipe From 6773188e2670122cb42ecfa07b83c6e15ee29eb0 Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Mon, 24 Apr 2023 09:31:48 -0700 Subject: [PATCH 065/753] Make FaceLandmarksConnections to be a public class. PiperOrigin-RevId: 526667505 --- .../tasks/vision/facelandmarker/FaceLandmarksConnections.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarksConnections.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarksConnections.java index f320cb07a..05a21cb1f 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarksConnections.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarksConnections.java @@ -23,7 +23,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; /** Face landmarks connection constants. */ -final class FaceLandmarksConnections { +public final class FaceLandmarksConnections { /** Value class representing face landmarks connection. */ @AutoValue From 61854dc6a3b7b0c8cdb21b459691362da3edb52a Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Mon, 24 Apr 2023 09:50:19 -0700 Subject: [PATCH 066/753] Create Pose Detector Web API PiperOrigin-RevId: 526672533 --- mediapipe/tasks/web/vision/BUILD | 1 + mediapipe/tasks/web/vision/README.md | 17 + mediapipe/tasks/web/vision/index.ts | 5 +- .../tasks/web/vision/pose_landmarker/BUILD | 73 +++ .../vision/pose_landmarker/pose_landmarker.ts | 434 ++++++++++++++++++ .../pose_landmarker_options.d.ts | 47 ++ .../pose_landmarker_result.d.ts | 38 ++ .../pose_landmarker/pose_landmarker_test.ts | 264 +++++++++++ mediapipe/tasks/web/vision/types.ts | 1 + 9 files changed, 879 insertions(+), 1 deletion(-) create mode 100644 mediapipe/tasks/web/vision/pose_landmarker/BUILD create mode 100644 mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts create mode 100644 mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.d.ts create mode 100644 mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts create mode 100644 mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts diff --git a/mediapipe/tasks/web/vision/BUILD b/mediapipe/tasks/web/vision/BUILD index fa1ed32da..503db3252 100644 --- a/mediapipe/tasks/web/vision/BUILD +++ b/mediapipe/tasks/web/vision/BUILD @@ -31,6 +31,7 @@ VISION_LIBS = [ "//mediapipe/tasks/web/vision/image_segmenter", "//mediapipe/tasks/web/vision/interactive_segmenter", "//mediapipe/tasks/web/vision/object_detector", + "//mediapipe/tasks/web/vision/pose_landmarker", ] mediapipe_ts_library( diff --git a/mediapipe/tasks/web/vision/README.md b/mediapipe/tasks/web/vision/README.md index 6423807fc..a9e4e7147 100644 --- a/mediapipe/tasks/web/vision/README.md +++ b/mediapipe/tasks/web/vision/README.md @@ -160,3 +160,20 @@ const detections = objectDetector.detect(image); For more information, refer to the [Object Detector](https://developers.google.com/mediapipe/solutions/vision/object_detector/web_js) documentation. + +## Pose Landmark Detection + +The MediaPipe Pose Landmarker task lets you detect the landmarks of body poses +in an image. You can use this Task to localize key points of a pose and render +visual effects over the body. + +``` +const vision = await FilesetResolver.forVisionTasks( + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm" +); +const poseLandmarker = await PoseLandmarker.createFromModelPath(vision, + "model.task" +); +const image = document.getElementById("image") as HTMLImageElement; +const landmarks = poseLandmarker.detect(image); +``` diff --git a/mediapipe/tasks/web/vision/index.ts b/mediapipe/tasks/web/vision/index.ts index c4adab7e6..6a3de450e 100644 --- a/mediapipe/tasks/web/vision/index.ts +++ b/mediapipe/tasks/web/vision/index.ts @@ -27,6 +27,7 @@ import {ImageEmbedder as ImageEmbedderImpl} from '../../../tasks/web/vision/imag import {ImageSegmenter as ImageSegementerImpl} from '../../../tasks/web/vision/image_segmenter/image_segmenter'; import {InteractiveSegmenter as InteractiveSegmenterImpl} from '../../../tasks/web/vision/interactive_segmenter/interactive_segmenter'; import {ObjectDetector as ObjectDetectorImpl} from '../../../tasks/web/vision/object_detector/object_detector'; +import {PoseLandmarker as PoseLandmarkerImpl} from '../../../tasks/web/vision/pose_landmarker/pose_landmarker'; // Declare the variables locally so that Rollup in OSS includes them explicitly // as exports. @@ -44,6 +45,7 @@ const ImageEmbedder = ImageEmbedderImpl; const ImageSegmenter = ImageSegementerImpl; const InteractiveSegmenter = InteractiveSegmenterImpl; const ObjectDetector = ObjectDetectorImpl; +const PoseLandmarker = PoseLandmarkerImpl; export { DrawingUtils, @@ -59,5 +61,6 @@ export { ImageEmbedder, ImageSegmenter, InteractiveSegmenter, - ObjectDetector + ObjectDetector, + PoseLandmarker }; diff --git a/mediapipe/tasks/web/vision/pose_landmarker/BUILD b/mediapipe/tasks/web/vision/pose_landmarker/BUILD new file mode 100644 index 000000000..932fce8bc --- /dev/null +++ b/mediapipe/tasks/web/vision/pose_landmarker/BUILD @@ -0,0 +1,73 @@ +# This contains the MediaPipe Pose Landmarker Task. +# +# This task takes video frames and outputs synchronized frames along with +# the detection results for one or more pose categories, using Pose Landmarker. + +load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_declaration", "mediapipe_ts_library") +load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test") + +package(default_visibility = ["//mediapipe/tasks:internal"]) + +licenses(["notice"]) + +mediapipe_ts_library( + name = "pose_landmarker", + srcs = ["pose_landmarker.ts"], + visibility = ["//visibility:public"], + deps = [ + ":pose_landmarker_types", + "//mediapipe/framework:calculator_jspb_proto", + "//mediapipe/framework:calculator_options_jspb_proto", + "//mediapipe/framework/formats:landmark_jspb_proto", + "//mediapipe/tasks/cc/core/proto:base_options_jspb_proto", + "//mediapipe/tasks/cc/vision/pose_detector/proto:pose_detector_graph_options_jspb_proto", + "//mediapipe/tasks/cc/vision/pose_landmarker/proto:pose_landmarker_graph_options_jspb_proto", + "//mediapipe/tasks/cc/vision/pose_landmarker/proto:pose_landmarks_detector_graph_options_jspb_proto", + "//mediapipe/tasks/web/components/containers:category", + "//mediapipe/tasks/web/components/containers:landmark", + "//mediapipe/tasks/web/components/processors:landmark_result", + "//mediapipe/tasks/web/core", + "//mediapipe/tasks/web/vision/core:image_processing_options", + "//mediapipe/tasks/web/vision/core:types", + "//mediapipe/tasks/web/vision/core:vision_task_runner", + "//mediapipe/web/graph_runner:graph_runner_ts", + ], +) + +mediapipe_ts_declaration( + name = "pose_landmarker_types", + srcs = [ + "pose_landmarker_options.d.ts", + "pose_landmarker_result.d.ts", + ], + visibility = ["//visibility:public"], + deps = [ + "//mediapipe/tasks/web/components/containers:category", + "//mediapipe/tasks/web/components/containers:landmark", + "//mediapipe/tasks/web/core", + "//mediapipe/tasks/web/vision/core:vision_task_options", + ], +) + +mediapipe_ts_library( + name = "pose_landmarker_test_lib", + testonly = True, + srcs = [ + "pose_landmarker_test.ts", + ], + deps = [ + ":pose_landmarker", + ":pose_landmarker_types", + "//mediapipe/framework:calculator_jspb_proto", + "//mediapipe/tasks/web/components/processors:landmark_result", + "//mediapipe/tasks/web/core", + "//mediapipe/tasks/web/core:task_runner_test_utils", + "//mediapipe/tasks/web/vision/core:vision_task_runner", + ], +) + +jasmine_node_test( + name = "pose_landmarker_test", + tags = ["nomsan"], + deps = [":pose_landmarker_test_lib"], +) diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts new file mode 100644 index 000000000..a3c0450fe --- /dev/null +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts @@ -0,0 +1,434 @@ +/** + * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; +import {CalculatorOptions} from '../../../../framework/calculator_options_pb'; +import {LandmarkList, NormalizedLandmarkList} from '../../../../framework/formats/landmark_pb'; +import {BaseOptions as BaseOptionsProto} from '../../../../tasks/cc/core/proto/base_options_pb'; +import {PoseDetectorGraphOptions} from '../../../../tasks/cc/vision/pose_detector/proto/pose_detector_graph_options_pb'; +import {PoseLandmarkerGraphOptions} from '../../../../tasks/cc/vision/pose_landmarker/proto/pose_landmarker_graph_options_pb'; +import {PoseLandmarksDetectorGraphOptions} from '../../../../tasks/cc/vision/pose_landmarker/proto/pose_landmarks_detector_graph_options_pb'; +import {convertToLandmarks, convertToWorldLandmarks} from '../../../../tasks/web/components/processors/landmark_result'; +import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; +import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; +import {Connection} from '../../../../tasks/web/vision/core/types'; +import {VisionGraphRunner, VisionTaskRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; +import {ImageSource, WasmModule} from '../../../../web/graph_runner/graph_runner'; +// Placeholder for internal dependency on trusted resource url + +import {PoseLandmarkerOptions} from './pose_landmarker_options'; +import {PoseLandmarkerResult} from './pose_landmarker_result'; + +export * from './pose_landmarker_options'; +export * from './pose_landmarker_result'; +export {ImageSource}; + +// The OSS JS API does not support the builder pattern. +// tslint:disable:jspb-use-builder-pattern + +const IMAGE_STREAM = 'image_in'; +const NORM_RECT_STREAM = 'norm_rect'; +const NORM_LANDMARKS_STREAM = 'normalized_landmarks'; +const WORLD_LANDMARKS_STREAM = 'world_landmarks'; +const AUXILIARY_LANDMARKS_STREAM = 'auxiliary_landmarks'; +const SEGMENTATION_MASK_STREAM = 'segmentation_masks'; +const POSE_LANDMARKER_GRAPH = + 'mediapipe.tasks.vision.pose_landmarker.PoseLandmarkerGraph'; + +const DEFAULT_NUM_POSES = 1; +const DEFAULT_SCORE_THRESHOLD = 0.5; +const DEFAULT_OUTPUT_SEGMANTATION_MASKS = false; + +/** + * A callback that receives the result from the pose detector. The returned + * masks are only valid for the duration of the callback. If asynchronous + * processing is needed, the masks need to be copied before the callback + * returns. + */ +export type PoseLandmarkerCallback = (result: PoseLandmarkerResult) => void; + +/** Performs pose landmarks detection on images. */ +export class PoseLandmarker extends VisionTaskRunner { + private result: PoseLandmarkerResult = { + landmarks: [], + worldLandmarks: [], + auxilaryLandmarks: [] + }; + private outputSegmentationMasks = false; + private readonly options: PoseLandmarkerGraphOptions; + private readonly poseLandmarksDetectorGraphOptions: + PoseLandmarksDetectorGraphOptions; + private readonly poseDetectorGraphOptions: PoseDetectorGraphOptions; + + /** + * An array containing the pairs of pose landmark indices to be rendered with + * connections. + */ + static POSE_CONNECTIONS: Connection[] = [ + {start: 0, end: 1}, {start: 1, end: 2}, {start: 2, end: 3}, + {start: 3, end: 7}, {start: 0, end: 4}, {start: 4, end: 5}, + {start: 5, end: 6}, {start: 6, end: 8}, {start: 9, end: 10}, + {start: 11, end: 12}, {start: 11, end: 13}, {start: 13, end: 15}, + {start: 15, end: 17}, {start: 15, end: 19}, {start: 15, end: 21}, + {start: 17, end: 19}, {start: 12, end: 14}, {start: 14, end: 16}, + {start: 16, end: 18}, {start: 16, end: 20}, {start: 16, end: 22}, + {start: 18, end: 20}, {start: 11, end: 23}, {start: 12, end: 24}, + {start: 23, end: 24}, {start: 23, end: 25}, {start: 24, end: 26}, + {start: 25, end: 27}, {start: 26, end: 28}, {start: 27, end: 29}, + {start: 28, end: 30}, {start: 29, end: 31}, {start: 30, end: 32}, + {start: 27, end: 31}, {start: 28, end: 32} + ]; + + /** + * Initializes the Wasm runtime and creates a new `PoseLandmarker` from the + * provided options. + * @param wasmFileset A configuration object that provides the location of the + * Wasm binary and its loader. + * @param poseLandmarkerOptions The options for the PoseLandmarker. + * Note that either a path to the model asset or a model buffer needs to + * be provided (via `baseOptions`). + */ + static createFromOptions( + wasmFileset: WasmFileset, + poseLandmarkerOptions: PoseLandmarkerOptions): Promise { + return VisionTaskRunner.createVisionInstance( + PoseLandmarker, wasmFileset, poseLandmarkerOptions); + } + + /** + * Initializes the Wasm runtime and creates a new `PoseLandmarker` based on + * the provided model asset buffer. + * @param wasmFileset A configuration object that provides the location of the + * Wasm binary and its loader. + * @param modelAssetBuffer A binary representation of the model. + */ + static createFromModelBuffer( + wasmFileset: WasmFileset, + modelAssetBuffer: Uint8Array): Promise { + return VisionTaskRunner.createVisionInstance( + PoseLandmarker, wasmFileset, {baseOptions: {modelAssetBuffer}}); + } + + /** + * Initializes the Wasm runtime and creates a new `PoseLandmarker` based on + * the path to the model asset. + * @param wasmFileset A configuration object that provides the location of the + * Wasm binary and its loader. + * @param modelAssetPath The path to the model asset. + */ + static createFromModelPath( + wasmFileset: WasmFileset, + modelAssetPath: string): Promise { + return VisionTaskRunner.createVisionInstance( + PoseLandmarker, wasmFileset, {baseOptions: {modelAssetPath}}); + } + + /** @hideconstructor */ + constructor( + wasmModule: WasmModule, + glCanvas?: HTMLCanvasElement|OffscreenCanvas|null) { + super( + new VisionGraphRunner(wasmModule, glCanvas), IMAGE_STREAM, + NORM_RECT_STREAM, /* roiAllowed= */ false); + + this.options = new PoseLandmarkerGraphOptions(); + this.options.setBaseOptions(new BaseOptionsProto()); + this.poseLandmarksDetectorGraphOptions = + new PoseLandmarksDetectorGraphOptions(); + this.options.setPoseLandmarksDetectorGraphOptions( + this.poseLandmarksDetectorGraphOptions); + this.poseDetectorGraphOptions = new PoseDetectorGraphOptions(); + this.options.setPoseDetectorGraphOptions(this.poseDetectorGraphOptions); + + this.initDefaults(); + } + + protected override get baseOptions(): BaseOptionsProto { + return this.options.getBaseOptions()!; + } + + protected override set baseOptions(proto: BaseOptionsProto) { + this.options.setBaseOptions(proto); + } + + /** + * Sets new options for this `PoseLandmarker`. + * + * Calling `setOptions()` with a subset of options only affects those options. + * You can reset an option back to its default value by explicitly setting it + * to `undefined`. + * + * @param options The options for the pose landmarker. + */ + override setOptions(options: PoseLandmarkerOptions): Promise { + // Configure pose detector options. + if ('numPoses' in options) { + this.poseDetectorGraphOptions.setNumPoses( + options.numPoses ?? DEFAULT_NUM_POSES); + } + if ('minPoseDetectionConfidence' in options) { + this.poseDetectorGraphOptions.setMinDetectionConfidence( + options.minPoseDetectionConfidence ?? DEFAULT_SCORE_THRESHOLD); + } + + // Configure pose landmark detector options. + if ('minTrackingConfidence' in options) { + this.options.setMinTrackingConfidence( + options.minTrackingConfidence ?? DEFAULT_SCORE_THRESHOLD); + } + if ('minPosePresenceConfidence' in options) { + this.poseLandmarksDetectorGraphOptions.setMinDetectionConfidence( + options.minPosePresenceConfidence ?? DEFAULT_SCORE_THRESHOLD); + } + + if ('outputSegmentationMasks' in options) { + this.outputSegmentationMasks = + options.outputSegmentationMasks ?? DEFAULT_OUTPUT_SEGMANTATION_MASKS; + } + + return this.applyOptions(options); + } + + /** + * Performs pose detection on the provided single image and waits + * synchronously for the response. Only use this method when the + * PoseLandmarker is created with running mode `image`. + * + * @param image An image to process. + * @param callback The callback that is invoked with the result. The + * lifetime of the returned masks is only guaranteed for the duration of + * the callback. + * @return The detected pose landmarks. + */ + detect(image: ImageSource, callback: PoseLandmarkerCallback): void; + /** + * Performs pose detection on the provided single image and waits + * synchronously for the response. Only use this method when the + * PoseLandmarker is created with running mode `image`. + * + * @param image An image to process. + * @param imageProcessingOptions the `ImageProcessingOptions` specifying how + * to process the input image before running inference. + * @param callback The callback that is invoked with the result. The + * lifetime of the returned masks is only guaranteed for the duration of + * the callback. + * @return The detected pose landmarks. + */ + detect( + image: ImageSource, imageProcessingOptions: ImageProcessingOptions, + callback: PoseLandmarkerCallback): void; + detect( + image: ImageSource, + imageProcessingOptionsOrCallback: ImageProcessingOptions| + PoseLandmarkerCallback, + callback?: PoseLandmarkerCallback): void { + const imageProcessingOptions = + typeof imageProcessingOptionsOrCallback !== 'function' ? + imageProcessingOptionsOrCallback : + {}; + const userCallback = + typeof imageProcessingOptionsOrCallback === 'function' ? + imageProcessingOptionsOrCallback : + callback!; + + this.resetResults(); + this.processImageData(image, imageProcessingOptions); + userCallback(this.result); + } + + /** + * Performs pose detection on the provided video frame and waits + * synchronously for the response. Only use this method when the + * PoseLandmarker is created with running mode `video`. + * + * @param videoFrame A video frame to process. + * @param timestamp The timestamp of the current frame, in ms. + * @param callback The callback that is invoked with the result. The + * lifetime of the returned masks is only guaranteed for the duration of + * the callback. + * @return The detected pose landmarks. + */ + detectForVideo( + videoFrame: ImageSource, timestamp: number, + callback: PoseLandmarkerCallback): void; + /** + * Performs pose detection on the provided video frame and waits + * synchronously for the response. Only use this method when the + * PoseLandmarker is created with running mode `video`. + * + * @param videoFrame A video frame to process. + * @param imageProcessingOptions the `ImageProcessingOptions` specifying how + * to process the input image before running inference. + * @param timestamp The timestamp of the current frame, in ms. + * @param callback The callback that is invoked with the result. The + * lifetime of the returned masks is only guaranteed for the duration of + * the callback. + * @return The detected pose landmarks. + */ + detectForVideo( + videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, + timestamp: number, callback: PoseLandmarkerCallback): void; + detectForVideo( + videoFrame: ImageSource, + timestampOrImageProcessingOptions: number|ImageProcessingOptions, + timestampOrCallback: number|PoseLandmarkerCallback, + callback?: PoseLandmarkerCallback): void { + const imageProcessingOptions = + typeof timestampOrImageProcessingOptions !== 'number' ? + timestampOrImageProcessingOptions : + {}; + const timestamp = typeof timestampOrImageProcessingOptions === 'number' ? + timestampOrImageProcessingOptions : + timestampOrCallback as number; + const userCallback = typeof timestampOrCallback === 'function' ? + timestampOrCallback : + callback!; + this.resetResults(); + this.processVideoData(videoFrame, imageProcessingOptions, timestamp); + userCallback(this.result); + } + + private resetResults(): void { + this.result = {landmarks: [], worldLandmarks: [], auxilaryLandmarks: []}; + if (this.outputSegmentationMasks) { + this.result.segmentationMasks = []; + } + } + + /** Sets the default values for the graph. */ + private initDefaults(): void { + this.poseDetectorGraphOptions.setNumPoses(DEFAULT_NUM_POSES); + this.poseDetectorGraphOptions.setMinDetectionConfidence( + DEFAULT_SCORE_THRESHOLD); + this.poseLandmarksDetectorGraphOptions.setMinDetectionConfidence( + DEFAULT_SCORE_THRESHOLD); + this.options.setMinTrackingConfidence(DEFAULT_SCORE_THRESHOLD); + } + + /** + * Converts raw data into a landmark, and adds it to our landmarks list. + */ + private addJsLandmarks(data: Uint8Array[]): void { + for (const binaryProto of data) { + const poseLandmarksProto = + NormalizedLandmarkList.deserializeBinary(binaryProto); + this.result.landmarks = convertToLandmarks(poseLandmarksProto); + } + } + + /** + * Converts raw data into a world landmark, and adds it to our + * worldLandmarks list. + */ + private adddJsWorldLandmarks(data: Uint8Array[]): void { + for (const binaryProto of data) { + const poseWorldLandmarksProto = + LandmarkList.deserializeBinary(binaryProto); + this.result.worldLandmarks = + convertToWorldLandmarks(poseWorldLandmarksProto); + } + } + + /** + * Converts raw data into a landmark, and adds it to our auxilary + * landmarks list. + */ + private addJsAuxiliaryLandmarks(data: Uint8Array[]): void { + for (const binaryProto of data) { + const auxiliaryLandmarksProto = + NormalizedLandmarkList.deserializeBinary(binaryProto); + this.result.auxilaryLandmarks = + convertToLandmarks(auxiliaryLandmarksProto); + } + } + + /** Updates the MediaPipe graph configuration. */ + protected override refreshGraph(): void { + const graphConfig = new CalculatorGraphConfig(); + graphConfig.addInputStream(IMAGE_STREAM); + graphConfig.addInputStream(NORM_RECT_STREAM); + graphConfig.addOutputStream(NORM_LANDMARKS_STREAM); + graphConfig.addOutputStream(WORLD_LANDMARKS_STREAM); + graphConfig.addOutputStream(AUXILIARY_LANDMARKS_STREAM); + graphConfig.addOutputStream(SEGMENTATION_MASK_STREAM); + + const calculatorOptions = new CalculatorOptions(); + calculatorOptions.setExtension( + PoseLandmarkerGraphOptions.ext, this.options); + + const landmarkerNode = new CalculatorGraphConfig.Node(); + landmarkerNode.setCalculator(POSE_LANDMARKER_GRAPH); + landmarkerNode.addInputStream('IMAGE:' + IMAGE_STREAM); + landmarkerNode.addInputStream('NORM_RECT:' + NORM_RECT_STREAM); + landmarkerNode.addOutputStream('NORM_LANDMARKS:' + NORM_LANDMARKS_STREAM); + landmarkerNode.addOutputStream('WORLD_LANDMARKS:' + WORLD_LANDMARKS_STREAM); + landmarkerNode.addOutputStream( + 'AUXILIARY_LANDMARKS:' + AUXILIARY_LANDMARKS_STREAM); + landmarkerNode.setOptions(calculatorOptions); + + graphConfig.addNode(landmarkerNode); + + this.graphRunner.attachProtoVectorListener( + NORM_LANDMARKS_STREAM, (binaryProto, timestamp) => { + this.addJsLandmarks(binaryProto); + this.setLatestOutputTimestamp(timestamp); + }); + this.graphRunner.attachEmptyPacketListener( + NORM_LANDMARKS_STREAM, timestamp => { + this.setLatestOutputTimestamp(timestamp); + }); + + this.graphRunner.attachProtoVectorListener( + WORLD_LANDMARKS_STREAM, (binaryProto, timestamp) => { + this.adddJsWorldLandmarks(binaryProto); + this.setLatestOutputTimestamp(timestamp); + }); + this.graphRunner.attachEmptyPacketListener( + WORLD_LANDMARKS_STREAM, timestamp => { + this.setLatestOutputTimestamp(timestamp); + }); + + this.graphRunner.attachProtoVectorListener( + AUXILIARY_LANDMARKS_STREAM, (binaryProto, timestamp) => { + this.addJsAuxiliaryLandmarks(binaryProto); + this.setLatestOutputTimestamp(timestamp); + }); + this.graphRunner.attachEmptyPacketListener( + AUXILIARY_LANDMARKS_STREAM, timestamp => { + this.setLatestOutputTimestamp(timestamp); + }); + + if (this.outputSegmentationMasks) { + landmarkerNode.addOutputStream( + 'SEGMENTATION_MASK:' + SEGMENTATION_MASK_STREAM); + this.graphRunner.attachImageVectorListener( + SEGMENTATION_MASK_STREAM, (masks, timestamp) => { + this.result.segmentationMasks = + masks.map(m => m.data) as Float32Array[] | WebGLBuffer[]; + this.setLatestOutputTimestamp(timestamp); + }); + this.graphRunner.attachEmptyPacketListener( + SEGMENTATION_MASK_STREAM, timestamp => { + this.setLatestOutputTimestamp(timestamp); + }); + } + + const binaryGraph = graphConfig.serializeBinary(); + this.setGraph(new Uint8Array(binaryGraph), /* isBinary= */ true); + } +} + + diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.d.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.d.ts new file mode 100644 index 000000000..46f96e6d8 --- /dev/null +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.d.ts @@ -0,0 +1,47 @@ +/** + * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {VisionTaskOptions} from '../../../../tasks/web/vision/core/vision_task_options'; + +/** Options to configure the MediaPipe PoseLandmarker Task */ +export declare interface PoseLandmarkerOptions extends VisionTaskOptions { + /** + * The maximum number of poses can be detected by the PoseLandmarker. + * Defaults to 1. + */ + numPoses?: number|undefined; + + /** + * The minimum confidence score for the pose detection to be considered + * successful. Defaults to 0.5. + */ + minPoseDetectionConfidence?: number|undefined; + + /** + * The minimum confidence score of pose presence score in the pose landmark + * detection. Defaults to 0.5. + */ + minPosePresenceConfidence?: number|undefined; + + /** + * The minimum confidence score for the pose tracking to be considered + * successful. Defaults to 0.5. + */ + minTrackingConfidence?: number|undefined; + + /** Whether to output segmentation masks. Defaults to false. */ + outputSegmentationMasks?: boolean|undefined; +} diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts new file mode 100644 index 000000000..7bfca807b --- /dev/null +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts @@ -0,0 +1,38 @@ +/** + * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {Category} from '../../../../tasks/web/components/containers/category'; +import {Landmark, NormalizedLandmark} from '../../../../tasks/web/components/containers/landmark'; + +export {Category, Landmark, NormalizedLandmark}; + +/** + * Represents the pose landmarks deection results generated by `PoseLandmarker`. + * Each vector element represents a single pose detected in the image. + */ +export declare interface PoseLandmarkerResult { + /** Pose landmarks of detected poses. */ + landmarks: NormalizedLandmark[]; + + /** Pose landmarks in world coordinates of detected poses. */ + worldLandmarks: Landmark[]; + + /** Detected auxiliary landmarks, used for deriving ROI for next frame. */ + auxilaryLandmarks: NormalizedLandmark[]; + + /** Segmentation mask for the detected pose. */ + segmentationMasks?: Float32Array[]|WebGLTexture[]; +} diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts new file mode 100644 index 000000000..1862cc433 --- /dev/null +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts @@ -0,0 +1,264 @@ +/** + * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import 'jasmine'; + +import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; +import {createLandmarks, createWorldLandmarks} from '../../../../tasks/web/components/processors/landmark_result_test_lib'; +import {addJasmineCustomFloatEqualityTester, createSpyWasmModule, MediapipeTasksFake, SpyWasmModule, verifyGraph} from '../../../../tasks/web/core/task_runner_test_utils'; +import {VisionGraphRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; + +import {PoseLandmarker} from './pose_landmarker'; +import {PoseLandmarkerOptions} from './pose_landmarker_options'; +import {PoseLandmarkerResult} from './pose_landmarker_result'; + +// The OSS JS API does not support the builder pattern. +// tslint:disable:jspb-use-builder-pattern + +type PacketListener = (data: unknown, timestamp: number) => void; + +class PoseLandmarkerFake extends PoseLandmarker implements MediapipeTasksFake { + calculatorName = 'mediapipe.tasks.vision.pose_landmarker.PoseLandmarkerGraph'; + attachListenerSpies: jasmine.Spy[] = []; + graph: CalculatorGraphConfig|undefined; + fakeWasmModule: SpyWasmModule; + listeners = new Map(); + + constructor() { + super(createSpyWasmModule(), /* glCanvas= */ null); + this.fakeWasmModule = + this.graphRunner.wasmModule as unknown as SpyWasmModule; + + this.attachListenerSpies[0] = + spyOn(this.graphRunner, 'attachProtoVectorListener') + .and.callFake((stream, listener) => { + expect(stream).toMatch( + /(normalized_landmarks|world_landmarks|auxiliary_landmarks)/); + this.listeners.set(stream, listener as PacketListener); + }); + this.attachListenerSpies[1] = + spyOn(this.graphRunner, 'attachImageVectorListener') + .and.callFake((stream, listener) => { + expect(stream).toEqual('segmentation_masks'); + this.listeners.set(stream, listener as PacketListener); + }); + + spyOn(this.graphRunner, 'setGraph').and.callFake(binaryGraph => { + this.graph = CalculatorGraphConfig.deserializeBinary(binaryGraph); + }); + spyOn(this.graphRunner, 'addGpuBufferAsImageToStream'); + spyOn(this.graphRunner, 'addProtoToStream'); + } + + getGraphRunner(): VisionGraphRunner { + return this.graphRunner; + } +} + +describe('PoseLandmarker', () => { + let poseLandmarker: PoseLandmarkerFake; + + beforeEach(async () => { + addJasmineCustomFloatEqualityTester(); + poseLandmarker = new PoseLandmarkerFake(); + await poseLandmarker.setOptions( + {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); + }); + + it('initializes graph', async () => { + verifyGraph(poseLandmarker); + expect(poseLandmarker.listeners).toHaveSize(3); + }); + + it('reloads graph when settings are changed', async () => { + await poseLandmarker.setOptions({numPoses: 1}); + verifyGraph(poseLandmarker, [['poseDetectorGraphOptions', 'numPoses'], 1]); + expect(poseLandmarker.listeners).toHaveSize(3); + + await poseLandmarker.setOptions({numPoses: 5}); + verifyGraph(poseLandmarker, [['poseDetectorGraphOptions', 'numPoses'], 5]); + expect(poseLandmarker.listeners).toHaveSize(3); + }); + + it('registers listener for segmentation masks', async () => { + expect(poseLandmarker.listeners).toHaveSize(3); + await poseLandmarker.setOptions({outputSegmentationMasks: true}); + expect(poseLandmarker.listeners).toHaveSize(4); + }); + + it('merges options', async () => { + await poseLandmarker.setOptions({numPoses: 2}); + await poseLandmarker.setOptions({minPoseDetectionConfidence: 0.1}); + verifyGraph(poseLandmarker, [ + 'poseDetectorGraphOptions', { + numPoses: 2, + baseOptions: undefined, + minDetectionConfidence: 0.1, + minSuppressionThreshold: 0.5 + } + ]); + }); + + describe('setOptions()', () => { + interface TestCase { + optionPath: [keyof PoseLandmarkerOptions, ...string[]]; + fieldPath: string[]; + customValue: unknown; + defaultValue: unknown; + } + + const testCases: TestCase[] = [ + { + optionPath: ['numPoses'], + fieldPath: ['poseDetectorGraphOptions', 'numPoses'], + customValue: 5, + defaultValue: 1 + }, + { + optionPath: ['minPoseDetectionConfidence'], + fieldPath: ['poseDetectorGraphOptions', 'minDetectionConfidence'], + customValue: 0.1, + defaultValue: 0.5 + }, + { + optionPath: ['minPosePresenceConfidence'], + fieldPath: + ['poseLandmarksDetectorGraphOptions', 'minDetectionConfidence'], + customValue: 0.2, + defaultValue: 0.5 + }, + { + optionPath: ['minTrackingConfidence'], + fieldPath: ['minTrackingConfidence'], + customValue: 0.3, + defaultValue: 0.5 + }, + ]; + + /** Creates an options object that can be passed to setOptions() */ + function createOptions( + path: string[], value: unknown): PoseLandmarkerOptions { + const options: Record = {}; + let currentLevel = options; + for (const element of path.slice(0, -1)) { + currentLevel[element] = {}; + currentLevel = currentLevel[element] as Record; + } + currentLevel[path[path.length - 1]] = value; + return options; + } + + for (const testCase of testCases) { + it(`uses default value for ${testCase.optionPath[0]}`, async () => { + verifyGraph( + poseLandmarker, [testCase.fieldPath, testCase.defaultValue]); + }); + + it(`can set ${testCase.optionPath[0]}`, async () => { + await poseLandmarker.setOptions( + createOptions(testCase.optionPath, testCase.customValue)); + verifyGraph(poseLandmarker, [testCase.fieldPath, testCase.customValue]); + }); + + it(`can clear ${testCase.optionPath[0]}`, async () => { + await poseLandmarker.setOptions( + createOptions(testCase.optionPath, testCase.customValue)); + verifyGraph(poseLandmarker, [testCase.fieldPath, testCase.customValue]); + + await poseLandmarker.setOptions( + createOptions(testCase.optionPath, undefined)); + verifyGraph( + poseLandmarker, [testCase.fieldPath, testCase.defaultValue]); + }); + } + }); + + it('doesn\'t support region of interest', () => { + expect(() => { + poseLandmarker.detect( + {} as HTMLImageElement, + {regionOfInterest: {left: 0, right: 0, top: 0, bottom: 0}}, () => {}); + }).toThrowError('This task doesn\'t support region-of-interest.'); + }); + + it('transforms results', (done) => { + const landmarksProto = [createLandmarks().serializeBinary()]; + const worldLandmarksProto = [createWorldLandmarks().serializeBinary()]; + const masks = [ + {data: new Float32Array([0, 1, 2, 3]), width: 2, height: 2}, + ]; + + poseLandmarker.setOptions({outputSegmentationMasks: true}); + + // Pass the test data to our listener + poseLandmarker.fakeWasmModule._waitUntilIdle.and.callFake(() => { + poseLandmarker.listeners.get('normalized_landmarks')! + (landmarksProto, 1337); + poseLandmarker.listeners.get('world_landmarks')! + (worldLandmarksProto, 1337); + poseLandmarker.listeners.get('auxiliary_landmarks')! + (landmarksProto, 1337); + poseLandmarker.listeners.get('segmentation_masks')!(masks, 1337); + }); + + // Invoke the pose landmarker + poseLandmarker.detect({} as HTMLImageElement, result => { + expect(poseLandmarker.getGraphRunner().addProtoToStream) + .toHaveBeenCalledTimes(1); + expect(poseLandmarker.getGraphRunner().addGpuBufferAsImageToStream) + .toHaveBeenCalledTimes(1); + expect(poseLandmarker.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); + + expect(result).toEqual({ + 'landmarks': [{'x': 0, 'y': 0, 'z': 0}], + 'worldLandmarks': [{'x': 0, 'y': 0, 'z': 0}], + 'auxilaryLandmarks': [{'x': 0, 'y': 0, 'z': 0}], + 'segmentationMasks': [new Float32Array([0, 1, 2, 3])], + }); + done(); + }); + }); + + it('clears results between invoations', async () => { + const landmarksProto = [createLandmarks().serializeBinary()]; + const worldLandmarksProto = [createWorldLandmarks().serializeBinary()]; + + // Pass the test data to our listener + poseLandmarker.fakeWasmModule._waitUntilIdle.and.callFake(() => { + poseLandmarker.listeners.get('normalized_landmarks')! + (landmarksProto, 1337); + poseLandmarker.listeners.get('world_landmarks')! + (worldLandmarksProto, 1337); + poseLandmarker.listeners.get('auxiliary_landmarks')! + (landmarksProto, 1337); + }); + + // Invoke the pose landmarker twice + let landmarks1: PoseLandmarkerResult|undefined; + poseLandmarker.detect({} as HTMLImageElement, result => { + landmarks1 = result; + }); + + let landmarks2: PoseLandmarkerResult|undefined; + poseLandmarker.detect({} as HTMLImageElement, result => { + landmarks2 = result; + }); + + // Verify that poses2 is not a concatenation of all previously returned + // poses. + expect(landmarks1).toBeDefined(); + expect(landmarks1).toEqual(landmarks2); + }); +}); diff --git a/mediapipe/tasks/web/vision/types.ts b/mediapipe/tasks/web/vision/types.ts index 92cae43fb..f818b46a6 100644 --- a/mediapipe/tasks/web/vision/types.ts +++ b/mediapipe/tasks/web/vision/types.ts @@ -27,3 +27,4 @@ export * from '../../../tasks/web/vision/image_embedder/image_embedder'; export * from '../../../tasks/web/vision/image_segmenter/image_segmenter'; export * from '../../../tasks/web/vision/interactive_segmenter/interactive_segmenter'; export * from '../../../tasks/web/vision/object_detector/object_detector'; +export * from '../../../tasks/web/vision/pose_landmarker/pose_landmarker'; From ceb911ae06621bf1cd35b66a2ddc3be1761b3179 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Mon, 24 Apr 2023 11:06:16 -0700 Subject: [PATCH 067/753] Add nullable annotation to AudioDataProducer#setAudioConsumer PiperOrigin-RevId: 526697945 --- .../com/google/mediapipe/components/AudioDataProducer.java | 4 +++- mediapipe/java/com/google/mediapipe/components/BUILD | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/mediapipe/java/com/google/mediapipe/components/AudioDataProducer.java b/mediapipe/java/com/google/mediapipe/components/AudioDataProducer.java index 4f18f4706..5d042562e 100644 --- a/mediapipe/java/com/google/mediapipe/components/AudioDataProducer.java +++ b/mediapipe/java/com/google/mediapipe/components/AudioDataProducer.java @@ -14,8 +14,10 @@ package com.google.mediapipe.components; +import javax.annotation.Nullable; + /** Lightweight abstraction for an object that can produce audio data. */ public interface AudioDataProducer { /** Set the consumer that receives the audio data from this producer. */ - void setAudioConsumer(AudioDataConsumer consumer); + void setAudioConsumer(@Nullable AudioDataConsumer consumer); } diff --git a/mediapipe/java/com/google/mediapipe/components/BUILD b/mediapipe/java/com/google/mediapipe/components/BUILD index a1ec17548..630bc94c3 100644 --- a/mediapipe/java/com/google/mediapipe/components/BUILD +++ b/mediapipe/java/com/google/mediapipe/components/BUILD @@ -71,7 +71,10 @@ android_library( "AudioDataProducer.java", ], visibility = ["//visibility:public"], - deps = ["@maven//:com_google_guava_guava"], + deps = [ + "@maven//:com_google_code_findbugs_jsr305", + "@maven//:com_google_guava_guava", + ], ) # MicrophoneHelper that provides access to audio data from a microphone From b5118228150d8b3c78ea387def8171e425e0d0d4 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Mon, 24 Apr 2023 11:23:27 -0700 Subject: [PATCH 068/753] Removed an unnecessary check and updated tests to check if the masks are generated or not --- .../test/vision/pose_landmarker_test.py | 73 ++++++++++++++----- .../tasks/python/vision/pose_landmarker.py | 1 - 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py index fb5ad86e6..f63076041 100644 --- a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py +++ b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py @@ -104,12 +104,19 @@ class PoseLandmarkerTest(parameterized.TestCase): self, actual_result: PoseLandmarkerResult, expected_result: PoseLandmarkerResult, + output_segmentation_masks: bool, margin: float ): self._expect_pose_landmarks_correct( actual_result.pose_landmarks, expected_result.pose_landmarks, margin ) + if output_segmentation_masks: + self.assertIsInstance(actual_result.segmentation_masks, List) + for i, mask in enumerate(actual_result.segmentation_masks): + self.assertIsInstance(mask, _Image) + else: + self.assertIsNone(actual_result.segmentation_masks) def test_create_from_file_succeeds_with_valid_model_path(self): # Creates with default option and valid model file successfully. @@ -141,12 +148,17 @@ class PoseLandmarkerTest(parameterized.TestCase): self.assertIsInstance(landmarker, _PoseLandmarker) @parameterized.parameters( - (ModelFileType.FILE_NAME, + (ModelFileType.FILE_NAME, False, _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), - (ModelFileType.FILE_CONTENT, + (ModelFileType.FILE_CONTENT, False, + _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), + (ModelFileType.FILE_NAME, True, + _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), + (ModelFileType.FILE_CONTENT, True, _get_expected_pose_landmarker_result(_POSE_LANDMARKS)) ) - def test_detect(self, model_file_type, expected_detection_result): + def test_detect(self, model_file_type, output_segmentation_masks, + expected_detection_result): # Creates pose landmarker. if model_file_type is ModelFileType.FILE_NAME: base_options = _BaseOptions(model_asset_path=self.model_path) @@ -158,7 +170,10 @@ class PoseLandmarkerTest(parameterized.TestCase): # Should never happen raise ValueError('model_file_type is invalid.') - options = _PoseLandmarkerOptions(base_options=base_options) + options = _PoseLandmarkerOptions( + base_options=base_options, + output_segmentation_masks=output_segmentation_masks + ) landmarker = _PoseLandmarker.create_from_options(options) # Performs pose landmarks detection on the input. @@ -166,19 +181,27 @@ class PoseLandmarkerTest(parameterized.TestCase): # Comparing results. self._expect_pose_landmarker_results_correct( - detection_result, expected_detection_result, _LANDMARKS_MARGIN + detection_result, expected_detection_result, output_segmentation_masks, + _LANDMARKS_MARGIN ) # Closes the pose landmarker explicitly when the pose landmarker is not used # in a context. landmarker.close() @parameterized.parameters( - (ModelFileType.FILE_NAME, + (ModelFileType.FILE_NAME, False, _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), - (ModelFileType.FILE_CONTENT, + (ModelFileType.FILE_CONTENT, False, + _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), + (ModelFileType.FILE_NAME, True, + _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), + (ModelFileType.FILE_CONTENT, True, _get_expected_pose_landmarker_result(_POSE_LANDMARKS)) ) - def test_detect_in_context(self, model_file_type, expected_detection_result): + def test_detect_in_context( + self, model_file_type, output_segmentation_masks, + expected_detection_result + ): # Creates pose landmarker. if model_file_type is ModelFileType.FILE_NAME: base_options = _BaseOptions(model_asset_path=self.model_path) @@ -190,14 +213,18 @@ class PoseLandmarkerTest(parameterized.TestCase): # Should never happen raise ValueError('model_file_type is invalid.') - options = _PoseLandmarkerOptions(base_options=base_options) + options = _PoseLandmarkerOptions( + base_options=base_options, + output_segmentation_masks=output_segmentation_masks + ) with _PoseLandmarker.create_from_options(options) as landmarker: # Performs pose landmarks detection on the input. detection_result = landmarker.detect(self.test_image) # Comparing results. self._expect_pose_landmarker_results_correct( - detection_result, expected_detection_result, _LANDMARKS_MARGIN + detection_result, expected_detection_result, + output_segmentation_masks, _LANDMARKS_MARGIN ) def test_detect_fails_with_region_of_interest(self): @@ -295,12 +322,15 @@ class PoseLandmarkerTest(parameterized.TestCase): landmarker.detect_for_video(self.test_image, 0) @parameterized.parameters( - (_POSE_IMAGE, 0, + (_POSE_IMAGE, 0, False, _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), - (_BURGER_IMAGE, 0, + (_POSE_IMAGE, 0, True, + _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), + (_BURGER_IMAGE, 0, False, PoseLandmarkerResult([], [], [])) ) - def test_detect_for_video(self, image_path, rotation, expected_result): + def test_detect_for_video(self, image_path, rotation, + output_segmentation_masks, expected_result): test_image = _Image.create_from_file( test_utils.get_test_data_path(image_path)) # Set rotation parameters using ImageProcessingOptions. @@ -308,6 +338,7 @@ class PoseLandmarkerTest(parameterized.TestCase): rotation_degrees=rotation) options = _PoseLandmarkerOptions( base_options=_BaseOptions(model_asset_path=self.model_path), + output_segmentation_masks=output_segmentation_masks, running_mode=_RUNNING_MODE.VIDEO) with _PoseLandmarker.create_from_options(options) as landmarker: for timestamp in range(0, 300, 30): @@ -315,7 +346,8 @@ class PoseLandmarkerTest(parameterized.TestCase): image_processing_options) if result.pose_landmarks: self._expect_pose_landmarker_results_correct( - result, expected_result, _LANDMARKS_MARGIN + result, expected_result, output_segmentation_masks, + _LANDMARKS_MARGIN ) else: self.assertEqual(result, expected_result) @@ -352,12 +384,15 @@ class PoseLandmarkerTest(parameterized.TestCase): landmarker.detect_async(self.test_image, 0) @parameterized.parameters( - (_POSE_IMAGE, 0, + (_POSE_IMAGE, 0, False, _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), - (_BURGER_IMAGE, 0, + (_POSE_IMAGE, 0, True, + _get_expected_pose_landmarker_result(_POSE_LANDMARKS)), + (_BURGER_IMAGE, 0, False, PoseLandmarkerResult([], [], [])) ) - def test_detect_async_calls(self, image_path, rotation, expected_result): + def test_detect_async_calls(self, image_path, rotation, + output_segmentation_masks, expected_result): test_image = _Image.create_from_file( test_utils.get_test_data_path(image_path)) # Set rotation parameters using ImageProcessingOptions. @@ -369,7 +404,8 @@ class PoseLandmarkerTest(parameterized.TestCase): timestamp_ms: int): if result.pose_landmarks: self._expect_pose_landmarker_results_correct( - result, expected_result, _LANDMARKS_MARGIN + result, expected_result, output_segmentation_masks, + _LANDMARKS_MARGIN ) else: self.assertEqual(result, expected_result) @@ -380,6 +416,7 @@ class PoseLandmarkerTest(parameterized.TestCase): options = _PoseLandmarkerOptions( base_options=_BaseOptions(model_asset_path=self.model_path), + output_segmentation_masks=output_segmentation_masks, running_mode=_RUNNING_MODE.LIVE_STREAM, result_callback=check_result) with _PoseLandmarker.create_from_options(options) as landmarker: diff --git a/mediapipe/tasks/python/vision/pose_landmarker.py b/mediapipe/tasks/python/vision/pose_landmarker.py index f5ebd1fd9..0dedff250 100644 --- a/mediapipe/tasks/python/vision/pose_landmarker.py +++ b/mediapipe/tasks/python/vision/pose_landmarker.py @@ -263,7 +263,6 @@ class PoseLandmarker(base_vision_task_api.BaseVisionTaskApi): ) output_streams = [ - ':'.join([_SEGMENTATION_MASK_TAG, _SEGMENTATION_MASK_STREAM_NAME]), ':'.join([_NORM_LANDMARKS_TAG, _NORM_LANDMARKS_STREAM_NAME]), ':'.join([ _POSE_WORLD_LANDMARKS_TAG, _POSE_WORLD_LANDMARKS_STREAM_NAME From ca5fca1db7a1c8b70b17215140d01173e66de9d8 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Mon, 24 Apr 2023 11:26:36 -0700 Subject: [PATCH 069/753] Mark index as unused --- mediapipe/tasks/python/test/vision/pose_landmarker_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py index f63076041..372788897 100644 --- a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py +++ b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py @@ -113,7 +113,7 @@ class PoseLandmarkerTest(parameterized.TestCase): ) if output_segmentation_masks: self.assertIsInstance(actual_result.segmentation_masks, List) - for i, mask in enumerate(actual_result.segmentation_masks): + for _, mask in enumerate(actual_result.segmentation_masks): self.assertIsInstance(mask, _Image) else: self.assertIsNone(actual_result.segmentation_masks) From 33c8c68bba7e1b5f37337b94ed0d0abf12bf28bc Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Mon, 24 Apr 2023 12:06:39 -0700 Subject: [PATCH 070/753] Add a default_applicable_licenses to model_maker/python/vision/core. PiperOrigin-RevId: 526716940 --- mediapipe/model_maker/python/vision/core/BUILD | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mediapipe/model_maker/python/vision/core/BUILD b/mediapipe/model_maker/python/vision/core/BUILD index 6dd547ff1..f6f6cce05 100644 --- a/mediapipe/model_maker/python/vision/core/BUILD +++ b/mediapipe/model_maker/python/vision/core/BUILD @@ -17,9 +17,7 @@ licenses(["notice"]) -package( - default_visibility = ["//mediapipe:__subpackages__"], -) +package(default_visibility = ["//mediapipe:__subpackages__"]) py_library( name = "image_preprocessing", From a0eb1b696cc9dc6c1694275e62e47eb3e4064c8e Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Mon, 24 Apr 2023 14:43:29 -0700 Subject: [PATCH 071/753] Internal changes. PiperOrigin-RevId: 526759809 --- mediapipe/python/pybind/packet_getter.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mediapipe/python/pybind/packet_getter.cc b/mediapipe/python/pybind/packet_getter.cc index 93adfa018..a576c8b3c 100644 --- a/mediapipe/python/pybind/packet_getter.cc +++ b/mediapipe/python/pybind/packet_getter.cc @@ -14,6 +14,8 @@ #include "mediapipe/python/pybind/packet_getter.h" +#include + #include "absl/status/statusor.h" #include "mediapipe/framework/formats/image.h" #include "mediapipe/framework/formats/matrix.h" From 6eee726025025827dfd64d92caa83daa292ed6d1 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 25 Apr 2023 04:21:41 +0530 Subject: [PATCH 072/753] Updated build rules for iOS frameworks to duplicate symbols --- mediapipe/tasks/ios/BUILD | 117 ++++++++++++++++-- .../tasks/ios/text/text_classifier/BUILD | 8 +- mediapipe/tasks/ios/text/text_embedder/BUILD | 8 +- 3 files changed, 112 insertions(+), 21 deletions(-) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index 175d674a8..c94d1b48e 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -27,13 +27,30 @@ package(default_visibility = ["//visibility:public"]) licenses(["notice"]) -config_setting( - name = "avoid_linking_graphs", - define_values = { - "MEDIAPIPE_AVOID_LINKING_GRAPHS": "1", - }, - visibility = ["//visibility:public"], -) +# list of targets to be added in avoid_deps of ":MediaPipeTaskVision_framework" +# and ":MediaPipeTaskText_framework". +# The transitive closure of the following targets are used for building the +# frameworks but are avoided from the framework binaries to avoid duplicate symbols +# error when included in an xcode project: +# 1. iOS classes shared amongst the various vision and text tasks. These classes +# will be built with ":MediaPipeTaskCommonObjects_framework" +# 2. Task graphs. These will be built with ":MediaPipeTaskGraphs_library". +# 3. gpu targets which will be built with the ":MediaPipeTaskGraphs_library". +OBJC_COMMON_DEPS = [ + "//mediapipe/tasks/ios/core:MPPBaseOptions", + "//mediapipe/tasks/ios/core:MPPTaskInfo", + "//mediapipe/tasks/ios/core:MPPTaskOptions", + "//mediapipe/tasks/ios/core:MPPTaskResult", + "//mediapipe/tasks/ios/core:MPPTaskRunner", + "//mediapipe/tasks/ios/components/containers:MPPClassificationResult", + "//mediapipe/tasks/ios/components/containers:MPPCategory", + "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", + "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", + "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", + "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", + "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", + "//mediapipe/gpu:metal_shared_resources", +] strip_api_include_path_prefix( name = "strip_api_include_path", @@ -84,17 +101,99 @@ apple_static_xcframework( deps = [ "//mediapipe/tasks/ios/text/text_classifier:MPPTextClassifier", "//mediapipe/tasks/ios/text/text_embedder:MPPTextEmbedder", - "@org_tensorflow//third_party/icu/data:conversion_data", + ], + # avoid dependencies of ":MediaPipeCommonObjects_framework" and + # ":MediaPipeTaskGraphs_library in order to prevent duplicate symbols error + # when the frameworks are imported in iOS projects. + avoid_deps = OBJC_COMMON_DEPS +) + +apple_static_xcframework( + name = "MediaPipeTaskVision_framework", + public_hdrs = [ + ":MPPBaseOptions.h", + ":MPPCategory.h", + ":MPPClassificationResult.h", + ":MPPDetection.h", + ":MPPCommon.h", + ":MPPTaskOptions.h", + ":MPPTaskResult.h", + ":MPPImage.h", + ":MPPRunningMode.h", + ":MPPImageClassifier.h", + ":MPPImageClassifierOptions.h", + ":MPPImageClassifierResult.h", + ":MPPObjectDetector.h", + ":MPPObjectDetectorOptions.h", + ":MPPObjectDetectionResult.h", + ], + bundle_name = "MediaPipeTaskVision", + ios = { + "simulator" : ["arm64", "x86_64"], + "device" : ["arm64"], + }, + minimum_os_versions = { + "ios": MPP_TASK_MINIMUM_OS_VERSION, + }, + deps = [ + "//mediapipe/tasks/ios/vision/image_classifier:MPPImageClassifier", + "//mediapipe/tasks/ios/vision/object_detector:MPPObjectDetector", + ], + # Avoids dependencies of ":MediaPipeCommonObjects_framework" and + # ":MediaPipeTaskGraphs_library in order to prevent duplicate symbols error + # when the frameworks are imported in iOS projects. + # Also avoids opencv since it will be built with + # ":MediaPipeTaskGraphs_library". + avoid_deps = OBJC_COMMON_DEPS + [ + "@ios_opencv//:OpencvFramework" ], ) apple_static_library( - name = "MediaPipeTaskText_GraphLibrary", + name = "MediaPipeTaskGraphs_library", + minimum_os_version = MPP_TASK_MINIMUM_OS_VERSION, platform_type = "ios", minimum_os_version = MPP_TASK_MINIMUM_OS_VERSION, deps = [ + "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", + "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", "@org_tensorflow//third_party/icu/data:conversion_data", + "@ios_opencv//:OpencvFramework" + ], + # There is no way to turn off zlib dependency in custom opencv builds. + # Hence zlib is avoided to prevent duplicate symbols because of conflicts + # between opencv's zlib and "@zlib//:zlib" + avoid_deps = [ + "@zlib//:zlib", + ], +) + +apple_static_xcframework( + name = "MediaPipeTaskCommonObjects_framework", + bundle_name = "MediaPipeTaskCommon", + ios = { + "simulator" : ["arm64", "x86_64"], + "device" : ["arm64"], + }, + minimum_os_versions = { + "ios": MPP_TASK_MINIMUM_OS_VERSION, + }, + # avoids gpu targets since they will be built with + # ":MediaPipeTaskGraphs_library". Otherwise it will result in + # duplicate symbols error when the frameworks are imported in iOS. + avoid_deps = [ + "//mediapipe/gpu:metal_shared_resources", + ], + deps = [ + "//mediapipe/tasks/ios/core:MPPBaseOptions", + "//mediapipe/tasks/ios/core:MPPTaskInfo", + "//mediapipe/tasks/ios/core:MPPTaskOptions", + "//mediapipe/tasks/ios/core:MPPTaskResult", + "//mediapipe/tasks/ios/core:MPPTaskRunner", + "//mediapipe/tasks/ios/components/containers:MPPClassificationResult", + "//mediapipe/tasks/ios/components/containers:MPPCategory", + "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", ], ) diff --git a/mediapipe/tasks/ios/text/text_classifier/BUILD b/mediapipe/tasks/ios/text/text_classifier/BUILD index 97cf27677..7913340ac 100644 --- a/mediapipe/tasks/ios/text/text_classifier/BUILD +++ b/mediapipe/tasks/ios/text/text_classifier/BUILD @@ -49,6 +49,7 @@ objc_library( ":MPPTextClassifierOptions", ":MPPTextClassifierResult", "//mediapipe/tasks/cc/components/containers/proto:classifications_cc_proto", + "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", "//mediapipe/tasks/ios/common/utils:NSStringHelpers", "//mediapipe/tasks/ios/core:MPPTaskInfo", @@ -57,10 +58,5 @@ objc_library( "//mediapipe/tasks/ios/text/core:MPPTextTaskRunner", "//mediapipe/tasks/ios/text/text_classifier/utils:MPPTextClassifierOptionsHelpers", "//mediapipe/tasks/ios/text/text_classifier/utils:MPPTextClassifierResultHelpers", - ] + select({ - "//mediapipe/tasks/ios:avoid_linking_graphs": [], - "//conditions:default": [ - "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", - ], - }), + ], ) diff --git a/mediapipe/tasks/ios/text/text_embedder/BUILD b/mediapipe/tasks/ios/text/text_embedder/BUILD index a2edd8a2a..a600d5366 100644 --- a/mediapipe/tasks/ios/text/text_embedder/BUILD +++ b/mediapipe/tasks/ios/text/text_embedder/BUILD @@ -48,6 +48,7 @@ objc_library( deps = [ ":MPPTextEmbedderOptions", ":MPPTextEmbedderResult", + "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", "//mediapipe/tasks/ios/common/utils:NSStringHelpers", "//mediapipe/tasks/ios/components/utils:MPPCosineSimilarity", @@ -57,10 +58,5 @@ objc_library( "//mediapipe/tasks/ios/text/core:MPPTextTaskRunner", "//mediapipe/tasks/ios/text/text_embedder/utils:MPPTextEmbedderOptionsHelpers", "//mediapipe/tasks/ios/text/text_embedder/utils:MPPTextEmbedderResultHelpers", - ] + select({ - "//mediapipe/tasks/ios:avoid_linking_graphs": [], - "//conditions:default": [ - "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", - ], - }), + ], ) From 472947818e25450823160aa3db1e09be6afce0fb Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 25 Apr 2023 04:22:03 +0530 Subject: [PATCH 073/753] Updated ios cocoapods build script --- mediapipe/tasks/ios/build_ios_framework.sh | 48 +++++++++++++--------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index 48bc0419c..6d59a9ac9 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -32,7 +32,9 @@ fi BAZEL="${BAZEL:-$(which bazel)}" MPP_BUILD_VERSION=${MPP_BUILD_VERSION:-0.0.1-dev} MPP_ROOT_DIR=$(git rev-parse --show-toplevel) -MPP_DISABLE_GPU=1 +ARCHIVE_FRAMEWORK=true +IS_RELEASE_BUILD=false +DEST_DIR=$HOME if [[ ! -x "${BAZEL}" ]]; then echo "bazel executable is not found." @@ -88,12 +90,8 @@ function build_target { echo ${OUTPUT_PATH} } -# This function builds 3 targets: -# 1. The ios task library xcframework -# 2. Fat static library including graphs needed for tasks in xcframework, for all -# simulator archs (x86_64, arm64). -# 3. Static library including graphs needed for the xcframework for all iOS device -# archs (arm64). +# This function builds 3 the xcframework and associated graph libraries if any +# for a given framework name. function build_ios_frameworks_and_libraries { local TARGET_PREFIX="//mediapipe/tasks/ios" FULL_FRAMEWORK_TARGET="${TARGET_PREFIX}:${FRAMEWORK_NAME}_framework" @@ -104,21 +102,26 @@ function build_ios_frameworks_and_libraries { # CocoaPods must set --apple_generate_dsym=false inorder to shave down the binary size to # the order of a few MBs. - # Build Text Task Library xcframework without the graph dependencies. - local FRAMEWORK_CQUERY_COMMAND="-c opt --define MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} \ - --define MEDIAPIPE_AVOID_LINKING_GRAPHS=1 --apple_generate_dsym=false ${FULL_FRAMEWORK_TARGET}" + # Build Task Library xcframework. + local FRAMEWORK_CQUERY_COMMAND="-c opt --apple_generate_dsym=false ${FULL_FRAMEWORK_TARGET}" IOS_FRAMEWORK_PATH="$(build_target "${FRAMEWORK_CQUERY_COMMAND}")" - # Build fat static library for text task graphs for simulator archs. - local IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_sim_fat --define \ - MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} --apple_generate_dsym=false ${FULL_GRAPH_LIBRARY_TARGET}" - IOS_GRAPHS_SIMULATOR_LIBRARY_PATH="$(build_target "${IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND}")" + # `MediaPipeTaskCommonObjects`` pods must also include the task graph libraries which + # are to be force loaded. Hence the graph libraies are only built if the framework + # name is `MediaPipeTaskCommonObjects`.` + case $FRAMEWORK_NAME in + "MediaPipeTaskCommonObjects") + local IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_sim_fat --apple_generate_dsym=false //mediapipe/tasks/ios:MediaPipeTaskGraphs_library" + IOS_GRAPHS_SIMULATOR_LIBRARY_PATH="$(build_target "${IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND}")" - # Build static library for iOS devices with arch ios_arm64. We don't need to build for armv7 since - # our deployment target is iOS 11.0. iOS 11.0 d anupwards is not supported by old armv7 devices. - local IOS_DEVICE_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_arm64 --define \ - MEDIAPIPE_DISABLE_GPU=${MPP_DISABLE_GPU} --apple_generate_dsym=false ${FULL_GRAPH_LIBRARY_TARGET}" - IOS_GRAPHS_DEVICE_LIBRARY_PATH="$(build_target "${IOS_DEVICE_LIBRARY_CQUERY_COMMAND}")" + # Build static library for iOS devices with arch ios_arm64. We don't need to build for armv7 since + # our deployment target is iOS 11.0. iOS 11.0 and upwards is not supported by old armv7 devices. + local IOS_DEVICE_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_arm64 --apple_generate_dsym=false //mediapipe/tasks/ios:MediaPipeTaskGraphs_library" + IOS_GRAPHS_DEVICE_LIBRARY_PATH="$(build_target "${IOS_DEVICE_LIBRARY_CQUERY_COMMAND}")" + ;; + *) + ;; + esac } function create_framework_archive { @@ -137,6 +140,13 @@ function create_framework_archive { echo ${IOS_FRAMEWORK_PATH} unzip "${IOS_FRAMEWORK_PATH}" -d "${FRAMEWORKS_DIR}" + + # If the framwork being built is `MediaPipeTaskCommonObjects`, the built graph + # libraries should be copied to the output directory which is to be archived. + case $FRAMEWORK_NAME in + "MediaPipeTaskCommonObjects") + + local GRAPH_LIBRARIES_DIR="graph_libraries" local GRAPH_LIBRARIES_DIR="graph_libraries" From 8b44a7f181fef78a1f068741308a423b1f90e1dc Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 25 Apr 2023 04:22:18 +0530 Subject: [PATCH 074/753] Updated text podspec --- mediapipe/tasks/ios/MediaPipeTaskText.podspec.template | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template b/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template index 88ec4d989..e84779ae8 100644 --- a/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template +++ b/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template @@ -12,12 +12,7 @@ Pod::Spec.new do |s| s.module_name = 'MediaPipeTaskText' s.static_framework = true - s.user_target_xcconfig = { - 'OTHER_LDFLAGS[sdk=iphonesimulator*]' => '$(inherited) -force_load "$(PODS_ROOT)/MediaPipeTaskText/frameworks/graph_libraries/libMediaPipeTaskText_simulator_graph.a"', - 'OTHER_LDFLAGS[sdk=iphoneos*]' => '$(inherited) -force_load "$(PODS_ROOT)/MediaPipeTaskText/frameworks/graph_libraries/libMediaPipeTaskText_device_graph.a"', - 'STRIP_INSTALLED_PRODUCT' => 'NO' - } + s.dependency 'MediaPipeTaskCommonObjects' s.library = 'c++' - s.preserve_paths = 'frameworks/graph_libraries/*.a' s.vendored_frameworks = 'frameworks/MediaPipeTaskText.xcframework' end From d63d3f61d76e71eac8422ee86421443add61e1f3 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 25 Apr 2023 04:22:40 +0530 Subject: [PATCH 075/753] Added podspec for CommonObjects and Vision tasks --- ...ediaPipeTaskCommonObjects.podspec.template | 23 +++++++++++++++++++ .../ios/MediaPipeTaskVision.podspec.template | 18 +++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 mediapipe/tasks/ios/MediaPipeTaskCommonObjects.podspec.template create mode 100644 mediapipe/tasks/ios/MediaPipeTaskVision.podspec.template diff --git a/mediapipe/tasks/ios/MediaPipeTaskCommonObjects.podspec.template b/mediapipe/tasks/ios/MediaPipeTaskCommonObjects.podspec.template new file mode 100644 index 000000000..a58d0b262 --- /dev/null +++ b/mediapipe/tasks/ios/MediaPipeTaskCommonObjects.podspec.template @@ -0,0 +1,23 @@ +Pod::Spec.new do |s| + s.name = 'MediaPipeTaskCommonObjects' + s.version = '${MPP_BUILD_VERSION}' + s.authors = 'Google Inc.' + s.license = { :type => 'Apache',:file => "LICENSE" } + s.homepage = 'https://github.com/google/mediapipe' + s.source = { :http => '${MPP_DOWNLOAD_URL}' } + s.summary = 'MediaPipe Task Library - Text' + s.description = 'The Natural Language APIs of the MediaPipe Task Library' + + s.ios.deployment_target = '11.0' + + s.module_name = 'MediaPipeTaskCommonObjects' + s.static_framework = true + s.user_target_xcconfig = { + 'OTHER_LDFLAGS[sdk=iphonesimulator*]' => '$(inherited) -force_load "${PODS_ROOT}/MediaPipeTaskCommonObjects/frameworks/graph_libraries/libMediaPipeTaskCommonObjects_simulator_graph.a"', + 'OTHER_LDFLAGS[sdk=iphoneos*]' => '$(inherited) -force_load "$(PODS_ROOT)/MediaPipeTaskCommonObjects/frameworks/graph_libraries/libMediaPipeTaskCommonObjects_device_graph.a"', + } + s.frameworks = 'Accelerate', 'CoreMedia', 'AssetsLibrary', 'CoreFoundation', 'CoreGraphics', 'CoreImage', 'QuartzCore', 'AVFoundation', 'CoreVideo' + s.preserve_paths ='frameworks/graph_libraries/*.a' + s.library = 'c++' + s.vendored_frameworks = 'frameworks/MediaPipeTaskCommon.xcframework' +end diff --git a/mediapipe/tasks/ios/MediaPipeTaskVision.podspec.template b/mediapipe/tasks/ios/MediaPipeTaskVision.podspec.template new file mode 100644 index 000000000..0d530e4cf --- /dev/null +++ b/mediapipe/tasks/ios/MediaPipeTaskVision.podspec.template @@ -0,0 +1,18 @@ +Pod::Spec.new do |s| + s.name = 'MediaPipeTaskVision' + s.version = '${MPP_BUILD_VERSION}' + s.authors = 'Google Inc.' + s.license = { :type => 'Apache',:file => "LICENSE" } + s.homepage = 'https://github.com/google/mediapipe' + s.source = { :http => '${MPP_DOWNLOAD_URL}' } + s.summary = 'MediaPipe Task Library - Vision' + s.description = 'The Vision APIs of the MediaPipe Task Library' + + s.ios.deployment_target = '11.0' + + s.module_name = 'MediaPipeTaskVision' + s.static_framework = true + s.dependency 'MediaPipeTaskCommonObjects' + s.library = 'c++' + s.vendored_frameworks = 'frameworks/MediaPipeTaskVision.xcframework' +end From 6ac39c9b93df23a5004ea13032f81a969591f2bf Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 25 Apr 2023 04:26:13 +0530 Subject: [PATCH 076/753] Updated name of common objects pod --- mediapipe/tasks/ios/BUILD | 8 ++++---- ...template => MediaPipeTaskCommon.podspec.template} | 8 ++++---- mediapipe/tasks/ios/build_ios_framework.sh | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) rename mediapipe/tasks/ios/{MediaPipeTaskCommonObjects.podspec.template => MediaPipeTaskCommon.podspec.template} (73%) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index c94d1b48e..25b7ab9ce 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -33,7 +33,7 @@ licenses(["notice"]) # frameworks but are avoided from the framework binaries to avoid duplicate symbols # error when included in an xcode project: # 1. iOS classes shared amongst the various vision and text tasks. These classes -# will be built with ":MediaPipeTaskCommonObjects_framework" +# will be built with ":MediaPipeTaskCommon_framework" # 2. Task graphs. These will be built with ":MediaPipeTaskGraphs_library". # 3. gpu targets which will be built with the ":MediaPipeTaskGraphs_library". OBJC_COMMON_DEPS = [ @@ -102,7 +102,7 @@ apple_static_xcframework( "//mediapipe/tasks/ios/text/text_classifier:MPPTextClassifier", "//mediapipe/tasks/ios/text/text_embedder:MPPTextEmbedder", ], - # avoid dependencies of ":MediaPipeCommonObjects_framework" and + # avoid dependencies of ":MediaPipeCommon_framework" and # ":MediaPipeTaskGraphs_library in order to prevent duplicate symbols error # when the frameworks are imported in iOS projects. avoid_deps = OBJC_COMMON_DEPS @@ -139,7 +139,7 @@ apple_static_xcframework( "//mediapipe/tasks/ios/vision/image_classifier:MPPImageClassifier", "//mediapipe/tasks/ios/vision/object_detector:MPPObjectDetector", ], - # Avoids dependencies of ":MediaPipeCommonObjects_framework" and + # Avoids dependencies of ":MediaPipeCommon_framework" and # ":MediaPipeTaskGraphs_library in order to prevent duplicate symbols error # when the frameworks are imported in iOS projects. # Also avoids opencv since it will be built with @@ -171,7 +171,7 @@ apple_static_library( ) apple_static_xcframework( - name = "MediaPipeTaskCommonObjects_framework", + name = "MediaPipeTaskCommon_framework", bundle_name = "MediaPipeTaskCommon", ios = { "simulator" : ["arm64", "x86_64"], diff --git a/mediapipe/tasks/ios/MediaPipeTaskCommonObjects.podspec.template b/mediapipe/tasks/ios/MediaPipeTaskCommon.podspec.template similarity index 73% rename from mediapipe/tasks/ios/MediaPipeTaskCommonObjects.podspec.template rename to mediapipe/tasks/ios/MediaPipeTaskCommon.podspec.template index a58d0b262..52dc73b3a 100644 --- a/mediapipe/tasks/ios/MediaPipeTaskCommonObjects.podspec.template +++ b/mediapipe/tasks/ios/MediaPipeTaskCommon.podspec.template @@ -1,5 +1,5 @@ Pod::Spec.new do |s| - s.name = 'MediaPipeTaskCommonObjects' + s.name = 'MediaPipeTaskCommon' s.version = '${MPP_BUILD_VERSION}' s.authors = 'Google Inc.' s.license = { :type => 'Apache',:file => "LICENSE" } @@ -10,11 +10,11 @@ Pod::Spec.new do |s| s.ios.deployment_target = '11.0' - s.module_name = 'MediaPipeTaskCommonObjects' + s.module_name = 'MediaPipeTaskCommon' s.static_framework = true s.user_target_xcconfig = { - 'OTHER_LDFLAGS[sdk=iphonesimulator*]' => '$(inherited) -force_load "${PODS_ROOT}/MediaPipeTaskCommonObjects/frameworks/graph_libraries/libMediaPipeTaskCommonObjects_simulator_graph.a"', - 'OTHER_LDFLAGS[sdk=iphoneos*]' => '$(inherited) -force_load "$(PODS_ROOT)/MediaPipeTaskCommonObjects/frameworks/graph_libraries/libMediaPipeTaskCommonObjects_device_graph.a"', + 'OTHER_LDFLAGS[sdk=iphonesimulator*]' => '$(inherited) -force_load "${PODS_ROOT}/MediaPipeTaskCommon/frameworks/graph_libraries/libMediaPipeTaskCommon_simulator_graph.a"', + 'OTHER_LDFLAGS[sdk=iphoneos*]' => '$(inherited) -force_load "$(PODS_ROOT)/MediaPipeTaskCommon/frameworks/graph_libraries/libMediaPipeTaskCommon_device_graph.a"', } s.frameworks = 'Accelerate', 'CoreMedia', 'AssetsLibrary', 'CoreFoundation', 'CoreGraphics', 'CoreImage', 'QuartzCore', 'AVFoundation', 'CoreVideo' s.preserve_paths ='frameworks/graph_libraries/*.a' diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index 6d59a9ac9..7ebbedca0 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -16,7 +16,7 @@ # Set the following variables as appropriate. # * BAZEL: path to bazel. defaults to the first one available in PATH # * FRAMEWORK_NAME: name of the iOS framework to be built. Currently the -# * accepted values are MediaPipeTaskText. +# * accepted values are MediaPipeTaskCommon, MediaPipeTaskText, MediaPipeTaskVision. # * MPP_BUILD_VERSION: to specify the release version. defaults to 0.0.1-dev # * IS_RELEASE_BUILD: set as true if this build should be a release build # * ARCHIVE_FRAMEWORK: set as true if the framework should be archived @@ -106,11 +106,11 @@ function build_ios_frameworks_and_libraries { local FRAMEWORK_CQUERY_COMMAND="-c opt --apple_generate_dsym=false ${FULL_FRAMEWORK_TARGET}" IOS_FRAMEWORK_PATH="$(build_target "${FRAMEWORK_CQUERY_COMMAND}")" - # `MediaPipeTaskCommonObjects`` pods must also include the task graph libraries which + # `MediaPipeTaskCommon`` pods must also include the task graph libraries which # are to be force loaded. Hence the graph libraies are only built if the framework - # name is `MediaPipeTaskCommonObjects`.` + # name is `MediaPipeTaskCommon`.` case $FRAMEWORK_NAME in - "MediaPipeTaskCommonObjects") + "MediaPipeTaskCommon") local IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_sim_fat --apple_generate_dsym=false //mediapipe/tasks/ios:MediaPipeTaskGraphs_library" IOS_GRAPHS_SIMULATOR_LIBRARY_PATH="$(build_target "${IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND}")" @@ -141,10 +141,10 @@ function create_framework_archive { echo ${IOS_FRAMEWORK_PATH} unzip "${IOS_FRAMEWORK_PATH}" -d "${FRAMEWORKS_DIR}" - # If the framwork being built is `MediaPipeTaskCommonObjects`, the built graph + # If the framwork being built is `MediaPipeTaskCommon`, the built graph # libraries should be copied to the output directory which is to be archived. case $FRAMEWORK_NAME in - "MediaPipeTaskCommonObjects") + "MediaPipeTaskCommon") local GRAPH_LIBRARIES_DIR="graph_libraries" From 33903252505c6863d3e97f957ea11a4e79440dbd Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 25 Apr 2023 11:23:38 +0530 Subject: [PATCH 077/753] Updated documentation --- mediapipe/tasks/ios/ios.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/ios/ios.bzl b/mediapipe/tasks/ios/ios.bzl index fdfc85d5f..e4cdeb503 100644 --- a/mediapipe/tasks/ios/ios.bzl +++ b/mediapipe/tasks/ios/ios.bzl @@ -6,7 +6,7 @@ MPP_TASK_MINIMUM_OS_VERSION = "11.0" # to the "Headers" directory with no header path prefixes. This auxiliary rule # is used for stripping the path prefix to the C/iOS API header files included by # other C/iOS API header files. -# In case of C header files includes start with a keyword of "#include'. +# In case of C header files, includes start with a keyword of "#include'. # Imports in iOS header files start with a keyword of '#import'. def strip_api_include_path_prefix(name, hdr_labels, prefix = ""): """Create modified header files with the import path stripped out. From 56df724c36b53445862ac1e726220129eee981c0 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 25 Apr 2023 00:45:26 -0700 Subject: [PATCH 078/753] Add customizable face stylizer module in MediaPipe model maker PiperOrigin-RevId: 526883862 --- .../python/vision/face_stylizer/BUILD | 42 +++- .../python/vision/face_stylizer/__init__.py | 14 ++ .../python/vision/face_stylizer/constants.py | 45 ++++ .../vision/face_stylizer/face_stylizer.py | 201 ++++++++++++++++++ .../face_stylizer/face_stylizer_test.py | 55 +++++ .../vision/face_stylizer/model_options.py | 18 +- 6 files changed, 369 insertions(+), 6 deletions(-) create mode 100644 mediapipe/model_maker/python/vision/face_stylizer/constants.py create mode 100644 mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py create mode 100644 mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_test.py diff --git a/mediapipe/model_maker/python/vision/face_stylizer/BUILD b/mediapipe/model_maker/python/vision/face_stylizer/BUILD index b5e0399d1..53fb684e4 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/BUILD +++ b/mediapipe/model_maker/python/vision/face_stylizer/BUILD @@ -14,6 +14,7 @@ # Placeholder for internal Python strict test compatibility macro. # Placeholder for internal Python strict library and test compatibility macro. +# Placeholder for internal Python GPU test rule. licenses(["notice"]) @@ -26,6 +27,12 @@ filegroup( ]), ) +py_library( + name = "constants", + srcs = ["constants.py"], + deps = ["//mediapipe/model_maker/python/core/utils:file_util"], +) + py_library( name = "hyperparameters", srcs = ["hyperparameters.py"], @@ -37,6 +44,7 @@ py_library( py_library( name = "model_options", srcs = ["model_options.py"], + deps = ["//mediapipe/model_maker/python/core/utils:loss_functions"], ) py_library( @@ -72,11 +80,39 @@ py_library( py_test( name = "dataset_test", srcs = ["dataset_test.py"], - data = [ - ":testdata", - ], + data = [":testdata"], deps = [ ":dataset", "//mediapipe/tasks/python/test:test_utils", ], ) + +py_library( + name = "face_stylizer", + srcs = ["face_stylizer.py"], + deps = [ + ":constants", + ":face_stylizer_options", + ":hyperparameters", + ":model_options", + ":model_spec", + "//mediapipe/model_maker/python/core/data:classification_dataset", + "//mediapipe/model_maker/python/core/utils:loss_functions", + "//mediapipe/model_maker/python/core/utils:model_util", + "//mediapipe/model_maker/python/vision/core:image_preprocessing", + ], +) + +py_library( + name = "face_stylizer_import", + srcs = ["__init__.py"], + visibility = ["//visibility:public"], + deps = [ + ":dataset", + ":face_stylizer", + ":face_stylizer_options", + ":hyperparameters", + ":model_options", + ":model_spec", + ], +) diff --git a/mediapipe/model_maker/python/vision/face_stylizer/__init__.py b/mediapipe/model_maker/python/vision/face_stylizer/__init__.py index e935c0c76..3cec27964 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/__init__.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/__init__.py @@ -12,3 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. """MediaPipe Model Maker Python Public API For Face Stylization.""" + +from mediapipe.model_maker.python.vision.face_stylizer import dataset +from mediapipe.model_maker.python.vision.face_stylizer import face_stylizer +from mediapipe.model_maker.python.vision.face_stylizer import face_stylizer_options +from mediapipe.model_maker.python.vision.face_stylizer import hyperparameters +from mediapipe.model_maker.python.vision.face_stylizer import model_options +from mediapipe.model_maker.python.vision.face_stylizer import model_spec + +FaceStylizer = face_stylizer.FaceStylizer +SupportedModels = model_spec.SupportedModels +ModelOptions = model_options.FaceStylizerModelOptions +HParams = hyperparameters.HParams +Dataset = dataset.Dataset +FaceStylizerOptions = face_stylizer_options.FaceStylizerOptions diff --git a/mediapipe/model_maker/python/vision/face_stylizer/constants.py b/mediapipe/model_maker/python/vision/face_stylizer/constants.py new file mode 100644 index 000000000..e7a03aebd --- /dev/null +++ b/mediapipe/model_maker/python/vision/face_stylizer/constants.py @@ -0,0 +1,45 @@ +# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Face stylizer model constants.""" + +from mediapipe.model_maker.python.core.utils import file_util + +# TODO: Move model files to GCS for downloading. +FACE_STYLIZER_ENCODER_MODEL_FILES = file_util.DownloadedFiles( + 'face_stylizer/encoder', + 'https://storage.googleapis.com/mediapipe-assets/face_stylizer_encoder.tar.gz', + is_folder=True, +) +FACE_STYLIZER_DECODER_MODEL_FILES = file_util.DownloadedFiles( + 'face_stylizer/decoder', + 'https://storage.googleapis.com/mediapipe-assets/face_stylizer_decoder.tar.gz', + is_folder=True, +) +FACE_STYLIZER_MAPPING_MODEL_FILES = file_util.DownloadedFiles( + 'face_stylizer/mapping', + 'https://storage.googleapis.com/mediapipe-assets/face_stylizer_mapping.tar.gz', + is_folder=True, +) +FACE_STYLIZER_DISCRIMINATOR_MODEL_FILES = file_util.DownloadedFiles( + 'face_stylizer/discriminator', + 'https://storage.googleapis.com/mediapipe-assets/face_stylizer_discriminator.tar.gz', + is_folder=True, +) +FACE_STYLIZER_W_FILES = file_util.DownloadedFiles( + 'face_stylizer/w_avg.npy', + 'https://storage.googleapis.com/mediapipe-assets/face_stylizer_w_avg.npy', +) + +# Dimension of the input style vector to the decoder +STYLE_DIM = 512 diff --git a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py new file mode 100644 index 000000000..3e850582f --- /dev/null +++ b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py @@ -0,0 +1,201 @@ +# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""APIs to train face stylization model.""" + +from typing import Callable, Optional + +import numpy as np +import tensorflow as tf + +from mediapipe.model_maker.python.core.data import classification_dataset as classification_ds +from mediapipe.model_maker.python.core.utils import loss_functions +from mediapipe.model_maker.python.core.utils import model_util +from mediapipe.model_maker.python.vision.core import image_preprocessing +from mediapipe.model_maker.python.vision.face_stylizer import constants +from mediapipe.model_maker.python.vision.face_stylizer import face_stylizer_options +from mediapipe.model_maker.python.vision.face_stylizer import hyperparameters as hp +from mediapipe.model_maker.python.vision.face_stylizer import model_options as model_opt +from mediapipe.model_maker.python.vision.face_stylizer import model_spec as ms + + +class FaceStylizer(object): + """FaceStylizer for building face stylization model. + + Attributes: + w_avg: An average face latent code to regularize face generation in face + stylization. + """ + + def __init__( + self, + model_spec: ms.ModelSpec, + model_options: model_opt.FaceStylizerModelOptions, + hparams: hp.HParams, + ): + """Initializes face stylizer. + + Args: + model_spec: Specification for the model. + model_options: Model options for creating face stylizer. + hparams: The hyperparameters for training face stylizer. + """ + self._model_spec = model_spec + self._model_options = model_options + self._hparams = hparams + # TODO: Support face alignment in image preprocessor. + self._preprocessor = image_preprocessing.Preprocessor( + input_shape=self._model_spec.input_image_shape, + num_classes=1, + mean_rgb=self._model_spec.mean_rgb, + stddev_rgb=self._model_spec.stddev_rgb, + ) + + @classmethod + def create( + cls, + train_data: classification_ds.ClassificationDataset, + options: face_stylizer_options.FaceStylizerOptions, + ) -> 'FaceStylizer': + """Creates and trains a face stylizer with input datasets. + + Args: + train_data: The input style image dataset for training the face stylizer. + options: The options to configure face stylizer. + + Returns: + A FaceStylizer instant with the trained model. + """ + if options.model_options is None: + options.model_options = model_opt.FaceStylizerModelOptions() + + if options.hparams is None: + options.hparams = hp.HParams() + + spec = ms.SupportedModels.get(options.model) + + face_stylizer = cls( + model_spec=spec, + model_options=options.model_options, + hparams=options.hparams, + ) + face_stylizer._create_and_train_model(train_data) + return face_stylizer + + def _create_and_train_model( + self, train_data: classification_ds.ClassificationDataset + ): + """Creates and trains the face stylizer model. + + Args: + train_data: Training data. + """ + self._create_model() + self._train_model(train_data=train_data, preprocessor=self._preprocessor) + + def _create_model(self): + """Creates the componenets of face stylizer.""" + self._encoder = model_util.load_keras_model( + constants.FACE_STYLIZER_ENCODER_MODEL_FILES.get_path() + ) + self._decoder = model_util.load_keras_model( + constants.FACE_STYLIZER_DECODER_MODEL_FILES.get_path() + ) + self._mapping_network = model_util.load_keras_model( + constants.FACE_STYLIZER_MAPPING_MODEL_FILES.get_path() + ) + self._discriminator = model_util.load_keras_model( + constants.FACE_STYLIZER_DISCRIMINATOR_MODEL_FILES.get_path() + ) + with tf.io.gfile.GFile( + constants.FACE_STYLIZER_W_FILES.get_path(), 'rb' + ) as f: + w_avg = np.load(f) + + self.w_avg = w_avg[: self._model_spec.style_block_num][np.newaxis] + + def _train_model( + self, + train_data: classification_ds.ClassificationDataset, + preprocessor: Optional[Callable[..., bool]] = None, + ): + """Trains the face stylizer model. + + Args: + train_data: The data for training model. + preprocessor: The image preprocessor. + """ + train_dataset = train_data.gen_tf_dataset(preprocess=preprocessor) + + # TODO: Support processing mulitple input style images. The + # input style images are expected to have similar style. + # style_sample represents a tuple of (style_image, style_label). + style_sample = next(iter(train_dataset)) + style_img = style_sample[0] + + batch_size = self._hparams.batch_size + label_in = tf.zeros(shape=[batch_size, 0]) + + style_encoding = self._encoder(style_img) + + optimizer = tf.keras.optimizers.Adam( + learning_rate=self._hparams.learning_rate, + beta_1=self._hparams.beta_1, + beta_2=self._hparams.beta_2, + ) + + image_perceptual_quality_loss = loss_functions.ImagePerceptualQualityLoss( + loss_weight=self._model_options.perception_loss_weight + ) + + for i in range(self._hparams.epochs): + noise = tf.random.normal(shape=[batch_size, constants.STYLE_DIM]) + + mean_w = self._mapping_network([noise, label_in], training=False)[ + :, : self._model_spec.style_block_num + ] + style_encodings = tf.tile(style_encoding, [batch_size, 1, 1]) + + in_latent = tf.Variable(tf.identity(style_encodings)) + + alpha = self._model_options.alpha + for swap_layer in self._model_options.swap_layers: + in_latent = in_latent[:, swap_layer].assign( + alpha * style_encodings[:, swap_layer] + + (1 - alpha) * mean_w[:, swap_layer] + ) + + with tf.GradientTape() as tape: + outputs = self._decoder( + {'inputs': in_latent + self.w_avg}, + training=False, + ) + gen_img = outputs['image'][-1] + + real_feature = self._discriminator( + [tf.transpose(style_img, [0, 3, 1, 2]), label_in] + ) + gen_feature = self._discriminator( + [tf.transpose(gen_img, [0, 3, 1, 2]), label_in] + ) + + style_loss = image_perceptual_quality_loss(gen_img, style_img) + style_loss += ( + tf.keras.losses.MeanAbsoluteError()(real_feature, gen_feature) + * self._model_options.adv_loss_weight + ) + tf.compat.v1.logging.info(f'Iteration {i} loss: {style_loss.numpy()}') + + tvars = self._decoder.trainable_variables + grads = tape.gradient(style_loss, tvars) + optimizer.apply_gradients(list(zip(grads, tvars))) diff --git a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_test.py b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_test.py new file mode 100644 index 000000000..c244a3ee4 --- /dev/null +++ b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_test.py @@ -0,0 +1,55 @@ +# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import tensorflow as tf + +from mediapipe.model_maker.python.vision import face_stylizer +from mediapipe.tasks.python.test import test_utils + + +class FaceStylizerTest(tf.test.TestCase): + + def _load_data(self): + """Loads training dataset.""" + input_data_dir = test_utils.get_test_data_path('testdata') + + data = face_stylizer.Dataset.from_folder(dirname=input_data_dir) + return data + + def _evaluate_saved_model(self, model: face_stylizer.FaceStylizer): + """Evaluates the fine-tuned face stylizer model.""" + test_image = tf.ones(shape=(256, 256, 3), dtype=tf.float32) + test_image_batch = test_image[tf.newaxis] + in_latent = model._encoder(test_image_batch) + output = model._decoder({'inputs': in_latent + model.w_avg}) + self.assertEqual(output['image'][-1].shape, (1, 256, 256, 3)) + + def setUp(self): + super().setUp() + self._train_data = self._load_data() + + def test_finetuning_face_stylizer_with_single_input_style_image(self): + with self.test_session(use_gpu=True): + face_stylizer_options = face_stylizer.FaceStylizerOptions( + model=face_stylizer.SupportedModels.BLAZE_FACE_STYLIZER_256, + hparams=face_stylizer.HParams(epochs=1), + ) + model = face_stylizer.FaceStylizer.create( + train_data=self._train_data, options=face_stylizer_options + ) + self._evaluate_saved_model(model) + + +if __name__ == '__main__': + tf.test.main() diff --git a/mediapipe/model_maker/python/vision/face_stylizer/model_options.py b/mediapipe/model_maker/python/vision/face_stylizer/model_options.py index 064e2d027..ff5a54eba 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/model_options.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/model_options.py @@ -13,8 +13,15 @@ # limitations under the License. """Configurable model options for face stylizer models.""" +from typing import Sequence import dataclasses -from typing import List + +from mediapipe.model_maker.python.core.utils import loss_functions + + +def _default_perceptual_quality_loss_weight(): + """Default perceptual quality loss weight for face stylizer.""" + return loss_functions.PerceptualLossWeight(l1=2.0, content=20.0, style=10.0) # TODO: Add more detailed instructions about hyperparameter tuning. @@ -26,12 +33,17 @@ class FaceStylizerModelOptions: swap_layers: The layers of feature to be interpolated between encoding features and StyleGAN input features. alpha: Weighting coefficient for swapping layer interpolation. - adv_loss_weight: Weighting coeffcieint of adversarial loss versus perceptual + perception_loss_weight: Weighting coefficients of image perception quality loss. + adv_loss_weight: Weighting coeffcieint of adversarial loss versus image + perceptual quality loss. """ - swap_layers: List[int] = dataclasses.field( + swap_layers: Sequence[int] = dataclasses.field( default_factory=lambda: [4, 5, 6, 7, 8, 9, 10, 11] ) alpha: float = 1.0 + perception_loss_weight: loss_functions.PerceptualLossWeight = ( + dataclasses.field(default_factory=_default_perceptual_quality_loss_weight) + ) adv_loss_weight: float = 1.0 From 0fc6118680a5ae1d7a424a9912b41993e684b0ae Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 25 Apr 2023 01:28:41 -0700 Subject: [PATCH 079/753] Internal change. PiperOrigin-RevId: 526892368 --- .../com/google/mediapipe/components/GlSurfaceViewRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/java/com/google/mediapipe/components/GlSurfaceViewRenderer.java b/mediapipe/java/com/google/mediapipe/components/GlSurfaceViewRenderer.java index 7732ed17d..9321e82b4 100644 --- a/mediapipe/java/com/google/mediapipe/components/GlSurfaceViewRenderer.java +++ b/mediapipe/java/com/google/mediapipe/components/GlSurfaceViewRenderer.java @@ -231,7 +231,7 @@ public class GlSurfaceViewRenderer implements GLSurfaceView.Renderer { } /** Returns the texture left, right, bottom, and top visible boundaries. */ - protected float[] calculateTextureBoundary() { + public float[] calculateTextureBoundary() { // TODO: compute scale from surfaceTexture size. float scaleWidth = frameWidth > 0 ? (float) surfaceWidth / (float) frameWidth : 1.0f; float scaleHeight = frameHeight > 0 ? (float) surfaceHeight / (float) frameHeight : 1.0f; From 3bc82766785949dfe90f3b4b0561378740f322f1 Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Tue, 25 Apr 2023 09:04:18 -0700 Subject: [PATCH 080/753] Remove "All Rights Reserved." in copyright headers. PiperOrigin-RevId: 526982992 --- docs/build_java_api_docs.py | 2 +- docs/build_model_maker_api_docs.py | 2 +- docs/build_py_api_docs.py | 2 +- mediapipe/calculators/core/merge_to_vector_calculator.cc | 2 +- mediapipe/calculators/core/merge_to_vector_calculator.h | 2 +- .../calculators/tensor/bert_preprocessor_calculator.proto | 2 +- .../calculators/tensor/regex_preprocessor_calculator.proto | 2 +- .../calculators/util/detections_deduplicate_calculator.cc | 2 +- mediapipe/framework/formats/frame_buffer.cc | 2 +- mediapipe/framework/formats/frame_buffer.h | 2 +- mediapipe/gpu/frame_buffer_view.h | 2 +- mediapipe/gpu/gpu_buffer_storage_image_frame.cc | 2 +- mediapipe/gpu/gpu_buffer_storage_image_frame.h | 2 +- mediapipe/gpu/gpu_buffer_storage_yuv_image.cc | 2 +- mediapipe/gpu/gpu_buffer_storage_yuv_image.h | 2 +- mediapipe/java/com/google/mediapipe/framework/image/BUILD | 2 +- .../com/google/mediapipe/framework/image/BitmapExtractor.java | 2 +- .../google/mediapipe/framework/image/BitmapImageBuilder.java | 2 +- .../mediapipe/framework/image/BitmapImageContainer.java | 2 +- .../google/mediapipe/framework/image/ByteBufferExtractor.java | 2 +- .../mediapipe/framework/image/ByteBufferImageBuilder.java | 2 +- .../mediapipe/framework/image/ByteBufferImageContainer.java | 2 +- .../java/com/google/mediapipe/framework/image/MPImage.java | 2 +- .../com/google/mediapipe/framework/image/MPImageConsumer.java | 2 +- .../google/mediapipe/framework/image/MPImageContainer.java | 2 +- .../com/google/mediapipe/framework/image/MPImageProducer.java | 2 +- .../google/mediapipe/framework/image/MPImageProperties.java | 2 +- .../google/mediapipe/framework/image/MediaImageBuilder.java | 2 +- .../google/mediapipe/framework/image/MediaImageContainer.java | 2 +- .../google/mediapipe/framework/image/MediaImageExtractor.java | 2 +- mediapipe/java/com/google/mediapipe/mediapipe_aar.bzl | 2 +- mediapipe/model_maker/BUILD | 2 +- mediapipe/model_maker/__init__.py | 2 +- mediapipe/model_maker/models/gesture_recognizer/BUILD | 2 +- mediapipe/model_maker/models/text_classifier/BUILD | 2 +- mediapipe/model_maker/python/BUILD | 2 +- mediapipe/model_maker/python/__init__.py | 2 +- mediapipe/model_maker/python/core/BUILD | 2 +- mediapipe/model_maker/python/core/__init__.py | 2 +- mediapipe/model_maker/python/core/data/BUILD | 2 +- mediapipe/model_maker/python/core/data/__init__.py | 2 +- .../model_maker/python/core/data/classification_dataset.py | 2 +- .../python/core/data/classification_dataset_test.py | 2 +- mediapipe/model_maker/python/core/data/data_util.py | 2 +- mediapipe/model_maker/python/core/data/data_util_test.py | 2 +- mediapipe/model_maker/python/core/data/dataset.py | 2 +- mediapipe/model_maker/python/core/data/dataset_test.py | 2 +- mediapipe/model_maker/python/core/data/testdata/BUILD | 2 +- mediapipe/model_maker/python/core/hyperparameters.py | 2 +- mediapipe/model_maker/python/core/tasks/BUILD | 2 +- mediapipe/model_maker/python/core/tasks/__init__.py | 2 +- mediapipe/model_maker/python/core/tasks/classifier.py | 2 +- mediapipe/model_maker/python/core/tasks/classifier_test.py | 2 +- mediapipe/model_maker/python/core/tasks/custom_model.py | 2 +- mediapipe/model_maker/python/core/tasks/custom_model_test.py | 2 +- mediapipe/model_maker/python/core/utils/BUILD | 2 +- mediapipe/model_maker/python/core/utils/__init__.py | 2 +- mediapipe/model_maker/python/core/utils/file_util.py | 2 +- mediapipe/model_maker/python/core/utils/file_util_test.py | 2 +- mediapipe/model_maker/python/core/utils/loss_functions.py | 2 +- .../model_maker/python/core/utils/loss_functions_test.py | 2 +- mediapipe/model_maker/python/core/utils/model_util.py | 2 +- mediapipe/model_maker/python/core/utils/model_util_test.py | 2 +- mediapipe/model_maker/python/core/utils/quantization.py | 2 +- mediapipe/model_maker/python/core/utils/quantization_test.py | 2 +- mediapipe/model_maker/python/core/utils/test_util.py | 2 +- mediapipe/model_maker/python/core/utils/testdata/BUILD | 2 +- mediapipe/model_maker/python/text/__init__.py | 2 +- mediapipe/model_maker/python/text/core/BUILD | 2 +- mediapipe/model_maker/python/text/core/__init__.py | 2 +- mediapipe/model_maker/python/text/core/bert_model_options.py | 2 +- mediapipe/model_maker/python/text/core/bert_model_spec.py | 2 +- mediapipe/model_maker/python/text/text_classifier/BUILD | 2 +- mediapipe/model_maker/python/text/text_classifier/__init__.py | 2 +- mediapipe/model_maker/python/text/text_classifier/dataset.py | 2 +- .../model_maker/python/text/text_classifier/dataset_test.py | 2 +- .../model_maker/python/text/text_classifier/model_options.py | 2 +- .../model_maker/python/text/text_classifier/model_spec.py | 2 +- .../python/text/text_classifier/model_spec_test.py | 2 +- .../model_maker/python/text/text_classifier/preprocessor.py | 2 +- .../python/text/text_classifier/preprocessor_test.py | 2 +- .../model_maker/python/text/text_classifier/testdata/BUILD | 2 +- .../python/text/text_classifier/text_classifier.py | 2 +- .../python/text/text_classifier/text_classifier_demo.py | 2 +- .../python/text/text_classifier/text_classifier_options.py | 2 +- .../python/text/text_classifier/text_classifier_test.py | 2 +- mediapipe/model_maker/python/vision/BUILD | 2 +- mediapipe/model_maker/python/vision/__init__.py | 2 +- mediapipe/model_maker/python/vision/core/BUILD | 2 +- mediapipe/model_maker/python/vision/core/__init__.py | 2 +- .../model_maker/python/vision/core/image_preprocessing.py | 2 +- .../python/vision/core/image_preprocessing_test.py | 2 +- mediapipe/model_maker/python/vision/core/image_utils.py | 2 +- mediapipe/model_maker/python/vision/core/image_utils_test.py | 2 +- mediapipe/model_maker/python/vision/core/test_utils.py | 2 +- mediapipe/model_maker/python/vision/face_stylizer/BUILD | 2 +- mediapipe/model_maker/python/vision/face_stylizer/__init__.py | 2 +- mediapipe/model_maker/python/vision/face_stylizer/dataset.py | 2 +- .../model_maker/python/vision/face_stylizer/dataset_test.py | 2 +- .../python/vision/face_stylizer/face_stylizer_options.py | 2 +- .../python/vision/face_stylizer/hyperparameters.py | 2 +- .../model_maker/python/vision/face_stylizer/model_options.py | 2 +- .../model_maker/python/vision/face_stylizer/model_spec.py | 2 +- .../python/vision/face_stylizer/model_spec_test.py | 2 +- mediapipe/model_maker/python/vision/gesture_recognizer/BUILD | 2 +- .../model_maker/python/vision/gesture_recognizer/__init__.py | 2 +- .../model_maker/python/vision/gesture_recognizer/constants.py | 2 +- .../model_maker/python/vision/gesture_recognizer/dataset.py | 2 +- .../python/vision/gesture_recognizer/dataset_test.py | 2 +- .../python/vision/gesture_recognizer/gesture_recognizer.py | 2 +- .../vision/gesture_recognizer/gesture_recognizer_demo.py | 2 +- .../vision/gesture_recognizer/gesture_recognizer_options.py | 2 +- .../vision/gesture_recognizer/gesture_recognizer_test.py | 2 +- .../python/vision/gesture_recognizer/hyperparameters.py | 2 +- .../python/vision/gesture_recognizer/metadata_writer.py | 2 +- .../python/vision/gesture_recognizer/metadata_writer_test.py | 2 +- .../python/vision/gesture_recognizer/model_options.py | 2 +- mediapipe/model_maker/python/vision/image_classifier/BUILD | 2 +- .../model_maker/python/vision/image_classifier/__init__.py | 2 +- .../model_maker/python/vision/image_classifier/dataset.py | 2 +- .../python/vision/image_classifier/dataset_test.py | 2 +- .../python/vision/image_classifier/hyperparameters.py | 2 +- .../python/vision/image_classifier/image_classifier.py | 2 +- .../python/vision/image_classifier/image_classifier_demo.py | 2 +- .../vision/image_classifier/image_classifier_options.py | 2 +- .../python/vision/image_classifier/image_classifier_test.py | 2 +- .../python/vision/image_classifier/model_options.py | 2 +- .../model_maker/python/vision/image_classifier/model_spec.py | 2 +- .../python/vision/image_classifier/model_spec_test.py | 2 +- .../model_maker/python/vision/image_classifier/testdata/BUILD | 2 +- mediapipe/model_maker/python/vision/object_detector/BUILD | 2 +- .../model_maker/python/vision/object_detector/__init__.py | 2 +- .../model_maker/python/vision/object_detector/dataset.py | 2 +- .../model_maker/python/vision/object_detector/dataset_test.py | 2 +- .../model_maker/python/vision/object_detector/dataset_util.py | 2 +- .../python/vision/object_detector/dataset_util_test.py | 2 +- .../python/vision/object_detector/hyperparameters.py | 2 +- mediapipe/model_maker/python/vision/object_detector/model.py | 2 +- .../python/vision/object_detector/model_options.py | 2 +- .../model_maker/python/vision/object_detector/model_spec.py | 2 +- .../model_maker/python/vision/object_detector/model_test.py | 2 +- .../python/vision/object_detector/object_detector.py | 2 +- .../python/vision/object_detector/object_detector_demo.py | 2 +- .../python/vision/object_detector/object_detector_options.py | 2 +- .../python/vision/object_detector/object_detector_test.py | 2 +- .../model_maker/python/vision/object_detector/preprocessor.py | 2 +- .../python/vision/object_detector/preprocessor_test.py | 2 +- mediapipe/model_maker/setup.py | 2 +- mediapipe/tasks/BUILD | 2 +- mediapipe/tasks/__init__.py | 2 +- mediapipe/tasks/cc/BUILD | 2 +- mediapipe/tasks/cc/audio/audio_classifier/BUILD | 2 +- mediapipe/tasks/cc/audio/audio_classifier/audio_classifier.cc | 2 +- mediapipe/tasks/cc/audio/audio_classifier/audio_classifier.h | 2 +- .../tasks/cc/audio/audio_classifier/audio_classifier_graph.cc | 2 +- .../tasks/cc/audio/audio_classifier/audio_classifier_test.cc | 2 +- mediapipe/tasks/cc/audio/audio_classifier/proto/BUILD | 2 +- .../proto/audio_classifier_graph_options.proto | 2 +- mediapipe/tasks/cc/audio/audio_embedder/BUILD | 2 +- mediapipe/tasks/cc/audio/audio_embedder/audio_embedder.cc | 2 +- mediapipe/tasks/cc/audio/audio_embedder/audio_embedder.h | 2 +- .../tasks/cc/audio/audio_embedder/audio_embedder_graph.cc | 2 +- .../tasks/cc/audio/audio_embedder/audio_embedder_test.cc | 2 +- mediapipe/tasks/cc/audio/audio_embedder/proto/BUILD | 2 +- .../audio_embedder/proto/audio_embedder_graph_options.proto | 2 +- mediapipe/tasks/cc/audio/core/BUILD | 2 +- mediapipe/tasks/cc/audio/core/audio_task_api_factory.h | 2 +- mediapipe/tasks/cc/audio/core/base_audio_task_api.h | 2 +- mediapipe/tasks/cc/audio/core/running_mode.h | 2 +- mediapipe/tasks/cc/audio/utils/BUILD | 2 +- mediapipe/tasks/cc/audio/utils/audio_tensor_specs.cc | 2 +- mediapipe/tasks/cc/audio/utils/audio_tensor_specs.h | 2 +- mediapipe/tasks/cc/audio/utils/audio_tensor_specs_test.cc | 2 +- mediapipe/tasks/cc/common.cc | 2 +- mediapipe/tasks/cc/common.h | 2 +- mediapipe/tasks/cc/components/calculators/BUILD | 2 +- .../calculators/classification_aggregation_calculator.proto | 2 +- .../calculators/classification_aggregation_calculator_test.cc | 2 +- .../calculators/embedding_aggregation_calculator_test.cc | 2 +- .../tasks/cc/components/calculators/end_loop_calculator.cc | 2 +- .../components/calculators/score_calibration_calculator.proto | 2 +- .../calculators/tensors_to_embeddings_calculator.proto | 2 +- mediapipe/tasks/cc/components/containers/BUILD | 2 +- mediapipe/tasks/cc/components/containers/category.cc | 2 +- mediapipe/tasks/cc/components/containers/category.h | 2 +- .../tasks/cc/components/containers/classification_result.cc | 2 +- .../tasks/cc/components/containers/classification_result.h | 2 +- mediapipe/tasks/cc/components/containers/detection_result.cc | 2 +- mediapipe/tasks/cc/components/containers/detection_result.h | 2 +- mediapipe/tasks/cc/components/containers/embedding_result.cc | 2 +- mediapipe/tasks/cc/components/containers/embedding_result.h | 2 +- mediapipe/tasks/cc/components/containers/keypoint.h | 2 +- mediapipe/tasks/cc/components/containers/landmark.cc | 2 +- mediapipe/tasks/cc/components/containers/landmark.h | 2 +- mediapipe/tasks/cc/components/containers/proto/BUILD | 2 +- .../cc/components/containers/proto/classifications.proto | 2 +- .../tasks/cc/components/containers/proto/embeddings.proto | 2 +- .../containers/proto/landmarks_detection_result.proto | 2 +- mediapipe/tasks/cc/components/containers/rect.cc | 2 +- mediapipe/tasks/cc/components/containers/rect.h | 2 +- mediapipe/tasks/cc/components/processors/BUILD | 2 +- .../processors/classification_postprocessing_graph.cc | 2 +- .../processors/classification_postprocessing_graph.h | 2 +- .../processors/classification_postprocessing_graph_test.cc | 2 +- .../tasks/cc/components/processors/classifier_options.cc | 2 +- mediapipe/tasks/cc/components/processors/classifier_options.h | 2 +- mediapipe/tasks/cc/components/processors/embedder_options.cc | 2 +- mediapipe/tasks/cc/components/processors/embedder_options.h | 2 +- .../components/processors/embedding_postprocessing_graph.cc | 2 +- .../cc/components/processors/embedding_postprocessing_graph.h | 2 +- .../processors/embedding_postprocessing_graph_test.cc | 2 +- .../cc/components/processors/image_preprocessing_graph.cc | 2 +- .../cc/components/processors/image_preprocessing_graph.h | 2 +- .../components/processors/image_preprocessing_graph_test.cc | 2 +- mediapipe/tasks/cc/components/processors/proto/BUILD | 2 +- .../proto/classification_postprocessing_graph_options.proto | 2 +- .../cc/components/processors/proto/classifier_options.proto | 2 +- .../cc/components/processors/proto/embedder_options.proto | 2 +- .../proto/embedding_postprocessing_graph_options.proto | 2 +- .../processors/proto/image_preprocessing_graph_options.proto | 2 +- .../cc/components/processors/proto/text_model_type.proto | 2 +- .../processors/proto/text_preprocessing_graph_options.proto | 2 +- .../cc/components/processors/text_preprocessing_graph.cc | 2 +- .../tasks/cc/components/processors/text_preprocessing_graph.h | 2 +- mediapipe/tasks/cc/components/utils/BUILD | 2 +- mediapipe/tasks/cc/components/utils/cosine_similarity.cc | 2 +- mediapipe/tasks/cc/components/utils/cosine_similarity.h | 2 +- mediapipe/tasks/cc/components/utils/cosine_similarity_test.cc | 2 +- mediapipe/tasks/cc/components/utils/gate.h | 2 +- mediapipe/tasks/cc/components/utils/gate_test.cc | 2 +- mediapipe/tasks/cc/core/BUILD | 2 +- mediapipe/tasks/cc/core/base_options.cc | 2 +- mediapipe/tasks/cc/core/base_options.h | 2 +- mediapipe/tasks/cc/core/base_task_api.h | 2 +- mediapipe/tasks/cc/core/external_file_handler.cc | 2 +- mediapipe/tasks/cc/core/external_file_handler.h | 2 +- mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.cc | 2 +- mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.h | 2 +- mediapipe/tasks/cc/core/model_asset_bundle_resources.cc | 2 +- mediapipe/tasks/cc/core/model_asset_bundle_resources.h | 2 +- mediapipe/tasks/cc/core/model_asset_bundle_resources_test.cc | 2 +- mediapipe/tasks/cc/core/model_resources.cc | 2 +- mediapipe/tasks/cc/core/model_resources.h | 2 +- mediapipe/tasks/cc/core/model_resources_cache.cc | 2 +- mediapipe/tasks/cc/core/model_resources_cache.h | 2 +- mediapipe/tasks/cc/core/model_resources_calculator.cc | 2 +- mediapipe/tasks/cc/core/model_resources_calculator_test.cc | 2 +- mediapipe/tasks/cc/core/model_resources_test.cc | 2 +- mediapipe/tasks/cc/core/model_task_graph.cc | 2 +- mediapipe/tasks/cc/core/model_task_graph.h | 2 +- mediapipe/tasks/cc/core/proto/BUILD | 2 +- mediapipe/tasks/cc/core/proto/acceleration.proto | 2 +- mediapipe/tasks/cc/core/proto/base_options.proto | 2 +- mediapipe/tasks/cc/core/proto/external_file.proto | 2 +- mediapipe/tasks/cc/core/proto/inference_subgraph.proto | 2 +- .../tasks/cc/core/proto/model_resources_calculator.proto | 2 +- mediapipe/tasks/cc/core/task_api_factory.h | 2 +- mediapipe/tasks/cc/core/task_runner.cc | 2 +- mediapipe/tasks/cc/core/task_runner.h | 2 +- mediapipe/tasks/cc/core/task_runner_test.cc | 2 +- mediapipe/tasks/cc/core/utils.cc | 2 +- mediapipe/tasks/cc/core/utils.h | 2 +- mediapipe/tasks/cc/metadata/metadata_extractor.cc | 2 +- mediapipe/tasks/cc/metadata/metadata_extractor.h | 2 +- mediapipe/tasks/cc/metadata/metadata_parser.h.template | 2 +- mediapipe/tasks/cc/metadata/metadata_populator.cc | 2 +- mediapipe/tasks/cc/metadata/metadata_populator.h | 2 +- mediapipe/tasks/cc/metadata/metadata_version.cc | 2 +- mediapipe/tasks/cc/metadata/metadata_version.h | 2 +- mediapipe/tasks/cc/metadata/python/metadata_version.cc | 2 +- mediapipe/tasks/cc/metadata/tests/metadata_extractor_test.cc | 2 +- mediapipe/tasks/cc/metadata/tests/metadata_parser_test.cc | 2 +- mediapipe/tasks/cc/metadata/tests/metadata_version_test.cc | 2 +- .../tasks/cc/metadata/tests/metadata_version_utils_test.cc | 2 +- mediapipe/tasks/cc/metadata/utils/zip_readonly_mem_file.cc | 2 +- mediapipe/tasks/cc/metadata/utils/zip_readonly_mem_file.h | 2 +- mediapipe/tasks/cc/metadata/utils/zip_utils.cc | 2 +- mediapipe/tasks/cc/metadata/utils/zip_utils.h | 2 +- mediapipe/tasks/cc/metadata/utils/zip_writable_mem_file.cc | 2 +- mediapipe/tasks/cc/metadata/utils/zip_writable_mem_file.h | 2 +- mediapipe/tasks/cc/text/custom_ops/ragged/BUILD | 2 +- .../text/custom_ops/ragged/ragged_tensor_to_tensor_tflite.cc | 2 +- .../text/custom_ops/ragged/ragged_tensor_to_tensor_tflite.h | 2 +- .../custom_ops/ragged/ragged_tensor_to_tensor_tflite_test.cc | 2 +- mediapipe/tasks/cc/text/custom_ops/sentencepiece/BUILD | 2 +- mediapipe/tasks/cc/text/custom_ops/sentencepiece/config.fbs | 2 +- .../cc/text/custom_ops/sentencepiece/double_array_trie.h | 2 +- .../custom_ops/sentencepiece/double_array_trie_builder.cc | 2 +- .../text/custom_ops/sentencepiece/double_array_trie_builder.h | 2 +- .../text/custom_ops/sentencepiece/double_array_trie_test.cc | 2 +- .../tasks/cc/text/custom_ops/sentencepiece/encoder_config.fbs | 2 +- .../tasks/cc/text/custom_ops/sentencepiece/model_converter.cc | 2 +- .../tasks/cc/text/custom_ops/sentencepiece/model_converter.h | 2 +- .../cc/text/custom_ops/sentencepiece/optimized_encoder.cc | 2 +- .../cc/text/custom_ops/sentencepiece/optimized_encoder.h | 2 +- .../text/custom_ops/sentencepiece/optimized_encoder_test.cc | 2 +- .../text/custom_ops/sentencepiece/sentencepiece_constants.h | 2 +- .../sentencepiece/sentencepiece_tokenizer_tflite.cc | 2 +- .../custom_ops/sentencepiece/sentencepiece_tokenizer_tflite.h | 2 +- mediapipe/tasks/cc/text/custom_ops/sentencepiece/utils.h | 2 +- mediapipe/tasks/cc/text/language_detector/BUILD | 2 +- mediapipe/tasks/cc/text/language_detector/custom_ops/BUILD | 2 +- .../language_detector/custom_ops/kmeans_embedding_lookup.cc | 2 +- .../language_detector/custom_ops/kmeans_embedding_lookup.h | 2 +- .../tasks/cc/text/language_detector/custom_ops/ngram_hash.cc | 2 +- .../tasks/cc/text/language_detector/custom_ops/ngram_hash.h | 2 +- .../cc/text/language_detector/custom_ops/ngram_hash_test.cc | 2 +- .../tasks/cc/text/language_detector/custom_ops/utils/BUILD | 2 +- .../cc/text/language_detector/custom_ops/utils/hash/BUILD | 2 +- .../cc/text/language_detector/custom_ops/utils/hash/murmur.cc | 4 ++-- .../cc/text/language_detector/custom_ops/utils/hash/murmur.h | 4 ++-- .../language_detector/custom_ops/utils/hash/murmur_test.cc | 4 ++-- .../custom_ops/utils/ngram_hash_ops_utils.cc | 2 +- .../language_detector/custom_ops/utils/ngram_hash_ops_utils.h | 2 +- .../custom_ops/utils/ngram_hash_ops_utils_test.cc | 2 +- .../cc/text/language_detector/custom_ops/utils/utf/BUILD | 2 +- .../cc/text/language_detector/custom_ops/utils/utf/rune.c | 2 +- .../cc/text/language_detector/custom_ops/utils/utf/runetype.c | 2 +- .../language_detector/custom_ops/utils/utf/runetypebody.h | 2 +- .../cc/text/language_detector/custom_ops/utils/utf/utf.h | 2 +- .../tasks/cc/text/language_detector/language_detector.cc | 2 +- mediapipe/tasks/cc/text/language_detector/language_detector.h | 2 +- .../tasks/cc/text/language_detector/language_detector_test.cc | 2 +- mediapipe/tasks/cc/text/text_classifier/BUILD | 2 +- mediapipe/tasks/cc/text/text_classifier/proto/BUILD | 2 +- .../text_classifier/proto/text_classifier_graph_options.proto | 2 +- mediapipe/tasks/cc/text/text_classifier/text_classifier.cc | 2 +- mediapipe/tasks/cc/text/text_classifier/text_classifier.h | 2 +- .../tasks/cc/text/text_classifier/text_classifier_graph.cc | 2 +- .../tasks/cc/text/text_classifier/text_classifier_test.cc | 2 +- .../cc/text/text_classifier/text_classifier_test_utils.cc | 2 +- .../cc/text/text_classifier/text_classifier_test_utils.h | 2 +- mediapipe/tasks/cc/text/text_embedder/BUILD | 2 +- mediapipe/tasks/cc/text/text_embedder/proto/BUILD | 2 +- .../text_embedder/proto/text_embedder_graph_options.proto | 2 +- mediapipe/tasks/cc/text/text_embedder/text_embedder.cc | 2 +- mediapipe/tasks/cc/text/text_embedder/text_embedder.h | 2 +- mediapipe/tasks/cc/text/text_embedder/text_embedder_graph.cc | 2 +- mediapipe/tasks/cc/text/text_embedder/text_embedder_test.cc | 2 +- mediapipe/tasks/cc/text/tokenizers/BUILD | 2 +- mediapipe/tasks/cc/text/tokenizers/bert_tokenizer.cc | 2 +- mediapipe/tasks/cc/text/tokenizers/bert_tokenizer.h | 2 +- mediapipe/tasks/cc/text/tokenizers/bert_tokenizer_test.cc | 2 +- mediapipe/tasks/cc/text/tokenizers/regex_tokenizer.cc | 2 +- mediapipe/tasks/cc/text/tokenizers/regex_tokenizer.h | 2 +- mediapipe/tasks/cc/text/tokenizers/regex_tokenizer_test.cc | 2 +- mediapipe/tasks/cc/text/tokenizers/sentencepiece_tokenizer.h | 2 +- .../tasks/cc/text/tokenizers/sentencepiece_tokenizer_test.cc | 2 +- mediapipe/tasks/cc/text/tokenizers/tokenizer.h | 2 +- mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.cc | 2 +- mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.h | 2 +- mediapipe/tasks/cc/text/tokenizers/tokenizer_utils_test.cc | 2 +- mediapipe/tasks/cc/text/utils/BUILD | 2 +- mediapipe/tasks/cc/text/utils/text_model_utils.cc | 2 +- mediapipe/tasks/cc/text/utils/text_model_utils.h | 2 +- mediapipe/tasks/cc/text/utils/text_model_utils_test.cc | 2 +- mediapipe/tasks/cc/text/utils/vocab_utils.cc | 2 +- mediapipe/tasks/cc/text/utils/vocab_utils.h | 2 +- mediapipe/tasks/cc/text/utils/vocab_utils_test.cc | 2 +- mediapipe/tasks/cc/vision/core/BUILD | 2 +- mediapipe/tasks/cc/vision/core/base_vision_task_api.h | 2 +- mediapipe/tasks/cc/vision/core/image_processing_options.h | 2 +- mediapipe/tasks/cc/vision/core/running_mode.h | 2 +- mediapipe/tasks/cc/vision/core/vision_task_api_factory.h | 2 +- mediapipe/tasks/cc/vision/face_detector/BUILD | 2 +- mediapipe/tasks/cc/vision/face_detector/face_detector.cc | 2 +- mediapipe/tasks/cc/vision/face_detector/face_detector.h | 2 +- .../tasks/cc/vision/face_detector/face_detector_graph.cc | 2 +- .../tasks/cc/vision/face_detector/face_detector_graph_test.cc | 2 +- mediapipe/tasks/cc/vision/face_detector/face_detector_test.cc | 2 +- mediapipe/tasks/cc/vision/face_detector/proto/BUILD | 2 +- .../face_detector/proto/face_detector_graph_options.proto | 2 +- .../face_geometry/face_geometry_from_landmarks_graph.cc | 2 +- .../face_geometry/face_geometry_from_landmarks_graph_test.cc | 2 +- mediapipe/tasks/cc/vision/face_landmarker/BUILD | 2 +- .../tasks/cc/vision/face_landmarker/face_blendshapes_graph.cc | 2 +- .../cc/vision/face_landmarker/face_blendshapes_graph_test.cc | 2 +- mediapipe/tasks/cc/vision/face_landmarker/face_landmarker.cc | 2 +- mediapipe/tasks/cc/vision/face_landmarker/face_landmarker.h | 2 +- .../tasks/cc/vision/face_landmarker/face_landmarker_graph.cc | 2 +- .../cc/vision/face_landmarker/face_landmarker_graph_test.cc | 2 +- .../tasks/cc/vision/face_landmarker/face_landmarker_result.cc | 2 +- .../tasks/cc/vision/face_landmarker/face_landmarker_result.h | 2 +- .../cc/vision/face_landmarker/face_landmarker_result_test.cc | 2 +- .../tasks/cc/vision/face_landmarker/face_landmarker_test.cc | 2 +- .../vision/face_landmarker/face_landmarks_detector_graph.cc | 2 +- .../face_landmarker/face_landmarks_detector_graph_test.cc | 2 +- mediapipe/tasks/cc/vision/face_landmarker/proto/BUILD | 2 +- .../proto/face_blendshapes_graph_options.proto | 2 +- .../face_landmarker/proto/face_landmarker_graph_options.proto | 2 +- .../proto/face_landmarks_detector_graph_options.proto | 2 +- .../proto/tensors_to_face_landmarks_graph_options.proto | 2 +- .../vision/face_landmarker/tensors_to_face_landmarks_graph.cc | 2 +- mediapipe/tasks/cc/vision/face_stylizer/BUILD | 2 +- mediapipe/tasks/cc/vision/face_stylizer/calculators/BUILD | 2 +- .../face_stylizer/calculators/strip_rotation_calculator.cc | 2 +- mediapipe/tasks/cc/vision/face_stylizer/face_stylizer.cc | 2 +- mediapipe/tasks/cc/vision/face_stylizer/face_stylizer.h | 2 +- .../tasks/cc/vision/face_stylizer/face_stylizer_graph.cc | 2 +- mediapipe/tasks/cc/vision/face_stylizer/proto/BUILD | 2 +- .../face_stylizer/proto/face_stylizer_graph_options.proto | 2 +- mediapipe/tasks/cc/vision/gesture_recognizer/BUILD | 2 +- .../tasks/cc/vision/gesture_recognizer/calculators/BUILD | 2 +- .../calculators/combined_prediction_calculator.cc | 2 +- .../calculators/combined_prediction_calculator.proto | 2 +- .../calculators/combined_prediction_calculator_test.cc | 2 +- .../calculators/handedness_to_matrix_calculator.cc | 2 +- .../calculators/handedness_to_matrix_calculator_test.cc | 2 +- .../calculators/landmarks_to_matrix_calculator.cc | 2 +- .../calculators/landmarks_to_matrix_calculator.proto | 2 +- .../calculators/landmarks_to_matrix_calculator_test.cc | 2 +- .../tasks/cc/vision/gesture_recognizer/gesture_recognizer.cc | 2 +- .../tasks/cc/vision/gesture_recognizer/gesture_recognizer.h | 2 +- .../cc/vision/gesture_recognizer/gesture_recognizer_graph.cc | 2 +- .../cc/vision/gesture_recognizer/gesture_recognizer_result.h | 2 +- .../gesture_recognizer/hand_gesture_recognizer_graph.cc | 2 +- .../tasks/cc/vision/gesture_recognizer/handedness_util.cc | 2 +- .../tasks/cc/vision/gesture_recognizer/handedness_util.h | 2 +- .../cc/vision/gesture_recognizer/handedness_util_test.cc | 2 +- mediapipe/tasks/cc/vision/gesture_recognizer/proto/BUILD | 2 +- .../proto/gesture_classifier_graph_options.proto | 2 +- .../proto/gesture_embedder_graph_options.proto | 2 +- .../proto/gesture_recognizer_graph_options.proto | 2 +- .../proto/hand_gesture_recognizer_graph_options.proto | 2 +- mediapipe/tasks/cc/vision/hand_detector/BUILD | 2 +- .../tasks/cc/vision/hand_detector/hand_detector_graph.cc | 2 +- .../tasks/cc/vision/hand_detector/hand_detector_graph_test.cc | 2 +- mediapipe/tasks/cc/vision/hand_detector/proto/BUILD | 2 +- .../hand_detector/proto/hand_detector_graph_options.proto | 2 +- .../cc/vision/hand_detector/proto/hand_detector_result.proto | 2 +- mediapipe/tasks/cc/vision/hand_landmarker/BUILD | 2 +- mediapipe/tasks/cc/vision/hand_landmarker/calculators/BUILD | 2 +- .../calculators/hand_association_calculator.cc | 2 +- .../calculators/hand_association_calculator.proto | 2 +- .../calculators/hand_association_calculator_test.cc | 2 +- .../calculators/hand_landmarks_deduplication_calculator.cc | 2 +- .../calculators/hand_landmarks_deduplication_calculator.h | 2 +- mediapipe/tasks/cc/vision/hand_landmarker/hand_landmark.h | 2 +- mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker.cc | 2 +- mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker.h | 2 +- .../tasks/cc/vision/hand_landmarker/hand_landmarker_graph.cc | 2 +- .../cc/vision/hand_landmarker/hand_landmarker_graph_test.cc | 2 +- .../tasks/cc/vision/hand_landmarker/hand_landmarker_result.cc | 2 +- .../tasks/cc/vision/hand_landmarker/hand_landmarker_result.h | 2 +- .../cc/vision/hand_landmarker/hand_landmarker_result_test.cc | 2 +- .../tasks/cc/vision/hand_landmarker/hand_landmarker_test.cc | 2 +- .../vision/hand_landmarker/hand_landmarks_detector_graph.cc | 2 +- .../hand_landmarker/hand_landmarks_detector_graph_test.cc | 2 +- mediapipe/tasks/cc/vision/hand_landmarker/proto/BUILD | 2 +- .../hand_landmarker/proto/hand_landmarker_graph_options.proto | 2 +- .../proto/hand_landmarks_detector_graph_options.proto | 2 +- mediapipe/tasks/cc/vision/image_classifier/BUILD | 2 +- .../tasks/cc/vision/image_classifier/image_classifier.cc | 2 +- mediapipe/tasks/cc/vision/image_classifier/image_classifier.h | 2 +- .../cc/vision/image_classifier/image_classifier_graph.cc | 2 +- .../tasks/cc/vision/image_classifier/image_classifier_test.cc | 2 +- mediapipe/tasks/cc/vision/image_classifier/proto/BUILD | 2 +- .../proto/image_classifier_graph_options.proto | 2 +- mediapipe/tasks/cc/vision/image_embedder/BUILD | 2 +- mediapipe/tasks/cc/vision/image_embedder/image_embedder.cc | 2 +- mediapipe/tasks/cc/vision/image_embedder/image_embedder.h | 2 +- .../tasks/cc/vision/image_embedder/image_embedder_graph.cc | 2 +- .../tasks/cc/vision/image_embedder/image_embedder_test.cc | 2 +- mediapipe/tasks/cc/vision/image_embedder/proto/BUILD | 2 +- .../image_embedder/proto/image_embedder_graph_options.proto | 2 +- mediapipe/tasks/cc/vision/image_segmenter/BUILD | 2 +- mediapipe/tasks/cc/vision/image_segmenter/calculators/BUILD | 2 +- .../calculators/tensors_to_segmentation_calculator.cc | 2 +- .../calculators/tensors_to_segmentation_calculator.proto | 2 +- .../calculators/tensors_to_segmentation_calculator_test.cc | 2 +- mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.cc | 2 +- mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.h | 2 +- .../tasks/cc/vision/image_segmenter/image_segmenter_graph.cc | 2 +- .../tasks/cc/vision/image_segmenter/image_segmenter_result.h | 2 +- .../tasks/cc/vision/image_segmenter/image_segmenter_test.cc | 2 +- mediapipe/tasks/cc/vision/image_segmenter/proto/BUILD | 2 +- .../image_segmenter/proto/image_segmenter_graph_options.proto | 2 +- .../cc/vision/image_segmenter/proto/segmenter_options.proto | 2 +- mediapipe/tasks/cc/vision/interactive_segmenter/BUILD | 2 +- .../cc/vision/interactive_segmenter/interactive_segmenter.cc | 2 +- .../cc/vision/interactive_segmenter/interactive_segmenter.h | 2 +- .../interactive_segmenter/interactive_segmenter_graph.cc | 2 +- .../interactive_segmenter/interactive_segmenter_test.cc | 2 +- mediapipe/tasks/cc/vision/object_detector/BUILD | 2 +- mediapipe/tasks/cc/vision/object_detector/object_detector.cc | 2 +- mediapipe/tasks/cc/vision/object_detector/object_detector.h | 2 +- .../tasks/cc/vision/object_detector/object_detector_graph.cc | 2 +- .../tasks/cc/vision/object_detector/object_detector_test.cc | 2 +- mediapipe/tasks/cc/vision/object_detector/proto/BUILD | 2 +- .../object_detector/proto/object_detector_options.proto | 2 +- mediapipe/tasks/cc/vision/pose_detector/BUILD | 2 +- .../tasks/cc/vision/pose_detector/pose_detector_graph.cc | 2 +- .../tasks/cc/vision/pose_detector/pose_detector_graph_test.cc | 2 +- mediapipe/tasks/cc/vision/pose_detector/proto/BUILD | 2 +- .../pose_detector/proto/pose_detector_graph_options.proto | 2 +- mediapipe/tasks/cc/vision/pose_landmarker/BUILD | 2 +- mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.cc | 2 +- mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.h | 2 +- .../tasks/cc/vision/pose_landmarker/pose_landmarker_graph.cc | 2 +- .../cc/vision/pose_landmarker/pose_landmarker_graph_test.cc | 2 +- .../tasks/cc/vision/pose_landmarker/pose_landmarker_result.cc | 2 +- .../tasks/cc/vision/pose_landmarker/pose_landmarker_result.h | 2 +- .../cc/vision/pose_landmarker/pose_landmarker_result_test.cc | 2 +- .../tasks/cc/vision/pose_landmarker/pose_landmarker_test.cc | 2 +- .../vision/pose_landmarker/pose_landmarks_detector_graph.cc | 2 +- .../pose_landmarker/pose_landmarks_detector_graph_test.cc | 2 +- mediapipe/tasks/cc/vision/pose_landmarker/proto/BUILD | 2 +- .../pose_landmarker/proto/pose_landmarker_graph_options.proto | 2 +- .../proto/pose_landmarks_detector_graph_options.proto | 2 +- mediapipe/tasks/cc/vision/utils/BUILD | 2 +- mediapipe/tasks/cc/vision/utils/image_tensor_specs.cc | 2 +- mediapipe/tasks/cc/vision/utils/image_tensor_specs.h | 2 +- mediapipe/tasks/cc/vision/utils/image_tensor_specs_test.cc | 2 +- mediapipe/tasks/cc/vision/utils/image_utils.cc | 2 +- mediapipe/tasks/cc/vision/utils/image_utils.h | 2 +- mediapipe/tasks/cc/vision/utils/landmarks_duplicates_finder.h | 2 +- mediapipe/tasks/cc/vision/utils/landmarks_utils.cc | 2 +- mediapipe/tasks/cc/vision/utils/landmarks_utils.h | 2 +- mediapipe/tasks/cc/vision/utils/landmarks_utils_test.cc | 2 +- mediapipe/tasks/examples/android/BUILD | 2 +- .../tasks/examples/android/objectdetector/src/main/BUILD | 2 +- .../mediapipe/tasks/examples/objectdetector/MainActivity.java | 2 +- .../objectdetector/ObjectDetectionResultImageView.java | 2 +- mediapipe/tasks/ios/common/BUILD | 2 +- mediapipe/tasks/ios/common/sources/MPPCommon.h | 2 +- mediapipe/tasks/ios/common/utils/BUILD | 2 +- mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h | 2 +- mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.mm | 2 +- mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h | 2 +- mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm | 2 +- mediapipe/tasks/ios/components/containers/BUILD | 2 +- mediapipe/tasks/ios/components/containers/utils/BUILD | 2 +- mediapipe/tasks/ios/components/processors/BUILD | 2 +- .../ios/components/processors/sources/MPPClassifierOptions.h | 2 +- .../ios/components/processors/sources/MPPClassifierOptions.m | 2 +- mediapipe/tasks/ios/components/processors/utils/BUILD | 2 +- mediapipe/tasks/ios/components/utils/BUILD | 2 +- .../tasks/ios/components/utils/sources/MPPCosineSimilarity.h | 2 +- .../tasks/ios/components/utils/sources/MPPCosineSimilarity.mm | 2 +- mediapipe/tasks/ios/core/BUILD | 2 +- mediapipe/tasks/ios/core/sources/MPPBaseOptions.h | 2 +- mediapipe/tasks/ios/core/sources/MPPBaseOptions.m | 2 +- mediapipe/tasks/ios/core/sources/MPPTaskOptions.h | 2 +- mediapipe/tasks/ios/core/sources/MPPTaskOptions.m | 2 +- mediapipe/tasks/ios/core/sources/MPPTaskOptionsProtocol.h | 2 +- mediapipe/tasks/ios/core/sources/MPPTaskResult.h | 2 +- mediapipe/tasks/ios/core/sources/MPPTaskResult.m | 2 +- mediapipe/tasks/ios/core/utils/BUILD | 2 +- mediapipe/tasks/ios/text/core/BUILD | 2 +- mediapipe/tasks/ios/text/text_classifier/BUILD | 2 +- mediapipe/tasks/ios/text/text_classifier/utils/BUILD | 2 +- mediapipe/tasks/ios/text/text_embedder/BUILD | 2 +- mediapipe/tasks/ios/text/text_embedder/utils/BUILD | 2 +- mediapipe/tasks/ios/vision/core/sources/MPPRunningMode.h | 2 +- mediapipe/tasks/ios/vision/gesture_recognizer/BUILD | 2 +- mediapipe/tasks/ios/vision/image_classifier/BUILD | 2 +- mediapipe/tasks/ios/vision/image_classifier/utils/BUILD | 2 +- mediapipe/tasks/ios/vision/object_detector/BUILD | 2 +- mediapipe/tasks/ios/vision/object_detector/utils/BUILD | 2 +- mediapipe/tasks/java/BUILD | 2 +- mediapipe/tasks/java/com/google/mediapipe/tasks/BUILD | 2 +- mediapipe/tasks/java/com/google/mediapipe/tasks/audio/BUILD | 2 +- .../tasks/audio/audioclassifier/AudioClassifier.java | 2 +- .../tasks/audio/audioclassifier/AudioClassifierResult.java | 2 +- .../mediapipe/tasks/audio/audioembedder/AudioEmbedder.java | 2 +- .../tasks/audio/audioembedder/AudioEmbedderResult.java | 2 +- .../google/mediapipe/tasks/audio/core/BaseAudioTaskApi.java | 2 +- .../com/google/mediapipe/tasks/audio/core/RunningMode.java | 2 +- .../mediapipe/tasks/components/containers/AudioData.java | 2 +- .../com/google/mediapipe/tasks/components/containers/BUILD | 2 +- .../mediapipe/tasks/components/containers/Category.java | 2 +- .../tasks/components/containers/ClassificationResult.java | 2 +- .../tasks/components/containers/Classifications.java | 2 +- .../mediapipe/tasks/components/containers/Detection.java | 2 +- .../mediapipe/tasks/components/containers/Embedding.java | 2 +- .../tasks/components/containers/EmbeddingResult.java | 2 +- .../mediapipe/tasks/components/containers/Landmark.java | 2 +- .../tasks/components/containers/NormalizedKeypoint.java | 2 +- .../tasks/components/containers/NormalizedLandmark.java | 2 +- .../com/google/mediapipe/tasks/components/processors/BUILD | 2 +- .../tasks/components/processors/ClassifierOptions.java | 2 +- .../java/com/google/mediapipe/tasks/components/utils/BUILD | 2 +- .../mediapipe/tasks/components/utils/CosineSimilarity.java | 2 +- mediapipe/tasks/java/com/google/mediapipe/tasks/core/BUILD | 2 +- .../java/com/google/mediapipe/tasks/core/BaseOptions.java | 2 +- .../tasks/java/com/google/mediapipe/tasks/core/Delegate.java | 2 +- .../java/com/google/mediapipe/tasks/core/ErrorListener.java | 2 +- .../com/google/mediapipe/tasks/core/ModelResourcesCache.java | 2 +- .../mediapipe/tasks/core/ModelResourcesCacheService.java | 2 +- .../java/com/google/mediapipe/tasks/core/OutputHandler.java | 2 +- .../tasks/java/com/google/mediapipe/tasks/core/TaskInfo.java | 2 +- .../java/com/google/mediapipe/tasks/core/TaskOptions.java | 2 +- .../java/com/google/mediapipe/tasks/core/TaskResult.java | 2 +- .../java/com/google/mediapipe/tasks/core/TaskRunner.java | 2 +- .../tasks/java/com/google/mediapipe/tasks/core/jni/BUILD | 2 +- .../java/com/google/mediapipe/tasks/core/jni/BUILD.bazel | 2 +- .../mediapipe/tasks/core/jni/model_resources_cache_jni.cc | 2 +- .../mediapipe/tasks/core/jni/model_resources_cache_jni.h | 2 +- .../mediapipe/tasks/core/logging/TasksStatsDummyLogger.java | 2 +- .../google/mediapipe/tasks/core/logging/TasksStatsLogger.java | 2 +- .../java/com/google/mediapipe/tasks/mediapipe_tasks_aar.bzl | 2 +- mediapipe/tasks/java/com/google/mediapipe/tasks/text/BUILD | 2 +- .../tasks/text/languagedetector/LanguageDetector.java | 2 +- .../tasks/text/languagedetector/LanguageDetectorResult.java | 2 +- .../tasks/text/languagedetector/LanguagePrediction.java | 2 +- .../mediapipe/tasks/text/textclassifier/TextClassifier.java | 2 +- .../tasks/text/textclassifier/TextClassifierResult.java | 2 +- .../mediapipe/tasks/text/textembedder/TextEmbedder.java | 2 +- .../mediapipe/tasks/text/textembedder/TextEmbedderResult.java | 2 +- mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD | 2 +- .../google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java | 2 +- .../mediapipe/tasks/vision/core/ImageProcessingOptions.java | 2 +- .../com/google/mediapipe/tasks/vision/core/RunningMode.java | 2 +- .../mediapipe/tasks/vision/facedetector/FaceDetector.java | 2 +- .../tasks/vision/facedetector/FaceDetectorResult.java | 2 +- .../mediapipe/tasks/vision/facelandmarker/FaceLandmarker.java | 2 +- .../tasks/vision/facelandmarker/FaceLandmarkerResult.java | 2 +- .../tasks/vision/facelandmarker/FaceLandmarksConnections.java | 2 +- .../mediapipe/tasks/vision/facestylizer/FaceStylizer.java | 2 +- .../tasks/vision/facestylizer/FaceStylizerResult.java | 2 +- .../tasks/vision/gesturerecognizer/GestureRecognizer.java | 2 +- .../vision/gesturerecognizer/GestureRecognizerResult.java | 2 +- .../mediapipe/tasks/vision/handlandmarker/HandLandmark.java | 2 +- .../mediapipe/tasks/vision/handlandmarker/HandLandmarker.java | 2 +- .../tasks/vision/handlandmarker/HandLandmarkerResult.java | 2 +- .../tasks/vision/imageclassifier/ImageClassifier.java | 2 +- .../tasks/vision/imageclassifier/ImageClassifierResult.java | 2 +- .../mediapipe/tasks/vision/imageembedder/ImageEmbedder.java | 2 +- .../tasks/vision/imageembedder/ImageEmbedderResult.java | 2 +- .../mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java | 2 +- .../tasks/vision/imagesegmenter/ImageSegmenterResult.java | 2 +- .../vision/interactivesegmenter/InteractiveSegmenter.java | 2 +- .../tasks/vision/objectdetector/ObjectDetectionResult.java | 2 +- .../mediapipe/tasks/vision/objectdetector/ObjectDetector.java | 2 +- .../mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java | 2 +- .../tasks/vision/poselandmarker/PoseLandmarkerResult.java | 2 +- .../com/google/mediapipe/tasks/components/utils/BUILD | 2 +- .../tasks/components/utils/CosineSimilarityTest.java | 2 +- .../tasks/javatests/com/google/mediapipe/tasks/core/BUILD | 2 +- .../javatests/com/google/mediapipe/tasks/core/TestUtils.java | 2 +- .../com/google/mediapipe/tasks/text/languagedetector/BUILD | 2 +- .../tasks/text/languagedetector/LanguageDetectorTest.java | 2 +- .../com/google/mediapipe/tasks/text/textclassifier/BUILD | 2 +- .../tasks/text/textclassifier/TextClassifierTest.java | 2 +- .../com/google/mediapipe/tasks/text/textembedder/BUILD | 2 +- .../mediapipe/tasks/text/textembedder/TextEmbedderTest.java | 2 +- .../javatests/com/google/mediapipe/tasks/vision/core/BUILD | 2 +- .../tasks/vision/core/ImageProcessingOptionsTest.java | 2 +- .../com/google/mediapipe/tasks/vision/facedetector/BUILD | 2 +- .../mediapipe/tasks/vision/facedetector/FaceDetectorTest.java | 2 +- .../com/google/mediapipe/tasks/vision/facelandmarker/BUILD | 2 +- .../tasks/vision/facelandmarker/FaceLandmarkerTest.java | 2 +- .../com/google/mediapipe/tasks/vision/facestylizer/BUILD | 2 +- .../mediapipe/tasks/vision/facestylizer/FaceStylizerTest.java | 2 +- .../com/google/mediapipe/tasks/vision/gesturerecognizer/BUILD | 2 +- .../tasks/vision/gesturerecognizer/GestureRecognizerTest.java | 2 +- .../com/google/mediapipe/tasks/vision/handlandmarker/BUILD | 2 +- .../tasks/vision/handlandmarker/HandLandmarkerTest.java | 2 +- .../com/google/mediapipe/tasks/vision/imageclassifier/BUILD | 2 +- .../tasks/vision/imageclassifier/ImageClassifierTest.java | 2 +- .../com/google/mediapipe/tasks/vision/imageembedder/BUILD | 2 +- .../tasks/vision/imageembedder/ImageEmbedderTest.java | 2 +- .../com/google/mediapipe/tasks/vision/imagesegmenter/BUILD | 2 +- .../tasks/vision/imagesegmenter/ImageSegmenterTest.java | 2 +- .../google/mediapipe/tasks/vision/interactivesegmenter/BUILD | 2 +- .../vision/interactivesegmenter/InteractiveSegmenterTest.java | 2 +- .../com/google/mediapipe/tasks/vision/objectdetector/BUILD | 2 +- .../tasks/vision/objectdetector/ObjectDetectorTest.java | 2 +- .../com/google/mediapipe/tasks/vision/poselandmarker/BUILD | 2 +- .../tasks/vision/poselandmarker/PoseLandmarkerTest.java | 2 +- mediapipe/tasks/metadata/image_segmenter_metadata_schema.fbs | 2 +- mediapipe/tasks/metadata/metadata_schema.fbs | 2 +- mediapipe/tasks/python/BUILD | 2 +- mediapipe/tasks/python/__init__.py | 2 +- mediapipe/tasks/python/audio/BUILD | 2 +- mediapipe/tasks/python/audio/__init__.py | 2 +- mediapipe/tasks/python/audio/audio_classifier.py | 2 +- mediapipe/tasks/python/audio/audio_embedder.py | 2 +- mediapipe/tasks/python/audio/core/BUILD | 2 +- mediapipe/tasks/python/audio/core/audio_record.py | 2 +- mediapipe/tasks/python/audio/core/audio_task_running_mode.py | 2 +- mediapipe/tasks/python/audio/core/base_audio_task_api.py | 2 +- mediapipe/tasks/python/components/__init__.py | 2 +- mediapipe/tasks/python/components/containers/BUILD | 2 +- mediapipe/tasks/python/components/containers/__init__.py | 2 +- mediapipe/tasks/python/components/containers/audio_data.py | 2 +- mediapipe/tasks/python/components/containers/bounding_box.py | 2 +- mediapipe/tasks/python/components/containers/category.py | 2 +- .../python/components/containers/classification_result.py | 2 +- mediapipe/tasks/python/components/containers/detections.py | 2 +- .../tasks/python/components/containers/embedding_result.py | 2 +- mediapipe/tasks/python/components/containers/keypoint.py | 2 +- mediapipe/tasks/python/components/containers/landmark.py | 2 +- .../python/components/containers/landmark_detection_result.py | 2 +- mediapipe/tasks/python/components/containers/rect.py | 2 +- mediapipe/tasks/python/components/processors/BUILD | 2 +- mediapipe/tasks/python/components/processors/__init__.py | 2 +- .../tasks/python/components/processors/classifier_options.py | 2 +- mediapipe/tasks/python/components/utils/BUILD | 2 +- mediapipe/tasks/python/components/utils/__init__.py | 2 +- mediapipe/tasks/python/components/utils/cosine_similarity.py | 2 +- mediapipe/tasks/python/core/BUILD | 2 +- mediapipe/tasks/python/core/__init__.py | 2 +- mediapipe/tasks/python/core/base_options.py | 2 +- mediapipe/tasks/python/core/optional_dependencies.py | 2 +- mediapipe/tasks/python/core/pybind/BUILD | 2 +- mediapipe/tasks/python/core/pybind/task_runner.cc | 2 +- mediapipe/tasks/python/core/pybind/task_runner.h | 2 +- mediapipe/tasks/python/core/task_info.py | 2 +- mediapipe/tasks/python/metadata/__init__.py | 2 +- .../tasks/python/metadata/flatbuffers_lib/flatbuffers_lib.cc | 2 +- mediapipe/tasks/python/metadata/metadata.py | 2 +- mediapipe/tasks/python/metadata/metadata_displayer_cli.py | 2 +- mediapipe/tasks/python/metadata/metadata_parser.py.template | 2 +- mediapipe/tasks/python/metadata/metadata_writers/__init__.py | 2 +- .../python/metadata/metadata_writers/image_classifier.py | 2 +- .../tasks/python/metadata/metadata_writers/image_segmenter.py | 2 +- .../tasks/python/metadata/metadata_writers/metadata_info.py | 2 +- .../tasks/python/metadata/metadata_writers/metadata_writer.py | 2 +- .../metadata/metadata_writers/model_asset_bundle_utils.py | 2 +- .../tasks/python/metadata/metadata_writers/object_detector.py | 2 +- .../tasks/python/metadata/metadata_writers/text_classifier.py | 2 +- .../tasks/python/metadata/metadata_writers/writer_utils.py | 2 +- mediapipe/tasks/python/test/BUILD | 2 +- mediapipe/tasks/python/test/__init__.py | 2 +- mediapipe/tasks/python/test/audio/BUILD | 2 +- mediapipe/tasks/python/test/audio/__init__.py | 2 +- mediapipe/tasks/python/test/audio/audio_classifier_test.py | 2 +- mediapipe/tasks/python/test/audio/audio_embedder_test.py | 2 +- mediapipe/tasks/python/test/audio/core/BUILD | 2 +- mediapipe/tasks/python/test/audio/core/audio_record_test.py | 2 +- mediapipe/tasks/python/test/metadata/metadata_parser_test.py | 2 +- mediapipe/tasks/python/test/metadata/metadata_test.py | 2 +- .../test/metadata/metadata_writers/image_classifier_test.py | 2 +- .../test/metadata/metadata_writers/image_segmenter_test.py | 2 +- .../test/metadata/metadata_writers/metadata_info_test.py | 2 +- .../test/metadata/metadata_writers/metadata_writer_test.py | 2 +- .../metadata_writers/model_asset_bundle_utils_test.py | 2 +- .../test/metadata/metadata_writers/object_detector_test.py | 2 +- .../test/metadata/metadata_writers/text_classifier_test.py | 2 +- mediapipe/tasks/python/test/test_utils.py | 2 +- mediapipe/tasks/python/test/text/BUILD | 2 +- mediapipe/tasks/python/test/text/__init__.py | 2 +- mediapipe/tasks/python/test/text/text_classifier_test.py | 2 +- mediapipe/tasks/python/test/text/text_embedder_test.py | 2 +- mediapipe/tasks/python/test/vision/BUILD | 2 +- mediapipe/tasks/python/test/vision/__init__.py | 2 +- mediapipe/tasks/python/test/vision/face_detector_test.py | 2 +- mediapipe/tasks/python/test/vision/face_landmarker_test.py | 2 +- mediapipe/tasks/python/test/vision/hand_landmarker_test.py | 2 +- mediapipe/tasks/python/test/vision/image_classifier_test.py | 2 +- mediapipe/tasks/python/test/vision/image_embedder_test.py | 2 +- mediapipe/tasks/python/test/vision/image_segmenter_test.py | 2 +- .../tasks/python/test/vision/interactive_segmenter_test.py | 2 +- mediapipe/tasks/python/test/vision/object_detector_test.py | 2 +- mediapipe/tasks/python/text/BUILD | 2 +- mediapipe/tasks/python/text/__init__.py | 2 +- mediapipe/tasks/python/text/core/BUILD | 2 +- mediapipe/tasks/python/text/core/base_text_task_api.py | 2 +- mediapipe/tasks/python/text/text_classifier.py | 2 +- mediapipe/tasks/python/text/text_embedder.py | 2 +- mediapipe/tasks/python/vision/BUILD | 2 +- mediapipe/tasks/python/vision/__init__.py | 2 +- mediapipe/tasks/python/vision/core/BUILD | 2 +- mediapipe/tasks/python/vision/core/__init__.py | 2 +- mediapipe/tasks/python/vision/core/base_vision_task_api.py | 2 +- .../tasks/python/vision/core/image_processing_options.py | 2 +- .../tasks/python/vision/core/vision_task_running_mode.py | 2 +- mediapipe/tasks/python/vision/face_detector.py | 2 +- mediapipe/tasks/python/vision/face_landmarker.py | 2 +- mediapipe/tasks/python/vision/face_stylizer.py | 2 +- mediapipe/tasks/python/vision/gesture_recognizer.py | 2 +- mediapipe/tasks/python/vision/hand_landmarker.py | 2 +- mediapipe/tasks/python/vision/image_classifier.py | 2 +- mediapipe/tasks/python/vision/image_embedder.py | 2 +- mediapipe/tasks/python/vision/image_segmenter.py | 2 +- mediapipe/tasks/python/vision/interactive_segmenter.py | 2 +- mediapipe/tasks/python/vision/object_detector.py | 2 +- mediapipe/tasks/testdata/text/BUILD | 2 +- .../tasks/web/audio/audio_classifier/audio_classifier.ts | 2 +- .../web/audio/audio_classifier/audio_classifier_options.d.ts | 2 +- .../web/audio/audio_classifier/audio_classifier_result.d.ts | 2 +- .../tasks/web/audio/audio_classifier/audio_classifier_test.ts | 2 +- mediapipe/tasks/web/audio/audio_embedder/audio_embedder.ts | 2 +- .../web/audio/audio_embedder/audio_embedder_options.d.ts | 2 +- .../tasks/web/audio/audio_embedder/audio_embedder_result.d.ts | 2 +- .../tasks/web/audio/audio_embedder/audio_embedder_test.ts | 2 +- mediapipe/tasks/web/audio/core/audio_task_runner.ts | 2 +- mediapipe/tasks/web/audio/index.ts | 2 +- mediapipe/tasks/web/audio/types.ts | 2 +- mediapipe/tasks/web/components/containers/bounding_box.d.ts | 2 +- mediapipe/tasks/web/components/containers/category.d.ts | 2 +- .../web/components/containers/classification_result.d.ts | 2 +- .../tasks/web/components/containers/detection_result.d.ts | 2 +- .../tasks/web/components/containers/embedding_result.d.ts | 2 +- mediapipe/tasks/web/components/containers/keypoint.d.ts | 2 +- mediapipe/tasks/web/components/containers/landmark.d.ts | 2 +- mediapipe/tasks/web/components/containers/matrix.d.ts | 2 +- mediapipe/tasks/web/components/containers/rect.d.ts | 2 +- .../web/components/processors/classifier_options.test.ts | 2 +- .../tasks/web/components/processors/classifier_options.ts | 2 +- .../tasks/web/components/processors/classifier_result.test.ts | 2 +- .../tasks/web/components/processors/classifier_result.ts | 2 +- .../tasks/web/components/processors/detection_result.test.ts | 2 +- mediapipe/tasks/web/components/processors/detection_result.ts | 2 +- .../tasks/web/components/processors/embedder_options.test.ts | 2 +- mediapipe/tasks/web/components/processors/embedder_options.ts | 2 +- .../tasks/web/components/processors/embedder_result.test.ts | 2 +- mediapipe/tasks/web/components/processors/embedder_result.ts | 2 +- .../tasks/web/components/processors/landmark_result.test.ts | 2 +- mediapipe/tasks/web/components/processors/landmark_result.ts | 2 +- .../web/components/processors/landmark_result_test_lib.ts | 2 +- .../tasks/web/components/utils/cosine_similarity.test.ts | 2 +- mediapipe/tasks/web/components/utils/cosine_similarity.ts | 2 +- mediapipe/tasks/web/core/classifier_options.d.ts | 2 +- mediapipe/tasks/web/core/embedder_options.d.ts | 2 +- mediapipe/tasks/web/core/fileset_resolver.ts | 2 +- mediapipe/tasks/web/core/task_runner.ts | 2 +- mediapipe/tasks/web/core/task_runner_options.d.ts | 2 +- mediapipe/tasks/web/core/task_runner_test.ts | 2 +- mediapipe/tasks/web/core/task_runner_test_utils.ts | 2 +- mediapipe/tasks/web/core/wasm_fileset.d.ts | 2 +- mediapipe/tasks/web/text/index.ts | 2 +- .../tasks/web/text/language_detector/language_detector.ts | 2 +- .../web/text/language_detector/language_detector_options.d.ts | 2 +- .../web/text/language_detector/language_detector_result.d.ts | 2 +- .../web/text/language_detector/language_detector_test.ts | 2 +- mediapipe/tasks/web/text/text_classifier/text_classifier.ts | 2 +- .../web/text/text_classifier/text_classifier_options.d.ts | 2 +- .../web/text/text_classifier/text_classifier_result.d.ts | 2 +- .../tasks/web/text/text_classifier/text_classifier_test.ts | 2 +- mediapipe/tasks/web/text/text_embedder/text_embedder.ts | 2 +- .../tasks/web/text/text_embedder/text_embedder_options.d.ts | 2 +- .../tasks/web/text/text_embedder/text_embedder_result.d.ts | 2 +- mediapipe/tasks/web/text/text_embedder/text_embedder_test.ts | 2 +- mediapipe/tasks/web/text/types.ts | 2 +- mediapipe/tasks/web/vision/core/drawing_utils.ts | 2 +- mediapipe/tasks/web/vision/core/image.test.ts | 2 +- mediapipe/tasks/web/vision/core/image.ts | 2 +- mediapipe/tasks/web/vision/core/image_processing_options.d.ts | 2 +- mediapipe/tasks/web/vision/core/render_utils.ts | 2 +- mediapipe/tasks/web/vision/core/types.d.ts | 2 +- mediapipe/tasks/web/vision/core/vision_task_options.d.ts | 2 +- mediapipe/tasks/web/vision/core/vision_task_runner.test.ts | 2 +- mediapipe/tasks/web/vision/core/vision_task_runner.ts | 2 +- mediapipe/tasks/web/vision/face_detector/face_detector.ts | 2 +- .../tasks/web/vision/face_detector/face_detector_options.d.ts | 2 +- .../tasks/web/vision/face_detector/face_detector_result.d.ts | 2 +- .../tasks/web/vision/face_detector/face_detector_test.ts | 2 +- mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts | 2 +- .../web/vision/face_landmarker/face_landmarker_options.d.ts | 2 +- .../web/vision/face_landmarker/face_landmarker_result.d.ts | 2 +- .../tasks/web/vision/face_landmarker/face_landmarker_test.ts | 2 +- .../web/vision/face_landmarker/face_landmarks_connections.ts | 2 +- mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts | 2 +- .../tasks/web/vision/face_stylizer/face_stylizer_options.d.ts | 2 +- .../tasks/web/vision/face_stylizer/face_stylizer_test.ts | 2 +- .../tasks/web/vision/gesture_recognizer/gesture_recognizer.ts | 2 +- .../vision/gesture_recognizer/gesture_recognizer_options.d.ts | 2 +- .../vision/gesture_recognizer/gesture_recognizer_result.d.ts | 2 +- .../web/vision/gesture_recognizer/gesture_recognizer_test.ts | 2 +- mediapipe/tasks/web/vision/hand_landmarker/hand_landmark.d.ts | 2 +- mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker.ts | 2 +- .../web/vision/hand_landmarker/hand_landmarker_options.d.ts | 2 +- .../web/vision/hand_landmarker/hand_landmarker_result.d.ts | 2 +- .../tasks/web/vision/hand_landmarker/hand_landmarker_test.ts | 2 +- .../web/vision/hand_landmarker/hand_landmarks_connections.ts | 2 +- .../tasks/web/vision/image_classifier/image_classifier.ts | 2 +- .../web/vision/image_classifier/image_classifier_options.d.ts | 2 +- .../web/vision/image_classifier/image_classifier_result.d.ts | 2 +- .../web/vision/image_classifier/image_classifier_test.ts | 2 +- mediapipe/tasks/web/vision/image_embedder/image_embedder.ts | 2 +- .../web/vision/image_embedder/image_embedder_options.d.ts | 2 +- .../web/vision/image_embedder/image_embedder_result.d.ts | 2 +- .../tasks/web/vision/image_embedder/image_embedder_test.ts | 2 +- mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts | 2 +- .../web/vision/image_segmenter/image_segmenter_options.d.ts | 2 +- .../web/vision/image_segmenter/image_segmenter_result.d.ts | 2 +- .../tasks/web/vision/image_segmenter/image_segmenter_test.ts | 2 +- mediapipe/tasks/web/vision/index.ts | 2 +- .../web/vision/interactive_segmenter/interactive_segmenter.ts | 2 +- .../interactive_segmenter/interactive_segmenter_options.d.ts | 2 +- .../interactive_segmenter/interactive_segmenter_result.d.ts | 2 +- .../interactive_segmenter/interactive_segmenter_test.ts | 2 +- mediapipe/tasks/web/vision/object_detector/object_detector.ts | 2 +- .../web/vision/object_detector/object_detector_options.d.ts | 2 +- .../web/vision/object_detector/object_detector_result.d.ts | 2 +- .../tasks/web/vision/object_detector/object_detector_test.ts | 2 +- mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts | 2 +- .../web/vision/pose_landmarker/pose_landmarker_options.d.ts | 2 +- .../web/vision/pose_landmarker/pose_landmarker_result.d.ts | 2 +- .../tasks/web/vision/pose_landmarker/pose_landmarker_test.ts | 2 +- mediapipe/tasks/web/vision/types.ts | 2 +- mediapipe/util/tflite/operations/max_pool_argmax.cc | 2 +- mediapipe/util/tflite/operations/transpose_conv_bias.cc | 2 +- mediapipe/web/graph_runner/platform_utils.test.ts | 2 +- mediapipe/web/graph_runner/platform_utils.ts | 2 +- setup.py | 2 +- third_party/halide/halide.bzl | 2 +- third_party/repo.bzl | 2 +- 900 files changed, 903 insertions(+), 903 deletions(-) diff --git a/docs/build_java_api_docs.py b/docs/build_java_api_docs.py index b13e8d1df..eaa380f87 100644 --- a/docs/build_java_api_docs.py +++ b/docs/build_java_api_docs.py @@ -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. diff --git a/docs/build_model_maker_api_docs.py b/docs/build_model_maker_api_docs.py index 7732b7d56..377536c33 100644 --- a/docs/build_model_maker_api_docs.py +++ b/docs/build_model_maker_api_docs.py @@ -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. diff --git a/docs/build_py_api_docs.py b/docs/build_py_api_docs.py index 02eb04074..10b799320 100644 --- a/docs/build_py_api_docs.py +++ b/docs/build_py_api_docs.py @@ -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. diff --git a/mediapipe/calculators/core/merge_to_vector_calculator.cc b/mediapipe/calculators/core/merge_to_vector_calculator.cc index fd053ed2b..4bb3c8a40 100644 --- a/mediapipe/calculators/core/merge_to_vector_calculator.cc +++ b/mediapipe/calculators/core/merge_to_vector_calculator.cc @@ -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. diff --git a/mediapipe/calculators/core/merge_to_vector_calculator.h b/mediapipe/calculators/core/merge_to_vector_calculator.h index b4f7a37c2..4ec674c05 100644 --- a/mediapipe/calculators/core/merge_to_vector_calculator.h +++ b/mediapipe/calculators/core/merge_to_vector_calculator.h @@ -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. diff --git a/mediapipe/calculators/tensor/bert_preprocessor_calculator.proto b/mediapipe/calculators/tensor/bert_preprocessor_calculator.proto index 5dc9815a1..b2dc5578f 100644 --- a/mediapipe/calculators/tensor/bert_preprocessor_calculator.proto +++ b/mediapipe/calculators/tensor/bert_preprocessor_calculator.proto @@ -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. diff --git a/mediapipe/calculators/tensor/regex_preprocessor_calculator.proto b/mediapipe/calculators/tensor/regex_preprocessor_calculator.proto index 793067a80..ef7ad0472 100644 --- a/mediapipe/calculators/tensor/regex_preprocessor_calculator.proto +++ b/mediapipe/calculators/tensor/regex_preprocessor_calculator.proto @@ -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. diff --git a/mediapipe/calculators/util/detections_deduplicate_calculator.cc b/mediapipe/calculators/util/detections_deduplicate_calculator.cc index 2dfa09028..a31585b88 100644 --- a/mediapipe/calculators/util/detections_deduplicate_calculator.cc +++ b/mediapipe/calculators/util/detections_deduplicate_calculator.cc @@ -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. diff --git a/mediapipe/framework/formats/frame_buffer.cc b/mediapipe/framework/formats/frame_buffer.cc index 930a3651a..743de8121 100644 --- a/mediapipe/framework/formats/frame_buffer.cc +++ b/mediapipe/framework/formats/frame_buffer.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/framework/formats/frame_buffer.h b/mediapipe/framework/formats/frame_buffer.h index 32ba41a2d..21a5f537f 100644 --- a/mediapipe/framework/formats/frame_buffer.h +++ b/mediapipe/framework/formats/frame_buffer.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/gpu/frame_buffer_view.h b/mediapipe/gpu/frame_buffer_view.h index 76d773a5e..a6192e521 100644 --- a/mediapipe/gpu/frame_buffer_view.h +++ b/mediapipe/gpu/frame_buffer_view.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/gpu/gpu_buffer_storage_image_frame.cc b/mediapipe/gpu/gpu_buffer_storage_image_frame.cc index 1cd661d37..316c6cc4e 100644 --- a/mediapipe/gpu/gpu_buffer_storage_image_frame.cc +++ b/mediapipe/gpu/gpu_buffer_storage_image_frame.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/gpu/gpu_buffer_storage_image_frame.h b/mediapipe/gpu/gpu_buffer_storage_image_frame.h index 542791f98..3b805e8f2 100644 --- a/mediapipe/gpu/gpu_buffer_storage_image_frame.h +++ b/mediapipe/gpu/gpu_buffer_storage_image_frame.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/gpu/gpu_buffer_storage_yuv_image.cc b/mediapipe/gpu/gpu_buffer_storage_yuv_image.cc index 4b0913b96..41905de74 100644 --- a/mediapipe/gpu/gpu_buffer_storage_yuv_image.cc +++ b/mediapipe/gpu/gpu_buffer_storage_yuv_image.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/gpu/gpu_buffer_storage_yuv_image.h b/mediapipe/gpu/gpu_buffer_storage_yuv_image.h index 6b34f4948..cf6ffcd0e 100644 --- a/mediapipe/gpu/gpu_buffer_storage_yuv_image.h +++ b/mediapipe/gpu/gpu_buffer_storage_yuv_image.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/BUILD b/mediapipe/java/com/google/mediapipe/framework/image/BUILD index d9508c1f7..a34e97954 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/BUILD +++ b/mediapipe/java/com/google/mediapipe/framework/image/BUILD @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/BitmapExtractor.java b/mediapipe/java/com/google/mediapipe/framework/image/BitmapExtractor.java index d6f50bf30..0211c808d 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/BitmapExtractor.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/BitmapExtractor.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/BitmapImageBuilder.java b/mediapipe/java/com/google/mediapipe/framework/image/BitmapImageBuilder.java index 988cdf542..0b11c6de0 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/BitmapImageBuilder.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/BitmapImageBuilder.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/BitmapImageContainer.java b/mediapipe/java/com/google/mediapipe/framework/image/BitmapImageContainer.java index 6fbcac214..264668575 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/BitmapImageContainer.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/BitmapImageContainer.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/ByteBufferExtractor.java b/mediapipe/java/com/google/mediapipe/framework/image/ByteBufferExtractor.java index 68c53b0c4..242404ad0 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/ByteBufferExtractor.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/ByteBufferExtractor.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/ByteBufferImageBuilder.java b/mediapipe/java/com/google/mediapipe/framework/image/ByteBufferImageBuilder.java index a650e4c33..a8bd90d2a 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/ByteBufferImageBuilder.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/ByteBufferImageBuilder.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/ByteBufferImageContainer.java b/mediapipe/java/com/google/mediapipe/framework/image/ByteBufferImageContainer.java index 82dbe32ca..a631a93de 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/ByteBufferImageContainer.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/ByteBufferImageContainer.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/MPImage.java b/mediapipe/java/com/google/mediapipe/framework/image/MPImage.java index 946beae37..4622189a6 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/MPImage.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/MPImage.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/MPImageConsumer.java b/mediapipe/java/com/google/mediapipe/framework/image/MPImageConsumer.java index f9f343e93..eb9f3ecb9 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/MPImageConsumer.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/MPImageConsumer.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/MPImageContainer.java b/mediapipe/java/com/google/mediapipe/framework/image/MPImageContainer.java index 674073b5b..7002b6f80 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/MPImageContainer.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/MPImageContainer.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/MPImageProducer.java b/mediapipe/java/com/google/mediapipe/framework/image/MPImageProducer.java index 9783935d4..48b8c33c9 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/MPImageProducer.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/MPImageProducer.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/MPImageProperties.java b/mediapipe/java/com/google/mediapipe/framework/image/MPImageProperties.java index 6005ce77b..dff6481e9 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/MPImageProperties.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/MPImageProperties.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/MediaImageBuilder.java b/mediapipe/java/com/google/mediapipe/framework/image/MediaImageBuilder.java index 9e719715d..af3372fea 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/MediaImageBuilder.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/MediaImageBuilder.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/MediaImageContainer.java b/mediapipe/java/com/google/mediapipe/framework/image/MediaImageContainer.java index 864c76df2..d9b85af70 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/MediaImageContainer.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/MediaImageContainer.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/framework/image/MediaImageExtractor.java b/mediapipe/java/com/google/mediapipe/framework/image/MediaImageExtractor.java index 76bb5a5ec..5fca757c5 100644 --- a/mediapipe/java/com/google/mediapipe/framework/image/MediaImageExtractor.java +++ b/mediapipe/java/com/google/mediapipe/framework/image/MediaImageExtractor.java @@ -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. diff --git a/mediapipe/java/com/google/mediapipe/mediapipe_aar.bzl b/mediapipe/java/com/google/mediapipe/mediapipe_aar.bzl index 03fc41757..879527ed4 100644 --- a/mediapipe/java/com/google/mediapipe/mediapipe_aar.bzl +++ b/mediapipe/java/com/google/mediapipe/mediapipe_aar.bzl @@ -1,4 +1,4 @@ -# Copyright 2019-2022 The MediaPipe Authors. All Rights Reserved. +# Copyright 2019-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. diff --git a/mediapipe/model_maker/BUILD b/mediapipe/model_maker/BUILD index cb312072f..e3995e134 100644 --- a/mediapipe/model_maker/BUILD +++ b/mediapipe/model_maker/BUILD @@ -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. diff --git a/mediapipe/model_maker/__init__.py b/mediapipe/model_maker/__init__.py index 533edebf7..6779524b2 100644 --- a/mediapipe/model_maker/__init__.py +++ b/mediapipe/model_maker/__init__.py @@ -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. diff --git a/mediapipe/model_maker/models/gesture_recognizer/BUILD b/mediapipe/model_maker/models/gesture_recognizer/BUILD index 5ead0e618..947508f1b 100644 --- a/mediapipe/model_maker/models/gesture_recognizer/BUILD +++ b/mediapipe/model_maker/models/gesture_recognizer/BUILD @@ -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. diff --git a/mediapipe/model_maker/models/text_classifier/BUILD b/mediapipe/model_maker/models/text_classifier/BUILD index dc6210a7d..d9d55048d 100644 --- a/mediapipe/model_maker/models/text_classifier/BUILD +++ b/mediapipe/model_maker/models/text_classifier/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/BUILD b/mediapipe/model_maker/python/BUILD index fe101f293..775ac82dd 100644 --- a/mediapipe/model_maker/python/BUILD +++ b/mediapipe/model_maker/python/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/__init__.py b/mediapipe/model_maker/python/__init__.py index 7ca2f9216..5b1a4244c 100644 --- a/mediapipe/model_maker/python/__init__.py +++ b/mediapipe/model_maker/python/__init__.py @@ -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. diff --git a/mediapipe/model_maker/python/core/BUILD b/mediapipe/model_maker/python/core/BUILD index 636a1a720..6331e638e 100644 --- a/mediapipe/model_maker/python/core/BUILD +++ b/mediapipe/model_maker/python/core/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/core/__init__.py b/mediapipe/model_maker/python/core/__init__.py index 7ca2f9216..5b1a4244c 100644 --- a/mediapipe/model_maker/python/core/__init__.py +++ b/mediapipe/model_maker/python/core/__init__.py @@ -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. diff --git a/mediapipe/model_maker/python/core/data/BUILD b/mediapipe/model_maker/python/core/data/BUILD index 70a62e8f7..cc0381f60 100644 --- a/mediapipe/model_maker/python/core/data/BUILD +++ b/mediapipe/model_maker/python/core/data/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/core/data/__init__.py b/mediapipe/model_maker/python/core/data/__init__.py index 7ca2f9216..5b1a4244c 100644 --- a/mediapipe/model_maker/python/core/data/__init__.py +++ b/mediapipe/model_maker/python/core/data/__init__.py @@ -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. diff --git a/mediapipe/model_maker/python/core/data/classification_dataset.py b/mediapipe/model_maker/python/core/data/classification_dataset.py index 073e79638..b1df3b6d4 100644 --- a/mediapipe/model_maker/python/core/data/classification_dataset.py +++ b/mediapipe/model_maker/python/core/data/classification_dataset.py @@ -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. diff --git a/mediapipe/model_maker/python/core/data/classification_dataset_test.py b/mediapipe/model_maker/python/core/data/classification_dataset_test.py index 82e74b04e..d21803f43 100644 --- a/mediapipe/model_maker/python/core/data/classification_dataset_test.py +++ b/mediapipe/model_maker/python/core/data/classification_dataset_test.py @@ -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. diff --git a/mediapipe/model_maker/python/core/data/data_util.py b/mediapipe/model_maker/python/core/data/data_util.py index 8c6b9145f..88efa896c 100644 --- a/mediapipe/model_maker/python/core/data/data_util.py +++ b/mediapipe/model_maker/python/core/data/data_util.py @@ -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. diff --git a/mediapipe/model_maker/python/core/data/data_util_test.py b/mediapipe/model_maker/python/core/data/data_util_test.py index 56ac832c3..8bed8ef7c 100644 --- a/mediapipe/model_maker/python/core/data/data_util_test.py +++ b/mediapipe/model_maker/python/core/data/data_util_test.py @@ -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. diff --git a/mediapipe/model_maker/python/core/data/dataset.py b/mediapipe/model_maker/python/core/data/dataset.py index 3b4182c14..bfdc5b0f1 100644 --- a/mediapipe/model_maker/python/core/data/dataset.py +++ b/mediapipe/model_maker/python/core/data/dataset.py @@ -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. diff --git a/mediapipe/model_maker/python/core/data/dataset_test.py b/mediapipe/model_maker/python/core/data/dataset_test.py index 9adff127d..7a3f75388 100644 --- a/mediapipe/model_maker/python/core/data/dataset_test.py +++ b/mediapipe/model_maker/python/core/data/dataset_test.py @@ -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. diff --git a/mediapipe/model_maker/python/core/data/testdata/BUILD b/mediapipe/model_maker/python/core/data/testdata/BUILD index 54e562d41..b799c3cee 100644 --- a/mediapipe/model_maker/python/core/data/testdata/BUILD +++ b/mediapipe/model_maker/python/core/data/testdata/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/core/hyperparameters.py b/mediapipe/model_maker/python/core/hyperparameters.py index e6848e0de..3b3e3540b 100644 --- a/mediapipe/model_maker/python/core/hyperparameters.py +++ b/mediapipe/model_maker/python/core/hyperparameters.py @@ -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. diff --git a/mediapipe/model_maker/python/core/tasks/BUILD b/mediapipe/model_maker/python/core/tasks/BUILD index 8c5448556..6a3e60c97 100644 --- a/mediapipe/model_maker/python/core/tasks/BUILD +++ b/mediapipe/model_maker/python/core/tasks/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/core/tasks/__init__.py b/mediapipe/model_maker/python/core/tasks/__init__.py index 7ca2f9216..5b1a4244c 100644 --- a/mediapipe/model_maker/python/core/tasks/__init__.py +++ b/mediapipe/model_maker/python/core/tasks/__init__.py @@ -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. diff --git a/mediapipe/model_maker/python/core/tasks/classifier.py b/mediapipe/model_maker/python/core/tasks/classifier.py index bfe0f027f..60c00f0de 100644 --- a/mediapipe/model_maker/python/core/tasks/classifier.py +++ b/mediapipe/model_maker/python/core/tasks/classifier.py @@ -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. diff --git a/mediapipe/model_maker/python/core/tasks/classifier_test.py b/mediapipe/model_maker/python/core/tasks/classifier_test.py index 6bf3b7a2e..2943825ac 100644 --- a/mediapipe/model_maker/python/core/tasks/classifier_test.py +++ b/mediapipe/model_maker/python/core/tasks/classifier_test.py @@ -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. diff --git a/mediapipe/model_maker/python/core/tasks/custom_model.py b/mediapipe/model_maker/python/core/tasks/custom_model.py index 188bf62cc..55f5a6db3 100644 --- a/mediapipe/model_maker/python/core/tasks/custom_model.py +++ b/mediapipe/model_maker/python/core/tasks/custom_model.py @@ -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. diff --git a/mediapipe/model_maker/python/core/tasks/custom_model_test.py b/mediapipe/model_maker/python/core/tasks/custom_model_test.py index ad77d4ecd..afb418c44 100644 --- a/mediapipe/model_maker/python/core/tasks/custom_model_test.py +++ b/mediapipe/model_maker/python/core/tasks/custom_model_test.py @@ -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. diff --git a/mediapipe/model_maker/python/core/utils/BUILD b/mediapipe/model_maker/python/core/utils/BUILD index 907706b3a..e86cbb1e3 100644 --- a/mediapipe/model_maker/python/core/utils/BUILD +++ b/mediapipe/model_maker/python/core/utils/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/core/utils/__init__.py b/mediapipe/model_maker/python/core/utils/__init__.py index 7ca2f9216..5b1a4244c 100644 --- a/mediapipe/model_maker/python/core/utils/__init__.py +++ b/mediapipe/model_maker/python/core/utils/__init__.py @@ -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. diff --git a/mediapipe/model_maker/python/core/utils/file_util.py b/mediapipe/model_maker/python/core/utils/file_util.py index 221df94fd..71b5a0a7b 100644 --- a/mediapipe/model_maker/python/core/utils/file_util.py +++ b/mediapipe/model_maker/python/core/utils/file_util.py @@ -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. diff --git a/mediapipe/model_maker/python/core/utils/file_util_test.py b/mediapipe/model_maker/python/core/utils/file_util_test.py index 027756ff0..d5b983929 100644 --- a/mediapipe/model_maker/python/core/utils/file_util_test.py +++ b/mediapipe/model_maker/python/core/utils/file_util_test.py @@ -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. diff --git a/mediapipe/model_maker/python/core/utils/loss_functions.py b/mediapipe/model_maker/python/core/utils/loss_functions.py index 7e7c4c5ea..cc17ab397 100644 --- a/mediapipe/model_maker/python/core/utils/loss_functions.py +++ b/mediapipe/model_maker/python/core/utils/loss_functions.py @@ -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. diff --git a/mediapipe/model_maker/python/core/utils/loss_functions_test.py b/mediapipe/model_maker/python/core/utils/loss_functions_test.py index 1c921779f..01f9a667d 100644 --- a/mediapipe/model_maker/python/core/utils/loss_functions_test.py +++ b/mediapipe/model_maker/python/core/utils/loss_functions_test.py @@ -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. diff --git a/mediapipe/model_maker/python/core/utils/model_util.py b/mediapipe/model_maker/python/core/utils/model_util.py index 7a0b8fcf0..5ca2c2b7b 100644 --- a/mediapipe/model_maker/python/core/utils/model_util.py +++ b/mediapipe/model_maker/python/core/utils/model_util.py @@ -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. diff --git a/mediapipe/model_maker/python/core/utils/model_util_test.py b/mediapipe/model_maker/python/core/utils/model_util_test.py index 6961a5fc7..57750624f 100644 --- a/mediapipe/model_maker/python/core/utils/model_util_test.py +++ b/mediapipe/model_maker/python/core/utils/model_util_test.py @@ -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. diff --git a/mediapipe/model_maker/python/core/utils/quantization.py b/mediapipe/model_maker/python/core/utils/quantization.py index a1a38cc64..2a8d92244 100644 --- a/mediapipe/model_maker/python/core/utils/quantization.py +++ b/mediapipe/model_maker/python/core/utils/quantization.py @@ -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. diff --git a/mediapipe/model_maker/python/core/utils/quantization_test.py b/mediapipe/model_maker/python/core/utils/quantization_test.py index 9d27d34ac..57523d405 100644 --- a/mediapipe/model_maker/python/core/utils/quantization_test.py +++ b/mediapipe/model_maker/python/core/utils/quantization_test.py @@ -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. diff --git a/mediapipe/model_maker/python/core/utils/test_util.py b/mediapipe/model_maker/python/core/utils/test_util.py index 14d02814e..eda8facc2 100644 --- a/mediapipe/model_maker/python/core/utils/test_util.py +++ b/mediapipe/model_maker/python/core/utils/test_util.py @@ -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. diff --git a/mediapipe/model_maker/python/core/utils/testdata/BUILD b/mediapipe/model_maker/python/core/utils/testdata/BUILD index 8eed72f78..ea45f6140 100644 --- a/mediapipe/model_maker/python/core/utils/testdata/BUILD +++ b/mediapipe/model_maker/python/core/utils/testdata/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/text/__init__.py b/mediapipe/model_maker/python/text/__init__.py index 7ca2f9216..5b1a4244c 100644 --- a/mediapipe/model_maker/python/text/__init__.py +++ b/mediapipe/model_maker/python/text/__init__.py @@ -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. diff --git a/mediapipe/model_maker/python/text/core/BUILD b/mediapipe/model_maker/python/text/core/BUILD index e0c53491a..3ba4e8e6e 100644 --- a/mediapipe/model_maker/python/text/core/BUILD +++ b/mediapipe/model_maker/python/text/core/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/text/core/__init__.py b/mediapipe/model_maker/python/text/core/__init__.py index 7ca2f9216..5b1a4244c 100644 --- a/mediapipe/model_maker/python/text/core/__init__.py +++ b/mediapipe/model_maker/python/text/core/__init__.py @@ -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. diff --git a/mediapipe/model_maker/python/text/core/bert_model_options.py b/mediapipe/model_maker/python/text/core/bert_model_options.py index ce5ef6af4..bb8aca963 100644 --- a/mediapipe/model_maker/python/text/core/bert_model_options.py +++ b/mediapipe/model_maker/python/text/core/bert_model_options.py @@ -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. diff --git a/mediapipe/model_maker/python/text/core/bert_model_spec.py b/mediapipe/model_maker/python/text/core/bert_model_spec.py index 605435df0..792c2c9a6 100644 --- a/mediapipe/model_maker/python/text/core/bert_model_spec.py +++ b/mediapipe/model_maker/python/text/core/bert_model_spec.py @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/BUILD b/mediapipe/model_maker/python/text/text_classifier/BUILD index 2c1e2d3d8..1ae3e2873 100644 --- a/mediapipe/model_maker/python/text/text_classifier/BUILD +++ b/mediapipe/model_maker/python/text/text_classifier/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/__init__.py b/mediapipe/model_maker/python/text/text_classifier/__init__.py index 697461969..4df3a771e 100644 --- a/mediapipe/model_maker/python/text/text_classifier/__init__.py +++ b/mediapipe/model_maker/python/text/text_classifier/__init__.py @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/dataset.py b/mediapipe/model_maker/python/text/text_classifier/dataset.py index 3679b67ae..63605b477 100644 --- a/mediapipe/model_maker/python/text/text_classifier/dataset.py +++ b/mediapipe/model_maker/python/text/text_classifier/dataset.py @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/dataset_test.py b/mediapipe/model_maker/python/text/text_classifier/dataset_test.py index ec9e8fa2d..012476e0b 100644 --- a/mediapipe/model_maker/python/text/text_classifier/dataset_test.py +++ b/mediapipe/model_maker/python/text/text_classifier/dataset_test.py @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/model_options.py b/mediapipe/model_maker/python/text/text_classifier/model_options.py index a3d94bdf7..a2f45e145 100644 --- a/mediapipe/model_maker/python/text/text_classifier/model_options.py +++ b/mediapipe/model_maker/python/text/text_classifier/model_options.py @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/model_spec.py b/mediapipe/model_maker/python/text/text_classifier/model_spec.py index d999f6867..e947f8c18 100644 --- a/mediapipe/model_maker/python/text/text_classifier/model_spec.py +++ b/mediapipe/model_maker/python/text/text_classifier/model_spec.py @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/model_spec_test.py b/mediapipe/model_maker/python/text/text_classifier/model_spec_test.py index c2d96bac4..d3daac540 100644 --- a/mediapipe/model_maker/python/text/text_classifier/model_spec_test.py +++ b/mediapipe/model_maker/python/text/text_classifier/model_spec_test.py @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/preprocessor.py b/mediapipe/model_maker/python/text/text_classifier/preprocessor.py index 0a48f459c..15b9d90d0 100644 --- a/mediapipe/model_maker/python/text/text_classifier/preprocessor.py +++ b/mediapipe/model_maker/python/text/text_classifier/preprocessor.py @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/preprocessor_test.py b/mediapipe/model_maker/python/text/text_classifier/preprocessor_test.py index 2ddc4aea9..27e98e262 100644 --- a/mediapipe/model_maker/python/text/text_classifier/preprocessor_test.py +++ b/mediapipe/model_maker/python/text/text_classifier/preprocessor_test.py @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/testdata/BUILD b/mediapipe/model_maker/python/text/text_classifier/testdata/BUILD index a581462cf..027bad7e6 100644 --- a/mediapipe/model_maker/python/text/text_classifier/testdata/BUILD +++ b/mediapipe/model_maker/python/text/text_classifier/testdata/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/text_classifier.py b/mediapipe/model_maker/python/text/text_classifier/text_classifier.py index 3d932ce90..cd6ceb9b3 100644 --- a/mediapipe/model_maker/python/text/text_classifier/text_classifier.py +++ b/mediapipe/model_maker/python/text/text_classifier/text_classifier.py @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/text_classifier_demo.py b/mediapipe/model_maker/python/text/text_classifier/text_classifier_demo.py index 08f4c2ad3..c3d1711dc 100644 --- a/mediapipe/model_maker/python/text/text_classifier/text_classifier_demo.py +++ b/mediapipe/model_maker/python/text/text_classifier/text_classifier_demo.py @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/text_classifier_options.py b/mediapipe/model_maker/python/text/text_classifier/text_classifier_options.py index a02f17347..c62fb27bf 100644 --- a/mediapipe/model_maker/python/text/text_classifier/text_classifier_options.py +++ b/mediapipe/model_maker/python/text/text_classifier/text_classifier_options.py @@ -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. diff --git a/mediapipe/model_maker/python/text/text_classifier/text_classifier_test.py b/mediapipe/model_maker/python/text/text_classifier/text_classifier_test.py index 6aa68a284..34830c9ff 100644 --- a/mediapipe/model_maker/python/text/text_classifier/text_classifier_test.py +++ b/mediapipe/model_maker/python/text/text_classifier/text_classifier_test.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/BUILD b/mediapipe/model_maker/python/vision/BUILD index 10aef8c33..4410d859f 100644 --- a/mediapipe/model_maker/python/vision/BUILD +++ b/mediapipe/model_maker/python/vision/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/vision/__init__.py b/mediapipe/model_maker/python/vision/__init__.py index 7ca2f9216..5b1a4244c 100644 --- a/mediapipe/model_maker/python/vision/__init__.py +++ b/mediapipe/model_maker/python/vision/__init__.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/core/BUILD b/mediapipe/model_maker/python/vision/core/BUILD index f6f6cce05..ba67b61e9 100644 --- a/mediapipe/model_maker/python/vision/core/BUILD +++ b/mediapipe/model_maker/python/vision/core/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/vision/core/__init__.py b/mediapipe/model_maker/python/vision/core/__init__.py index 7ca2f9216..5b1a4244c 100644 --- a/mediapipe/model_maker/python/vision/core/__init__.py +++ b/mediapipe/model_maker/python/vision/core/__init__.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/core/image_preprocessing.py b/mediapipe/model_maker/python/vision/core/image_preprocessing.py index 104ccd9ca..84d486347 100644 --- a/mediapipe/model_maker/python/vision/core/image_preprocessing.py +++ b/mediapipe/model_maker/python/vision/core/image_preprocessing.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/core/image_preprocessing_test.py b/mediapipe/model_maker/python/vision/core/image_preprocessing_test.py index 0594b4376..563b19cfc 100644 --- a/mediapipe/model_maker/python/vision/core/image_preprocessing_test.py +++ b/mediapipe/model_maker/python/vision/core/image_preprocessing_test.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/core/image_utils.py b/mediapipe/model_maker/python/vision/core/image_utils.py index 80d0616e5..0562da44e 100644 --- a/mediapipe/model_maker/python/vision/core/image_utils.py +++ b/mediapipe/model_maker/python/vision/core/image_utils.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/core/image_utils_test.py b/mediapipe/model_maker/python/vision/core/image_utils_test.py index 84101113c..a89ff20a2 100644 --- a/mediapipe/model_maker/python/vision/core/image_utils_test.py +++ b/mediapipe/model_maker/python/vision/core/image_utils_test.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/core/test_utils.py b/mediapipe/model_maker/python/vision/core/test_utils.py index 528b2ca7b..8cfe30811 100644 --- a/mediapipe/model_maker/python/vision/core/test_utils.py +++ b/mediapipe/model_maker/python/vision/core/test_utils.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/face_stylizer/BUILD b/mediapipe/model_maker/python/vision/face_stylizer/BUILD index 53fb684e4..a2e30a112 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/BUILD +++ b/mediapipe/model_maker/python/vision/face_stylizer/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/face_stylizer/__init__.py b/mediapipe/model_maker/python/vision/face_stylizer/__init__.py index 3cec27964..cc5bd2ae8 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/__init__.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/face_stylizer/dataset.py b/mediapipe/model_maker/python/vision/face_stylizer/dataset.py index b6c85d6f3..d517fd9c1 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/dataset.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/dataset.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/face_stylizer/dataset_test.py b/mediapipe/model_maker/python/vision/face_stylizer/dataset_test.py index a8af222d4..cf0dce800 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/dataset_test.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/dataset_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_options.py b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_options.py index e0e2441d1..90fd8eb38 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_options.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_options.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/face_stylizer/hyperparameters.py b/mediapipe/model_maker/python/vision/face_stylizer/hyperparameters.py index 0a129a721..f48a916b0 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/hyperparameters.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/hyperparameters.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/face_stylizer/model_options.py b/mediapipe/model_maker/python/vision/face_stylizer/model_options.py index ff5a54eba..9b3f7beef 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/model_options.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/model_options.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/face_stylizer/model_spec.py b/mediapipe/model_maker/python/vision/face_stylizer/model_spec.py index 6f5126f0b..1c528a63d 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/model_spec.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/model_spec.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/face_stylizer/model_spec_test.py b/mediapipe/model_maker/python/vision/face_stylizer/model_spec_test.py index 8be3242ac..e420adef4 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/model_spec_test.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/model_spec_test.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/BUILD b/mediapipe/model_maker/python/vision/gesture_recognizer/BUILD index e96421593..578723fb0 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/BUILD +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/__init__.py b/mediapipe/model_maker/python/vision/gesture_recognizer/__init__.py index a302e8d79..5d5c54813 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/__init__.py +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/__init__.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/constants.py b/mediapipe/model_maker/python/vision/gesture_recognizer/constants.py index acd569d0e..71689bd7c 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/constants.py +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/constants.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/dataset.py b/mediapipe/model_maker/python/vision/gesture_recognizer/dataset.py index 70a363f1a..1ba626be9 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/dataset.py +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/dataset.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/dataset_test.py b/mediapipe/model_maker/python/vision/gesture_recognizer/dataset_test.py index e9e7ddd06..a32905597 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/dataset_test.py +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/dataset_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The MediaPipe Authors. All Rights Reserved.s +# Copyright 2022 The MediaPipe Authors.s # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer.py b/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer.py index f009ef281..66934304a 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer.py +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer_demo.py b/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer_demo.py index 1cf9f0619..0c1d57d2b 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer_demo.py +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer_demo.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer_options.py b/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer_options.py index da9e2d647..2d80da8e2 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer_options.py +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer_options.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer_test.py b/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer_test.py index 11b4f9759..41799af97 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer_test.py +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/gesture_recognizer_test.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/hyperparameters.py b/mediapipe/model_maker/python/vision/gesture_recognizer/hyperparameters.py index fed62453b..f7cf9cf05 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/hyperparameters.py +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/hyperparameters.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/metadata_writer.py b/mediapipe/model_maker/python/vision/gesture_recognizer/metadata_writer.py index d6dc3ec2c..8ccfcb186 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/metadata_writer.py +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/metadata_writer.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/metadata_writer_test.py b/mediapipe/model_maker/python/vision/gesture_recognizer/metadata_writer_test.py index fd26b274d..794e7678b 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/metadata_writer_test.py +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/metadata_writer_test.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/model_options.py b/mediapipe/model_maker/python/vision/gesture_recognizer/model_options.py index 1870437d4..a607fd6b6 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/model_options.py +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/model_options.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/BUILD b/mediapipe/model_maker/python/vision/image_classifier/BUILD index f88616690..3b6d7551a 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/BUILD +++ b/mediapipe/model_maker/python/vision/image_classifier/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/__init__.py b/mediapipe/model_maker/python/vision/image_classifier/__init__.py index 4cde9e7e3..c9ab6faec 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/__init__.py +++ b/mediapipe/model_maker/python/vision/image_classifier/__init__.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/dataset.py b/mediapipe/model_maker/python/vision/image_classifier/dataset.py index bf4bbc4b6..6bc180be8 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/dataset.py +++ b/mediapipe/model_maker/python/vision/image_classifier/dataset.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/dataset_test.py b/mediapipe/model_maker/python/vision/image_classifier/dataset_test.py index 1f290b327..63fa666b3 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/dataset_test.py +++ b/mediapipe/model_maker/python/vision/image_classifier/dataset_test.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/hyperparameters.py b/mediapipe/model_maker/python/vision/image_classifier/hyperparameters.py index 1d3bfdad2..5092ed370 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/hyperparameters.py +++ b/mediapipe/model_maker/python/vision/image_classifier/hyperparameters.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/image_classifier.py b/mediapipe/model_maker/python/vision/image_classifier/image_classifier.py index c2181121c..3838a5a1a 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/image_classifier.py +++ b/mediapipe/model_maker/python/vision/image_classifier/image_classifier.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/image_classifier_demo.py b/mediapipe/model_maker/python/vision/image_classifier/image_classifier_demo.py index f382e28aa..31b6e5876 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/image_classifier_demo.py +++ b/mediapipe/model_maker/python/vision/image_classifier/image_classifier_demo.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/image_classifier_options.py b/mediapipe/model_maker/python/vision/image_classifier/image_classifier_options.py index d3566a9fa..bf3034c62 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/image_classifier_options.py +++ b/mediapipe/model_maker/python/vision/image_classifier/image_classifier_options.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/image_classifier_test.py b/mediapipe/model_maker/python/vision/image_classifier/image_classifier_test.py index afda8643b..4b1ea607f 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/image_classifier_test.py +++ b/mediapipe/model_maker/python/vision/image_classifier/image_classifier_test.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/model_options.py b/mediapipe/model_maker/python/vision/image_classifier/model_options.py index a8f89b577..2e7c32df6 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/model_options.py +++ b/mediapipe/model_maker/python/vision/image_classifier/model_options.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/model_spec.py b/mediapipe/model_maker/python/vision/image_classifier/model_spec.py index d46cafe6b..7bc6aca8b 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/model_spec.py +++ b/mediapipe/model_maker/python/vision/image_classifier/model_spec.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/model_spec_test.py b/mediapipe/model_maker/python/vision/image_classifier/model_spec_test.py index 63f360ab9..6b388cd13 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/model_spec_test.py +++ b/mediapipe/model_maker/python/vision/image_classifier/model_spec_test.py @@ -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. diff --git a/mediapipe/model_maker/python/vision/image_classifier/testdata/BUILD b/mediapipe/model_maker/python/vision/image_classifier/testdata/BUILD index 37730ea91..3d778836a 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/testdata/BUILD +++ b/mediapipe/model_maker/python/vision/image_classifier/testdata/BUILD @@ -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. diff --git a/mediapipe/model_maker/python/vision/object_detector/BUILD b/mediapipe/model_maker/python/vision/object_detector/BUILD index b97d215da..f9c3f00fc 100644 --- a/mediapipe/model_maker/python/vision/object_detector/BUILD +++ b/mediapipe/model_maker/python/vision/object_detector/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/__init__.py b/mediapipe/model_maker/python/vision/object_detector/__init__.py index ef7a92010..4670b343c 100644 --- a/mediapipe/model_maker/python/vision/object_detector/__init__.py +++ b/mediapipe/model_maker/python/vision/object_detector/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/dataset.py b/mediapipe/model_maker/python/vision/object_detector/dataset.py index f260c82c5..6899d8612 100644 --- a/mediapipe/model_maker/python/vision/object_detector/dataset.py +++ b/mediapipe/model_maker/python/vision/object_detector/dataset.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/dataset_test.py b/mediapipe/model_maker/python/vision/object_detector/dataset_test.py index 46cce68dc..91ae273be 100644 --- a/mediapipe/model_maker/python/vision/object_detector/dataset_test.py +++ b/mediapipe/model_maker/python/vision/object_detector/dataset_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/dataset_util.py b/mediapipe/model_maker/python/vision/object_detector/dataset_util.py index 440d45945..74d082f9f 100644 --- a/mediapipe/model_maker/python/vision/object_detector/dataset_util.py +++ b/mediapipe/model_maker/python/vision/object_detector/dataset_util.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/dataset_util_test.py b/mediapipe/model_maker/python/vision/object_detector/dataset_util_test.py index 7a2ef95f5..6daea1f47 100644 --- a/mediapipe/model_maker/python/vision/object_detector/dataset_util_test.py +++ b/mediapipe/model_maker/python/vision/object_detector/dataset_util_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/hyperparameters.py b/mediapipe/model_maker/python/vision/object_detector/hyperparameters.py index 241104cf8..8b49564a0 100644 --- a/mediapipe/model_maker/python/vision/object_detector/hyperparameters.py +++ b/mediapipe/model_maker/python/vision/object_detector/hyperparameters.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/model.py b/mediapipe/model_maker/python/vision/object_detector/model.py index 26e0d036c..eac669786 100644 --- a/mediapipe/model_maker/python/vision/object_detector/model.py +++ b/mediapipe/model_maker/python/vision/object_detector/model.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/model_options.py b/mediapipe/model_maker/python/vision/object_detector/model_options.py index 64042aa0f..a332804b6 100644 --- a/mediapipe/model_maker/python/vision/object_detector/model_options.py +++ b/mediapipe/model_maker/python/vision/object_detector/model_options.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/model_spec.py b/mediapipe/model_maker/python/vision/object_detector/model_spec.py index 7d284b432..2ce838c71 100644 --- a/mediapipe/model_maker/python/vision/object_detector/model_spec.py +++ b/mediapipe/model_maker/python/vision/object_detector/model_spec.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/model_test.py b/mediapipe/model_maker/python/vision/object_detector/model_test.py index 66401f8d6..3ccee4d04 100644 --- a/mediapipe/model_maker/python/vision/object_detector/model_test.py +++ b/mediapipe/model_maker/python/vision/object_detector/model_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/object_detector.py b/mediapipe/model_maker/python/vision/object_detector/object_detector.py index 2d1d92ef3..1282e1a16 100644 --- a/mediapipe/model_maker/python/vision/object_detector/object_detector.py +++ b/mediapipe/model_maker/python/vision/object_detector/object_detector.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/object_detector_demo.py b/mediapipe/model_maker/python/vision/object_detector/object_detector_demo.py index 3bbac5d8b..04820796f 100644 --- a/mediapipe/model_maker/python/vision/object_detector/object_detector_demo.py +++ b/mediapipe/model_maker/python/vision/object_detector/object_detector_demo.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/object_detector_options.py b/mediapipe/model_maker/python/vision/object_detector/object_detector_options.py index e1647cd50..6333eb81a 100644 --- a/mediapipe/model_maker/python/vision/object_detector/object_detector_options.py +++ b/mediapipe/model_maker/python/vision/object_detector/object_detector_options.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/object_detector_test.py b/mediapipe/model_maker/python/vision/object_detector/object_detector_test.py index 02f773e69..268a926fd 100644 --- a/mediapipe/model_maker/python/vision/object_detector/object_detector_test.py +++ b/mediapipe/model_maker/python/vision/object_detector/object_detector_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/preprocessor.py b/mediapipe/model_maker/python/vision/object_detector/preprocessor.py index b0d2afb74..b4e08f997 100644 --- a/mediapipe/model_maker/python/vision/object_detector/preprocessor.py +++ b/mediapipe/model_maker/python/vision/object_detector/preprocessor.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/python/vision/object_detector/preprocessor_test.py b/mediapipe/model_maker/python/vision/object_detector/preprocessor_test.py index d8ea63cd8..30db6bdff 100644 --- a/mediapipe/model_maker/python/vision/object_detector/preprocessor_test.py +++ b/mediapipe/model_maker/python/vision/object_detector/preprocessor_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/model_maker/setup.py b/mediapipe/model_maker/setup.py index ccf633909..d80e6ebe4 100644 --- a/mediapipe/model_maker/setup.py +++ b/mediapipe/model_maker/setup.py @@ -1,4 +1,4 @@ -"""Copyright 2020-2022 The MediaPipe Authors. All Rights Reserved. +"""Copyright 2020-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. diff --git a/mediapipe/tasks/BUILD b/mediapipe/tasks/BUILD index 98ddd5777..582fc4c30 100644 --- a/mediapipe/tasks/BUILD +++ b/mediapipe/tasks/BUILD @@ -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. diff --git a/mediapipe/tasks/__init__.py b/mediapipe/tasks/__init__.py index ad7f0fd95..701d72379 100644 --- a/mediapipe/tasks/__init__.py +++ b/mediapipe/tasks/__init__.py @@ -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. diff --git a/mediapipe/tasks/cc/BUILD b/mediapipe/tasks/cc/BUILD index f49657af3..39df9c55d 100644 --- a/mediapipe/tasks/cc/BUILD +++ b/mediapipe/tasks/cc/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_classifier/BUILD b/mediapipe/tasks/cc/audio/audio_classifier/BUILD index c575caabe..50f587545 100644 --- a/mediapipe/tasks/cc/audio/audio_classifier/BUILD +++ b/mediapipe/tasks/cc/audio/audio_classifier/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier.cc b/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier.cc index 822c3a22f..0ebdea108 100644 --- a/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier.cc +++ b/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier.cc @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier.h b/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier.h index dd611ec81..373b31519 100644 --- a/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier.h +++ b/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier.h @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier_graph.cc b/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier_graph.cc index b232afc72..b15a23f32 100644 --- a/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier_graph.cc +++ b/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier_test.cc b/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier_test.cc index 5f5f8da6c..30b55b8de 100644 --- a/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier_test.cc +++ b/mediapipe/tasks/cc/audio/audio_classifier/audio_classifier_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_classifier/proto/BUILD b/mediapipe/tasks/cc/audio/audio_classifier/proto/BUILD index bfe37ec01..1b3783d51 100644 --- a/mediapipe/tasks/cc/audio/audio_classifier/proto/BUILD +++ b/mediapipe/tasks/cc/audio/audio_classifier/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_classifier/proto/audio_classifier_graph_options.proto b/mediapipe/tasks/cc/audio/audio_classifier/proto/audio_classifier_graph_options.proto index cc26b3070..78eb2cf86 100644 --- a/mediapipe/tasks/cc/audio/audio_classifier/proto/audio_classifier_graph_options.proto +++ b/mediapipe/tasks/cc/audio/audio_classifier/proto/audio_classifier_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_embedder/BUILD b/mediapipe/tasks/cc/audio/audio_embedder/BUILD index d79a6f01e..7d5a49f8a 100644 --- a/mediapipe/tasks/cc/audio/audio_embedder/BUILD +++ b/mediapipe/tasks/cc/audio/audio_embedder/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder.cc b/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder.cc index 15bf1fb87..08f08bba1 100644 --- a/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder.cc +++ b/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder.cc @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder.h b/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder.h index c5f548a60..1035fa0aa 100644 --- a/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder.h +++ b/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder.h @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder_graph.cc b/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder_graph.cc index 187f11f7f..a9654947c 100644 --- a/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder_graph.cc +++ b/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder_test.cc b/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder_test.cc index 81ecb1237..a297e7c45 100644 --- a/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder_test.cc +++ b/mediapipe/tasks/cc/audio/audio_embedder/audio_embedder_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_embedder/proto/BUILD b/mediapipe/tasks/cc/audio/audio_embedder/proto/BUILD index 38df8fb44..3b26138f5 100644 --- a/mediapipe/tasks/cc/audio/audio_embedder/proto/BUILD +++ b/mediapipe/tasks/cc/audio/audio_embedder/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/audio/audio_embedder/proto/audio_embedder_graph_options.proto b/mediapipe/tasks/cc/audio/audio_embedder/proto/audio_embedder_graph_options.proto index 367a1bf26..a6f7275e5 100644 --- a/mediapipe/tasks/cc/audio/audio_embedder/proto/audio_embedder_graph_options.proto +++ b/mediapipe/tasks/cc/audio/audio_embedder/proto/audio_embedder_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/audio/core/BUILD b/mediapipe/tasks/cc/audio/core/BUILD index 016faa10f..8372b1aa2 100644 --- a/mediapipe/tasks/cc/audio/core/BUILD +++ b/mediapipe/tasks/cc/audio/core/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/audio/core/audio_task_api_factory.h b/mediapipe/tasks/cc/audio/core/audio_task_api_factory.h index 6f5c4ff67..bdac1cad0 100644 --- a/mediapipe/tasks/cc/audio/core/audio_task_api_factory.h +++ b/mediapipe/tasks/cc/audio/core/audio_task_api_factory.h @@ -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. diff --git a/mediapipe/tasks/cc/audio/core/base_audio_task_api.h b/mediapipe/tasks/cc/audio/core/base_audio_task_api.h index c04b3cf32..ef8254d17 100644 --- a/mediapipe/tasks/cc/audio/core/base_audio_task_api.h +++ b/mediapipe/tasks/cc/audio/core/base_audio_task_api.h @@ -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. diff --git a/mediapipe/tasks/cc/audio/core/running_mode.h b/mediapipe/tasks/cc/audio/core/running_mode.h index 332454f9f..b7e857a58 100644 --- a/mediapipe/tasks/cc/audio/core/running_mode.h +++ b/mediapipe/tasks/cc/audio/core/running_mode.h @@ -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. diff --git a/mediapipe/tasks/cc/audio/utils/BUILD b/mediapipe/tasks/cc/audio/utils/BUILD index 29d88d33d..a25bbe8ac 100644 --- a/mediapipe/tasks/cc/audio/utils/BUILD +++ b/mediapipe/tasks/cc/audio/utils/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/audio/utils/audio_tensor_specs.cc b/mediapipe/tasks/cc/audio/utils/audio_tensor_specs.cc index 8efd94741..6765bc63c 100644 --- a/mediapipe/tasks/cc/audio/utils/audio_tensor_specs.cc +++ b/mediapipe/tasks/cc/audio/utils/audio_tensor_specs.cc @@ -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. diff --git a/mediapipe/tasks/cc/audio/utils/audio_tensor_specs.h b/mediapipe/tasks/cc/audio/utils/audio_tensor_specs.h index 69393a10a..09bfa264f 100644 --- a/mediapipe/tasks/cc/audio/utils/audio_tensor_specs.h +++ b/mediapipe/tasks/cc/audio/utils/audio_tensor_specs.h @@ -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. diff --git a/mediapipe/tasks/cc/audio/utils/audio_tensor_specs_test.cc b/mediapipe/tasks/cc/audio/utils/audio_tensor_specs_test.cc index 4f7a5000e..32816a92f 100644 --- a/mediapipe/tasks/cc/audio/utils/audio_tensor_specs_test.cc +++ b/mediapipe/tasks/cc/audio/utils/audio_tensor_specs_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/common.cc b/mediapipe/tasks/cc/common.cc index e7102edc3..cdb069a72 100644 --- a/mediapipe/tasks/cc/common.cc +++ b/mediapipe/tasks/cc/common.cc @@ -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. diff --git a/mediapipe/tasks/cc/common.h b/mediapipe/tasks/cc/common.h index 70892c5cd..bee410957 100644 --- a/mediapipe/tasks/cc/common.h +++ b/mediapipe/tasks/cc/common.h @@ -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. diff --git a/mediapipe/tasks/cc/components/calculators/BUILD b/mediapipe/tasks/cc/components/calculators/BUILD index e447f5d72..fb4b66b35 100644 --- a/mediapipe/tasks/cc/components/calculators/BUILD +++ b/mediapipe/tasks/cc/components/calculators/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/components/calculators/classification_aggregation_calculator.proto b/mediapipe/tasks/cc/components/calculators/classification_aggregation_calculator.proto index e2ed1788e..fba146f74 100644 --- a/mediapipe/tasks/cc/components/calculators/classification_aggregation_calculator.proto +++ b/mediapipe/tasks/cc/components/calculators/classification_aggregation_calculator.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/calculators/classification_aggregation_calculator_test.cc b/mediapipe/tasks/cc/components/calculators/classification_aggregation_calculator_test.cc index c824919df..4fb9eead5 100644 --- a/mediapipe/tasks/cc/components/calculators/classification_aggregation_calculator_test.cc +++ b/mediapipe/tasks/cc/components/calculators/classification_aggregation_calculator_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/calculators/embedding_aggregation_calculator_test.cc b/mediapipe/tasks/cc/components/calculators/embedding_aggregation_calculator_test.cc index c4b635d24..040a803a1 100644 --- a/mediapipe/tasks/cc/components/calculators/embedding_aggregation_calculator_test.cc +++ b/mediapipe/tasks/cc/components/calculators/embedding_aggregation_calculator_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/calculators/end_loop_calculator.cc b/mediapipe/tasks/cc/components/calculators/end_loop_calculator.cc index 10eb962dd..883ada6cb 100644 --- a/mediapipe/tasks/cc/components/calculators/end_loop_calculator.cc +++ b/mediapipe/tasks/cc/components/calculators/end_loop_calculator.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/calculators/score_calibration_calculator.proto b/mediapipe/tasks/cc/components/calculators/score_calibration_calculator.proto index 11d944c93..e614c6207 100644 --- a/mediapipe/tasks/cc/components/calculators/score_calibration_calculator.proto +++ b/mediapipe/tasks/cc/components/calculators/score_calibration_calculator.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/calculators/tensors_to_embeddings_calculator.proto b/mediapipe/tasks/cc/components/calculators/tensors_to_embeddings_calculator.proto index fd87383b4..7dd4a6058 100644 --- a/mediapipe/tasks/cc/components/calculators/tensors_to_embeddings_calculator.proto +++ b/mediapipe/tasks/cc/components/calculators/tensors_to_embeddings_calculator.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/BUILD b/mediapipe/tasks/cc/components/containers/BUILD index 816e3c766..b19a178b9 100644 --- a/mediapipe/tasks/cc/components/containers/BUILD +++ b/mediapipe/tasks/cc/components/containers/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/category.cc b/mediapipe/tasks/cc/components/containers/category.cc index e07333a7b..65b553842 100644 --- a/mediapipe/tasks/cc/components/containers/category.cc +++ b/mediapipe/tasks/cc/components/containers/category.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/category.h b/mediapipe/tasks/cc/components/containers/category.h index 57b18e7ea..1bff5601d 100644 --- a/mediapipe/tasks/cc/components/containers/category.h +++ b/mediapipe/tasks/cc/components/containers/category.h @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/classification_result.cc b/mediapipe/tasks/cc/components/containers/classification_result.cc index f2d88406d..bbedc273d 100644 --- a/mediapipe/tasks/cc/components/containers/classification_result.cc +++ b/mediapipe/tasks/cc/components/containers/classification_result.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/classification_result.h b/mediapipe/tasks/cc/components/containers/classification_result.h index e359fb33e..5b736cefd 100644 --- a/mediapipe/tasks/cc/components/containers/classification_result.h +++ b/mediapipe/tasks/cc/components/containers/classification_result.h @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/detection_result.cc b/mediapipe/tasks/cc/components/containers/detection_result.cc index c5e4cde41..1be7950fd 100644 --- a/mediapipe/tasks/cc/components/containers/detection_result.cc +++ b/mediapipe/tasks/cc/components/containers/detection_result.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/detection_result.h b/mediapipe/tasks/cc/components/containers/detection_result.h index cfddfdb00..c267fc5a7 100644 --- a/mediapipe/tasks/cc/components/containers/detection_result.h +++ b/mediapipe/tasks/cc/components/containers/detection_result.h @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/embedding_result.cc b/mediapipe/tasks/cc/components/containers/embedding_result.cc index 9de55911b..15e762e38 100644 --- a/mediapipe/tasks/cc/components/containers/embedding_result.cc +++ b/mediapipe/tasks/cc/components/containers/embedding_result.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/embedding_result.h b/mediapipe/tasks/cc/components/containers/embedding_result.h index 2d01d2f2a..4fdb8d24e 100644 --- a/mediapipe/tasks/cc/components/containers/embedding_result.h +++ b/mediapipe/tasks/cc/components/containers/embedding_result.h @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/keypoint.h b/mediapipe/tasks/cc/components/containers/keypoint.h index dd01037c8..89de36601 100644 --- a/mediapipe/tasks/cc/components/containers/keypoint.h +++ b/mediapipe/tasks/cc/components/containers/keypoint.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/components/containers/landmark.cc b/mediapipe/tasks/cc/components/containers/landmark.cc index 6d80cb835..1cd0b4c3f 100644 --- a/mediapipe/tasks/cc/components/containers/landmark.cc +++ b/mediapipe/tasks/cc/components/containers/landmark.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/components/containers/landmark.h b/mediapipe/tasks/cc/components/containers/landmark.h index 5cb57bfb3..63760ae8b 100644 --- a/mediapipe/tasks/cc/components/containers/landmark.h +++ b/mediapipe/tasks/cc/components/containers/landmark.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/components/containers/proto/BUILD b/mediapipe/tasks/cc/components/containers/proto/BUILD index 27d2357b5..66255aed7 100644 --- a/mediapipe/tasks/cc/components/containers/proto/BUILD +++ b/mediapipe/tasks/cc/components/containers/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/proto/classifications.proto b/mediapipe/tasks/cc/components/containers/proto/classifications.proto index 2b2306829..e4a6ec29d 100644 --- a/mediapipe/tasks/cc/components/containers/proto/classifications.proto +++ b/mediapipe/tasks/cc/components/containers/proto/classifications.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/proto/embeddings.proto b/mediapipe/tasks/cc/components/containers/proto/embeddings.proto index 4f888c699..0b55a1a95 100644 --- a/mediapipe/tasks/cc/components/containers/proto/embeddings.proto +++ b/mediapipe/tasks/cc/components/containers/proto/embeddings.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/proto/landmarks_detection_result.proto b/mediapipe/tasks/cc/components/containers/proto/landmarks_detection_result.proto index ac44f9b58..2e28d3c02 100644 --- a/mediapipe/tasks/cc/components/containers/proto/landmarks_detection_result.proto +++ b/mediapipe/tasks/cc/components/containers/proto/landmarks_detection_result.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/rect.cc b/mediapipe/tasks/cc/components/containers/rect.cc index 4a94832a6..3a733e81e 100644 --- a/mediapipe/tasks/cc/components/containers/rect.cc +++ b/mediapipe/tasks/cc/components/containers/rect.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/containers/rect.h b/mediapipe/tasks/cc/components/containers/rect.h index 72c7a8acb..80af898cf 100644 --- a/mediapipe/tasks/cc/components/containers/rect.h +++ b/mediapipe/tasks/cc/components/containers/rect.h @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/BUILD b/mediapipe/tasks/cc/components/processors/BUILD index dfa18e806..532bc9a3b 100644 --- a/mediapipe/tasks/cc/components/processors/BUILD +++ b/mediapipe/tasks/cc/components/processors/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.cc b/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.cc index 9f796920c..5534cb96d 100644 --- a/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.cc +++ b/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.h b/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.h index 03ae91130..e29aef19c 100644 --- a/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.h +++ b/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.h @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph_test.cc b/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph_test.cc index a61ffa6b1..014053fa0 100644 --- a/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph_test.cc +++ b/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/classifier_options.cc b/mediapipe/tasks/cc/components/processors/classifier_options.cc index 349bb569d..0343db2ec 100644 --- a/mediapipe/tasks/cc/components/processors/classifier_options.cc +++ b/mediapipe/tasks/cc/components/processors/classifier_options.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/classifier_options.h b/mediapipe/tasks/cc/components/processors/classifier_options.h index 189b42e60..598e3dab6 100644 --- a/mediapipe/tasks/cc/components/processors/classifier_options.h +++ b/mediapipe/tasks/cc/components/processors/classifier_options.h @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/embedder_options.cc b/mediapipe/tasks/cc/components/processors/embedder_options.cc index fce7baa44..2f2121dd6 100644 --- a/mediapipe/tasks/cc/components/processors/embedder_options.cc +++ b/mediapipe/tasks/cc/components/processors/embedder_options.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/embedder_options.h b/mediapipe/tasks/cc/components/processors/embedder_options.h index b37171592..483e48670 100644 --- a/mediapipe/tasks/cc/components/processors/embedder_options.h +++ b/mediapipe/tasks/cc/components/processors/embedder_options.h @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph.cc b/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph.cc index 7b023ba41..ec28d6294 100644 --- a/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph.cc +++ b/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph.h b/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph.h index 889992463..bb96dfbd5 100644 --- a/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph.h +++ b/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph.h @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph_test.cc b/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph_test.cc index 94a2a7f3f..0f0710405 100644 --- a/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph_test.cc +++ b/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.cc b/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.cc index 7a45bb148..1040701c4 100644 --- a/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.cc +++ b/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.h b/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.h index 455a9b316..2f7473fe4 100644 --- a/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.h +++ b/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.h @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/image_preprocessing_graph_test.cc b/mediapipe/tasks/cc/components/processors/image_preprocessing_graph_test.cc index c69a51a65..2e182ee85 100644 --- a/mediapipe/tasks/cc/components/processors/image_preprocessing_graph_test.cc +++ b/mediapipe/tasks/cc/components/processors/image_preprocessing_graph_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/proto/BUILD b/mediapipe/tasks/cc/components/processors/proto/BUILD index 816ba47e3..1877bc7e2 100644 --- a/mediapipe/tasks/cc/components/processors/proto/BUILD +++ b/mediapipe/tasks/cc/components/processors/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/proto/classification_postprocessing_graph_options.proto b/mediapipe/tasks/cc/components/processors/proto/classification_postprocessing_graph_options.proto index 84ba95222..e393f58ca 100644 --- a/mediapipe/tasks/cc/components/processors/proto/classification_postprocessing_graph_options.proto +++ b/mediapipe/tasks/cc/components/processors/proto/classification_postprocessing_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/proto/classifier_options.proto b/mediapipe/tasks/cc/components/processors/proto/classifier_options.proto index 12ece7249..345c7e1fc 100644 --- a/mediapipe/tasks/cc/components/processors/proto/classifier_options.proto +++ b/mediapipe/tasks/cc/components/processors/proto/classifier_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/proto/embedder_options.proto b/mediapipe/tasks/cc/components/processors/proto/embedder_options.proto index 8973ab248..4595bfc86 100644 --- a/mediapipe/tasks/cc/components/processors/proto/embedder_options.proto +++ b/mediapipe/tasks/cc/components/processors/proto/embedder_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/proto/embedding_postprocessing_graph_options.proto b/mediapipe/tasks/cc/components/processors/proto/embedding_postprocessing_graph_options.proto index 3a50818f6..5e04a8d1f 100644 --- a/mediapipe/tasks/cc/components/processors/proto/embedding_postprocessing_graph_options.proto +++ b/mediapipe/tasks/cc/components/processors/proto/embedding_postprocessing_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/proto/image_preprocessing_graph_options.proto b/mediapipe/tasks/cc/components/processors/proto/image_preprocessing_graph_options.proto index bf4fc9067..e8704679d 100644 --- a/mediapipe/tasks/cc/components/processors/proto/image_preprocessing_graph_options.proto +++ b/mediapipe/tasks/cc/components/processors/proto/image_preprocessing_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/proto/text_model_type.proto b/mediapipe/tasks/cc/components/processors/proto/text_model_type.proto index db363c75d..1e9cf48c4 100644 --- a/mediapipe/tasks/cc/components/processors/proto/text_model_type.proto +++ b/mediapipe/tasks/cc/components/processors/proto/text_model_type.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/proto/text_preprocessing_graph_options.proto b/mediapipe/tasks/cc/components/processors/proto/text_preprocessing_graph_options.proto index 8ddd52439..dbb28c9e1 100644 --- a/mediapipe/tasks/cc/components/processors/proto/text_preprocessing_graph_options.proto +++ b/mediapipe/tasks/cc/components/processors/proto/text_preprocessing_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/text_preprocessing_graph.cc b/mediapipe/tasks/cc/components/processors/text_preprocessing_graph.cc index 7587161ae..ecf59e2d1 100644 --- a/mediapipe/tasks/cc/components/processors/text_preprocessing_graph.cc +++ b/mediapipe/tasks/cc/components/processors/text_preprocessing_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/processors/text_preprocessing_graph.h b/mediapipe/tasks/cc/components/processors/text_preprocessing_graph.h index 43d57be29..6d5fdb5f8 100644 --- a/mediapipe/tasks/cc/components/processors/text_preprocessing_graph.h +++ b/mediapipe/tasks/cc/components/processors/text_preprocessing_graph.h @@ -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. diff --git a/mediapipe/tasks/cc/components/utils/BUILD b/mediapipe/tasks/cc/components/utils/BUILD index 2e0ea3ce6..f2ebcd4b3 100644 --- a/mediapipe/tasks/cc/components/utils/BUILD +++ b/mediapipe/tasks/cc/components/utils/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/components/utils/cosine_similarity.cc b/mediapipe/tasks/cc/components/utils/cosine_similarity.cc index 1403700c8..8ef33073c 100644 --- a/mediapipe/tasks/cc/components/utils/cosine_similarity.cc +++ b/mediapipe/tasks/cc/components/utils/cosine_similarity.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/utils/cosine_similarity.h b/mediapipe/tasks/cc/components/utils/cosine_similarity.h index 45ddce76e..b2ebabca4 100644 --- a/mediapipe/tasks/cc/components/utils/cosine_similarity.h +++ b/mediapipe/tasks/cc/components/utils/cosine_similarity.h @@ -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. diff --git a/mediapipe/tasks/cc/components/utils/cosine_similarity_test.cc b/mediapipe/tasks/cc/components/utils/cosine_similarity_test.cc index 4ff9dfc3a..f476a7d43 100644 --- a/mediapipe/tasks/cc/components/utils/cosine_similarity_test.cc +++ b/mediapipe/tasks/cc/components/utils/cosine_similarity_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/components/utils/gate.h b/mediapipe/tasks/cc/components/utils/gate.h index 139205fc5..2b1fc4658 100644 --- a/mediapipe/tasks/cc/components/utils/gate.h +++ b/mediapipe/tasks/cc/components/utils/gate.h @@ -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. diff --git a/mediapipe/tasks/cc/components/utils/gate_test.cc b/mediapipe/tasks/cc/components/utils/gate_test.cc index 47ff25074..94231496d 100644 --- a/mediapipe/tasks/cc/components/utils/gate_test.cc +++ b/mediapipe/tasks/cc/components/utils/gate_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/BUILD b/mediapipe/tasks/cc/core/BUILD index 6f1daa580..dad9cdf1f 100644 --- a/mediapipe/tasks/cc/core/BUILD +++ b/mediapipe/tasks/cc/core/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/core/base_options.cc b/mediapipe/tasks/cc/core/base_options.cc index 8bee6b469..410e8d353 100644 --- a/mediapipe/tasks/cc/core/base_options.cc +++ b/mediapipe/tasks/cc/core/base_options.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/base_options.h b/mediapipe/tasks/cc/core/base_options.h index b6a0f0556..021aebbe5 100644 --- a/mediapipe/tasks/cc/core/base_options.h +++ b/mediapipe/tasks/cc/core/base_options.h @@ -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. diff --git a/mediapipe/tasks/cc/core/base_task_api.h b/mediapipe/tasks/cc/core/base_task_api.h index 92d41cc84..5238527a3 100644 --- a/mediapipe/tasks/cc/core/base_task_api.h +++ b/mediapipe/tasks/cc/core/base_task_api.h @@ -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. diff --git a/mediapipe/tasks/cc/core/external_file_handler.cc b/mediapipe/tasks/cc/core/external_file_handler.cc index 27b579f97..af304c466 100644 --- a/mediapipe/tasks/cc/core/external_file_handler.cc +++ b/mediapipe/tasks/cc/core/external_file_handler.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/external_file_handler.h b/mediapipe/tasks/cc/core/external_file_handler.h index 04a3e1ac4..3150fde59 100644 --- a/mediapipe/tasks/cc/core/external_file_handler.h +++ b/mediapipe/tasks/cc/core/external_file_handler.h @@ -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. diff --git a/mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.cc b/mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.cc index 80097fd09..b816d8859 100644 --- a/mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.cc +++ b/mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.h b/mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.h index a7c28aa71..6c045d73d 100644 --- a/mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.h +++ b/mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.h @@ -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. diff --git a/mediapipe/tasks/cc/core/model_asset_bundle_resources.cc b/mediapipe/tasks/cc/core/model_asset_bundle_resources.cc index 2f53ff2d5..58b30630d 100644 --- a/mediapipe/tasks/cc/core/model_asset_bundle_resources.cc +++ b/mediapipe/tasks/cc/core/model_asset_bundle_resources.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/model_asset_bundle_resources.h b/mediapipe/tasks/cc/core/model_asset_bundle_resources.h index 02d989d4b..5b334fabd 100644 --- a/mediapipe/tasks/cc/core/model_asset_bundle_resources.h +++ b/mediapipe/tasks/cc/core/model_asset_bundle_resources.h @@ -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. diff --git a/mediapipe/tasks/cc/core/model_asset_bundle_resources_test.cc b/mediapipe/tasks/cc/core/model_asset_bundle_resources_test.cc index 85a94ccc7..4cf53fe42 100644 --- a/mediapipe/tasks/cc/core/model_asset_bundle_resources_test.cc +++ b/mediapipe/tasks/cc/core/model_asset_bundle_resources_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/model_resources.cc b/mediapipe/tasks/cc/core/model_resources.cc index 76695125a..1a917f72f 100644 --- a/mediapipe/tasks/cc/core/model_resources.cc +++ b/mediapipe/tasks/cc/core/model_resources.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/model_resources.h b/mediapipe/tasks/cc/core/model_resources.h index 1bc1b65eb..d8e8dada0 100644 --- a/mediapipe/tasks/cc/core/model_resources.h +++ b/mediapipe/tasks/cc/core/model_resources.h @@ -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. diff --git a/mediapipe/tasks/cc/core/model_resources_cache.cc b/mediapipe/tasks/cc/core/model_resources_cache.cc index affcb6dea..ced64babd 100644 --- a/mediapipe/tasks/cc/core/model_resources_cache.cc +++ b/mediapipe/tasks/cc/core/model_resources_cache.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/model_resources_cache.h b/mediapipe/tasks/cc/core/model_resources_cache.h index 32909f93d..75c24f344 100644 --- a/mediapipe/tasks/cc/core/model_resources_cache.h +++ b/mediapipe/tasks/cc/core/model_resources_cache.h @@ -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. diff --git a/mediapipe/tasks/cc/core/model_resources_calculator.cc b/mediapipe/tasks/cc/core/model_resources_calculator.cc index d5c8cd502..8db35818c 100644 --- a/mediapipe/tasks/cc/core/model_resources_calculator.cc +++ b/mediapipe/tasks/cc/core/model_resources_calculator.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/model_resources_calculator_test.cc b/mediapipe/tasks/cc/core/model_resources_calculator_test.cc index 6ba52e521..cf10a209e 100644 --- a/mediapipe/tasks/cc/core/model_resources_calculator_test.cc +++ b/mediapipe/tasks/cc/core/model_resources_calculator_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/model_resources_test.cc b/mediapipe/tasks/cc/core/model_resources_test.cc index 036d0e784..ffd78f3de 100644 --- a/mediapipe/tasks/cc/core/model_resources_test.cc +++ b/mediapipe/tasks/cc/core/model_resources_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/model_task_graph.cc b/mediapipe/tasks/cc/core/model_task_graph.cc index 8767fb48b..46cc088f2 100644 --- a/mediapipe/tasks/cc/core/model_task_graph.cc +++ b/mediapipe/tasks/cc/core/model_task_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/model_task_graph.h b/mediapipe/tasks/cc/core/model_task_graph.h index aa864c9fc..10634d3d0 100644 --- a/mediapipe/tasks/cc/core/model_task_graph.h +++ b/mediapipe/tasks/cc/core/model_task_graph.h @@ -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. diff --git a/mediapipe/tasks/cc/core/proto/BUILD b/mediapipe/tasks/cc/core/proto/BUILD index fff935b24..72de1be85 100644 --- a/mediapipe/tasks/cc/core/proto/BUILD +++ b/mediapipe/tasks/cc/core/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/core/proto/acceleration.proto b/mediapipe/tasks/cc/core/proto/acceleration.proto index c7215604a..64165f292 100644 --- a/mediapipe/tasks/cc/core/proto/acceleration.proto +++ b/mediapipe/tasks/cc/core/proto/acceleration.proto @@ -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. diff --git a/mediapipe/tasks/cc/core/proto/base_options.proto b/mediapipe/tasks/cc/core/proto/base_options.proto index b7c0629e8..9c9571923 100644 --- a/mediapipe/tasks/cc/core/proto/base_options.proto +++ b/mediapipe/tasks/cc/core/proto/base_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/core/proto/external_file.proto b/mediapipe/tasks/cc/core/proto/external_file.proto index 3147a2224..dbb3da37c 100644 --- a/mediapipe/tasks/cc/core/proto/external_file.proto +++ b/mediapipe/tasks/cc/core/proto/external_file.proto @@ -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. diff --git a/mediapipe/tasks/cc/core/proto/inference_subgraph.proto b/mediapipe/tasks/cc/core/proto/inference_subgraph.proto index 2232a1153..d4c80020b 100644 --- a/mediapipe/tasks/cc/core/proto/inference_subgraph.proto +++ b/mediapipe/tasks/cc/core/proto/inference_subgraph.proto @@ -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. diff --git a/mediapipe/tasks/cc/core/proto/model_resources_calculator.proto b/mediapipe/tasks/cc/core/proto/model_resources_calculator.proto index dd67bb479..ec200fd19 100644 --- a/mediapipe/tasks/cc/core/proto/model_resources_calculator.proto +++ b/mediapipe/tasks/cc/core/proto/model_resources_calculator.proto @@ -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. diff --git a/mediapipe/tasks/cc/core/task_api_factory.h b/mediapipe/tasks/cc/core/task_api_factory.h index 83c2f3207..6c55a6567 100644 --- a/mediapipe/tasks/cc/core/task_api_factory.h +++ b/mediapipe/tasks/cc/core/task_api_factory.h @@ -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. diff --git a/mediapipe/tasks/cc/core/task_runner.cc b/mediapipe/tasks/cc/core/task_runner.cc index fc933d547..d97c4e480 100644 --- a/mediapipe/tasks/cc/core/task_runner.cc +++ b/mediapipe/tasks/cc/core/task_runner.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/task_runner.h b/mediapipe/tasks/cc/core/task_runner.h index 8123a45aa..cd77c0555 100644 --- a/mediapipe/tasks/cc/core/task_runner.h +++ b/mediapipe/tasks/cc/core/task_runner.h @@ -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. diff --git a/mediapipe/tasks/cc/core/task_runner_test.cc b/mediapipe/tasks/cc/core/task_runner_test.cc index 75c6260af..6a53a0ff1 100644 --- a/mediapipe/tasks/cc/core/task_runner_test.cc +++ b/mediapipe/tasks/cc/core/task_runner_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/utils.cc b/mediapipe/tasks/cc/core/utils.cc index 1e44109c3..168c4363c 100644 --- a/mediapipe/tasks/cc/core/utils.cc +++ b/mediapipe/tasks/cc/core/utils.cc @@ -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. diff --git a/mediapipe/tasks/cc/core/utils.h b/mediapipe/tasks/cc/core/utils.h index 4ca51fa91..54d63866d 100644 --- a/mediapipe/tasks/cc/core/utils.h +++ b/mediapipe/tasks/cc/core/utils.h @@ -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. diff --git a/mediapipe/tasks/cc/metadata/metadata_extractor.cc b/mediapipe/tasks/cc/metadata/metadata_extractor.cc index 4d6f526f5..16e05d7a3 100644 --- a/mediapipe/tasks/cc/metadata/metadata_extractor.cc +++ b/mediapipe/tasks/cc/metadata/metadata_extractor.cc @@ -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. diff --git a/mediapipe/tasks/cc/metadata/metadata_extractor.h b/mediapipe/tasks/cc/metadata/metadata_extractor.h index b88eda863..c1d8a4c2a 100644 --- a/mediapipe/tasks/cc/metadata/metadata_extractor.h +++ b/mediapipe/tasks/cc/metadata/metadata_extractor.h @@ -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. diff --git a/mediapipe/tasks/cc/metadata/metadata_parser.h.template b/mediapipe/tasks/cc/metadata/metadata_parser.h.template index 28c38af82..852791a03 100644 --- a/mediapipe/tasks/cc/metadata/metadata_parser.h.template +++ b/mediapipe/tasks/cc/metadata/metadata_parser.h.template @@ -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. diff --git a/mediapipe/tasks/cc/metadata/metadata_populator.cc b/mediapipe/tasks/cc/metadata/metadata_populator.cc index a6fd496a3..872bc2b20 100644 --- a/mediapipe/tasks/cc/metadata/metadata_populator.cc +++ b/mediapipe/tasks/cc/metadata/metadata_populator.cc @@ -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. diff --git a/mediapipe/tasks/cc/metadata/metadata_populator.h b/mediapipe/tasks/cc/metadata/metadata_populator.h index c0554f704..c3856e104 100644 --- a/mediapipe/tasks/cc/metadata/metadata_populator.h +++ b/mediapipe/tasks/cc/metadata/metadata_populator.h @@ -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. diff --git a/mediapipe/tasks/cc/metadata/metadata_version.cc b/mediapipe/tasks/cc/metadata/metadata_version.cc index 7e2414dd5..aab3d8c56 100644 --- a/mediapipe/tasks/cc/metadata/metadata_version.cc +++ b/mediapipe/tasks/cc/metadata/metadata_version.cc @@ -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. diff --git a/mediapipe/tasks/cc/metadata/metadata_version.h b/mediapipe/tasks/cc/metadata/metadata_version.h index a53caa547..bb0bd36f9 100644 --- a/mediapipe/tasks/cc/metadata/metadata_version.h +++ b/mediapipe/tasks/cc/metadata/metadata_version.h @@ -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. diff --git a/mediapipe/tasks/cc/metadata/python/metadata_version.cc b/mediapipe/tasks/cc/metadata/python/metadata_version.cc index e3072bc9e..e1e50459e 100644 --- a/mediapipe/tasks/cc/metadata/python/metadata_version.cc +++ b/mediapipe/tasks/cc/metadata/python/metadata_version.cc @@ -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. diff --git a/mediapipe/tasks/cc/metadata/tests/metadata_extractor_test.cc b/mediapipe/tasks/cc/metadata/tests/metadata_extractor_test.cc index 0e05e5167..bed1610d6 100644 --- a/mediapipe/tasks/cc/metadata/tests/metadata_extractor_test.cc +++ b/mediapipe/tasks/cc/metadata/tests/metadata_extractor_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/metadata/tests/metadata_parser_test.cc b/mediapipe/tasks/cc/metadata/tests/metadata_parser_test.cc index 0d613e65e..9b70f7a28 100644 --- a/mediapipe/tasks/cc/metadata/tests/metadata_parser_test.cc +++ b/mediapipe/tasks/cc/metadata/tests/metadata_parser_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/metadata/tests/metadata_version_test.cc b/mediapipe/tasks/cc/metadata/tests/metadata_version_test.cc index 63cd2ff9c..188560b54 100644 --- a/mediapipe/tasks/cc/metadata/tests/metadata_version_test.cc +++ b/mediapipe/tasks/cc/metadata/tests/metadata_version_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/metadata/tests/metadata_version_utils_test.cc b/mediapipe/tasks/cc/metadata/tests/metadata_version_utils_test.cc index eaaa39f0e..ae4315f90 100644 --- a/mediapipe/tasks/cc/metadata/tests/metadata_version_utils_test.cc +++ b/mediapipe/tasks/cc/metadata/tests/metadata_version_utils_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/metadata/utils/zip_readonly_mem_file.cc b/mediapipe/tasks/cc/metadata/utils/zip_readonly_mem_file.cc index a231afc40..cd5fa6316 100644 --- a/mediapipe/tasks/cc/metadata/utils/zip_readonly_mem_file.cc +++ b/mediapipe/tasks/cc/metadata/utils/zip_readonly_mem_file.cc @@ -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. diff --git a/mediapipe/tasks/cc/metadata/utils/zip_readonly_mem_file.h b/mediapipe/tasks/cc/metadata/utils/zip_readonly_mem_file.h index fcd22d6d6..b99664b75 100644 --- a/mediapipe/tasks/cc/metadata/utils/zip_readonly_mem_file.h +++ b/mediapipe/tasks/cc/metadata/utils/zip_readonly_mem_file.h @@ -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. diff --git a/mediapipe/tasks/cc/metadata/utils/zip_utils.cc b/mediapipe/tasks/cc/metadata/utils/zip_utils.cc index 2c09e1961..e0cc3d773 100644 --- a/mediapipe/tasks/cc/metadata/utils/zip_utils.cc +++ b/mediapipe/tasks/cc/metadata/utils/zip_utils.cc @@ -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. diff --git a/mediapipe/tasks/cc/metadata/utils/zip_utils.h b/mediapipe/tasks/cc/metadata/utils/zip_utils.h index 10ad0a5a9..e69abf9ff 100644 --- a/mediapipe/tasks/cc/metadata/utils/zip_utils.h +++ b/mediapipe/tasks/cc/metadata/utils/zip_utils.h @@ -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. diff --git a/mediapipe/tasks/cc/metadata/utils/zip_writable_mem_file.cc b/mediapipe/tasks/cc/metadata/utils/zip_writable_mem_file.cc index 3dc1f1950..1f27c5bfd 100644 --- a/mediapipe/tasks/cc/metadata/utils/zip_writable_mem_file.cc +++ b/mediapipe/tasks/cc/metadata/utils/zip_writable_mem_file.cc @@ -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. diff --git a/mediapipe/tasks/cc/metadata/utils/zip_writable_mem_file.h b/mediapipe/tasks/cc/metadata/utils/zip_writable_mem_file.h index ca06476ec..6a28e2d8a 100644 --- a/mediapipe/tasks/cc/metadata/utils/zip_writable_mem_file.h +++ b/mediapipe/tasks/cc/metadata/utils/zip_writable_mem_file.h @@ -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. diff --git a/mediapipe/tasks/cc/text/custom_ops/ragged/BUILD b/mediapipe/tasks/cc/text/custom_ops/ragged/BUILD index 00e8fa1e7..c8a38f94f 100644 --- a/mediapipe/tasks/cc/text/custom_ops/ragged/BUILD +++ b/mediapipe/tasks/cc/text/custom_ops/ragged/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/ragged/ragged_tensor_to_tensor_tflite.cc b/mediapipe/tasks/cc/text/custom_ops/ragged/ragged_tensor_to_tensor_tflite.cc index 4ba1a9291..a0eadd715 100644 --- a/mediapipe/tasks/cc/text/custom_ops/ragged/ragged_tensor_to_tensor_tflite.cc +++ b/mediapipe/tasks/cc/text/custom_ops/ragged/ragged_tensor_to_tensor_tflite.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/ragged/ragged_tensor_to_tensor_tflite.h b/mediapipe/tasks/cc/text/custom_ops/ragged/ragged_tensor_to_tensor_tflite.h index 02536c97a..65da8d055 100644 --- a/mediapipe/tasks/cc/text/custom_ops/ragged/ragged_tensor_to_tensor_tflite.h +++ b/mediapipe/tasks/cc/text/custom_ops/ragged/ragged_tensor_to_tensor_tflite.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/ragged/ragged_tensor_to_tensor_tflite_test.cc b/mediapipe/tasks/cc/text/custom_ops/ragged/ragged_tensor_to_tensor_tflite_test.cc index 38e220344..e0c8604e1 100644 --- a/mediapipe/tasks/cc/text/custom_ops/ragged/ragged_tensor_to_tensor_tflite_test.cc +++ b/mediapipe/tasks/cc/text/custom_ops/ragged/ragged_tensor_to_tensor_tflite_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/BUILD b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/BUILD index 19f843c4e..334ed74d4 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/BUILD +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/config.fbs b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/config.fbs index 16408ffee..6fb5f1bff 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/config.fbs +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/config.fbs @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie.h b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie.h index c3b568f1c..d6497c747 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie.h +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie_builder.cc b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie_builder.cc index f492b5c48..85f6c2f59 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie_builder.cc +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie_builder.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie_builder.h b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie_builder.h index 94c50bffc..90c8f6066 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie_builder.h +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie_builder.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie_test.cc b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie_test.cc index 60a78e126..a53c9be1e 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie_test.cc +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/double_array_trie_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/encoder_config.fbs b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/encoder_config.fbs index 2e7836803..3aed17ee3 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/encoder_config.fbs +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/encoder_config.fbs @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/model_converter.cc b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/model_converter.cc index 3a831f3d7..0c407448e 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/model_converter.cc +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/model_converter.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/model_converter.h b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/model_converter.h index 828db16da..49410fa56 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/model_converter.h +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/model_converter.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/optimized_encoder.cc b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/optimized_encoder.cc index 365b1a5ad..0dbc061fc 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/optimized_encoder.cc +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/optimized_encoder.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/optimized_encoder.h b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/optimized_encoder.h index 849a47849..d4712dc94 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/optimized_encoder.h +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/optimized_encoder.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/optimized_encoder_test.cc b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/optimized_encoder_test.cc index e65bd1850..fcef6b864 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/optimized_encoder_test.cc +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/optimized_encoder_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/sentencepiece_constants.h b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/sentencepiece_constants.h index faf481844..bb50c4f96 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/sentencepiece_constants.h +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/sentencepiece_constants.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/sentencepiece_tokenizer_tflite.cc b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/sentencepiece_tokenizer_tflite.cc index 468a3a54f..481fd5237 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/sentencepiece_tokenizer_tflite.cc +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/sentencepiece_tokenizer_tflite.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/sentencepiece_tokenizer_tflite.h b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/sentencepiece_tokenizer_tflite.h index 8a9fa8aef..f6c89bdb0 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/sentencepiece_tokenizer_tflite.h +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/sentencepiece_tokenizer_tflite.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/utils.h b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/utils.h index c1b7728cc..04380ff5a 100644 --- a/mediapipe/tasks/cc/text/custom_ops/sentencepiece/utils.h +++ b/mediapipe/tasks/cc/text/custom_ops/sentencepiece/utils.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/BUILD b/mediapipe/tasks/cc/text/language_detector/BUILD index 57b9c7b51..a7229cdfd 100644 --- a/mediapipe/tasks/cc/text/language_detector/BUILD +++ b/mediapipe/tasks/cc/text/language_detector/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/BUILD b/mediapipe/tasks/cc/text/language_detector/custom_ops/BUILD index 090f528ef..26eee18c4 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/BUILD +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/kmeans_embedding_lookup.cc b/mediapipe/tasks/cc/text/language_detector/custom_ops/kmeans_embedding_lookup.cc index 2c9b7a172..9df8d6d59 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/kmeans_embedding_lookup.cc +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/kmeans_embedding_lookup.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/kmeans_embedding_lookup.h b/mediapipe/tasks/cc/text/language_detector/custom_ops/kmeans_embedding_lookup.h index 31dd4abbd..030e0663c 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/kmeans_embedding_lookup.h +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/kmeans_embedding_lookup.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/ngram_hash.cc b/mediapipe/tasks/cc/text/language_detector/custom_ops/ngram_hash.cc index efe39a01f..b20d77b91 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/ngram_hash.cc +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/ngram_hash.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/ngram_hash.h b/mediapipe/tasks/cc/text/language_detector/custom_ops/ngram_hash.h index c32e91c62..53599bf29 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/ngram_hash.h +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/ngram_hash.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/ngram_hash_test.cc b/mediapipe/tasks/cc/text/language_detector/custom_ops/ngram_hash_test.cc index b799afc2f..d8b6ce3d4 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/ngram_hash_test.cc +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/ngram_hash_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/BUILD b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/BUILD index 9f2fe298a..894f2b9bb 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/BUILD +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/BUILD b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/BUILD index 86b659245..9a6f6f389 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/BUILD +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/murmur.cc b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/murmur.cc index 75dd161bf..4889ae665 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/murmur.cc +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/murmur.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ // Forked from a library written by Austin Appelby and Jyrki Alakuijala. // Original copyright message below. -// Copyright 2009 Google Inc. All Rights Reserved. +// Copyright 2009 Google Inc. // Author: aappleby@google.com (Austin Appleby) // jyrki@google.com (Jyrki Alakuijala) diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/murmur.h b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/murmur.h index abcb41a6b..cf6a44d50 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/murmur.h +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/murmur.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ // Forked from a library written by Austin Appelby and Jyrki Alakuijala. // Original copyright message below. -// Copyright 2009 Google Inc. All Rights Reserved. +// Copyright 2009 Google Inc. // Author: aappleby@google.com (Austin Appelby) // jyrki@google.com (Jyrki Alakuijala) // diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/murmur_test.cc b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/murmur_test.cc index 6658965bf..10ea0ffdf 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/murmur_test.cc +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/hash/murmur_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ // Forked from a test library written by Jyrki Alakuijala. // Original copyright message below. -// Copyright 2009 Google Inc. All Rights Reserved. +// Copyright 2009 Google Inc. // Author: jyrki@google.com (Jyrki Alakuijala) // // Tests for the fast hashing algorithm based on Austin Appleby's diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/ngram_hash_ops_utils.cc b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/ngram_hash_ops_utils.cc index f1ad71fc1..7f46917e0 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/ngram_hash_ops_utils.cc +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/ngram_hash_ops_utils.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/ngram_hash_ops_utils.h b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/ngram_hash_ops_utils.h index 9a80554c8..24daf5152 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/ngram_hash_ops_utils.h +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/ngram_hash_ops_utils.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/ngram_hash_ops_utils_test.cc b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/ngram_hash_ops_utils_test.cc index d22af1c95..b36391d20 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/ngram_hash_ops_utils_test.cc +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/ngram_hash_ops_utils_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/BUILD b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/BUILD index a71845305..b633d6812 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/BUILD +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/rune.c b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/rune.c index b74450f44..80ac027ca 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/rune.c +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/rune.c @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/runetype.c b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/runetype.c index 1dd8abdbd..949a652fd 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/runetype.c +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/runetype.c @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/runetypebody.h b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/runetypebody.h index 66d1dfc19..ba9146851 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/runetypebody.h +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/runetypebody.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/utf.h b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/utf.h index 24d9b9dbe..016ab1ebf 100644 --- a/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/utf.h +++ b/mediapipe/tasks/cc/text/language_detector/custom_ops/utils/utf/utf.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/language_detector.cc b/mediapipe/tasks/cc/text/language_detector/language_detector.cc index e3841211b..476427729 100644 --- a/mediapipe/tasks/cc/text/language_detector/language_detector.cc +++ b/mediapipe/tasks/cc/text/language_detector/language_detector.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/language_detector.h b/mediapipe/tasks/cc/text/language_detector/language_detector.h index bbe58dedf..95e2e9c97 100644 --- a/mediapipe/tasks/cc/text/language_detector/language_detector.h +++ b/mediapipe/tasks/cc/text/language_detector/language_detector.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/text/language_detector/language_detector_test.cc b/mediapipe/tasks/cc/text/language_detector/language_detector_test.cc index 2e9a58409..1ff12fda1 100644 --- a/mediapipe/tasks/cc/text/language_detector/language_detector_test.cc +++ b/mediapipe/tasks/cc/text/language_detector/language_detector_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/text_classifier/BUILD b/mediapipe/tasks/cc/text/text_classifier/BUILD index 4bf773270..4b244c00d 100644 --- a/mediapipe/tasks/cc/text/text_classifier/BUILD +++ b/mediapipe/tasks/cc/text/text_classifier/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/text/text_classifier/proto/BUILD b/mediapipe/tasks/cc/text/text_classifier/proto/BUILD index f2b544d87..fc298575c 100644 --- a/mediapipe/tasks/cc/text/text_classifier/proto/BUILD +++ b/mediapipe/tasks/cc/text/text_classifier/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/text/text_classifier/proto/text_classifier_graph_options.proto b/mediapipe/tasks/cc/text/text_classifier/proto/text_classifier_graph_options.proto index 41f87b519..7f693ee71 100644 --- a/mediapipe/tasks/cc/text/text_classifier/proto/text_classifier_graph_options.proto +++ b/mediapipe/tasks/cc/text/text_classifier/proto/text_classifier_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/text/text_classifier/text_classifier.cc b/mediapipe/tasks/cc/text/text_classifier/text_classifier.cc index d174fac47..0ffd57ce8 100644 --- a/mediapipe/tasks/cc/text/text_classifier/text_classifier.cc +++ b/mediapipe/tasks/cc/text/text_classifier/text_classifier.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/text_classifier/text_classifier.h b/mediapipe/tasks/cc/text/text_classifier/text_classifier.h index 03569c5a6..0fd9e56a8 100644 --- a/mediapipe/tasks/cc/text/text_classifier/text_classifier.h +++ b/mediapipe/tasks/cc/text/text_classifier/text_classifier.h @@ -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. diff --git a/mediapipe/tasks/cc/text/text_classifier/text_classifier_graph.cc b/mediapipe/tasks/cc/text/text_classifier/text_classifier_graph.cc index 3be92f309..bd032cdf2 100644 --- a/mediapipe/tasks/cc/text/text_classifier/text_classifier_graph.cc +++ b/mediapipe/tasks/cc/text/text_classifier/text_classifier_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/text_classifier/text_classifier_test.cc b/mediapipe/tasks/cc/text/text_classifier/text_classifier_test.cc index f800a0e52..e10bd53f3 100644 --- a/mediapipe/tasks/cc/text/text_classifier/text_classifier_test.cc +++ b/mediapipe/tasks/cc/text/text_classifier/text_classifier_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/text_classifier/text_classifier_test_utils.cc b/mediapipe/tasks/cc/text/text_classifier/text_classifier_test_utils.cc index d12370372..0e3d8b895 100644 --- a/mediapipe/tasks/cc/text/text_classifier/text_classifier_test_utils.cc +++ b/mediapipe/tasks/cc/text/text_classifier/text_classifier_test_utils.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/text_classifier/text_classifier_test_utils.h b/mediapipe/tasks/cc/text/text_classifier/text_classifier_test_utils.h index a427b561c..d6ebaf502 100644 --- a/mediapipe/tasks/cc/text/text_classifier/text_classifier_test_utils.h +++ b/mediapipe/tasks/cc/text/text_classifier/text_classifier_test_utils.h @@ -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. diff --git a/mediapipe/tasks/cc/text/text_embedder/BUILD b/mediapipe/tasks/cc/text/text_embedder/BUILD index addb971f1..e8deee241 100644 --- a/mediapipe/tasks/cc/text/text_embedder/BUILD +++ b/mediapipe/tasks/cc/text/text_embedder/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/text/text_embedder/proto/BUILD b/mediapipe/tasks/cc/text/text_embedder/proto/BUILD index 146483af1..0e42f40e8 100644 --- a/mediapipe/tasks/cc/text/text_embedder/proto/BUILD +++ b/mediapipe/tasks/cc/text/text_embedder/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/text/text_embedder/proto/text_embedder_graph_options.proto b/mediapipe/tasks/cc/text/text_embedder/proto/text_embedder_graph_options.proto index fc8e02858..f367d3531 100644 --- a/mediapipe/tasks/cc/text/text_embedder/proto/text_embedder_graph_options.proto +++ b/mediapipe/tasks/cc/text/text_embedder/proto/text_embedder_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/text/text_embedder/text_embedder.cc b/mediapipe/tasks/cc/text/text_embedder/text_embedder.cc index 375058d57..aa98c1e27 100644 --- a/mediapipe/tasks/cc/text/text_embedder/text_embedder.cc +++ b/mediapipe/tasks/cc/text/text_embedder/text_embedder.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/text_embedder/text_embedder.h b/mediapipe/tasks/cc/text/text_embedder/text_embedder.h index d729ff3c2..a7e9736ab 100644 --- a/mediapipe/tasks/cc/text/text_embedder/text_embedder.h +++ b/mediapipe/tasks/cc/text/text_embedder/text_embedder.h @@ -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. diff --git a/mediapipe/tasks/cc/text/text_embedder/text_embedder_graph.cc b/mediapipe/tasks/cc/text/text_embedder/text_embedder_graph.cc index 518695138..9c812e9fd 100644 --- a/mediapipe/tasks/cc/text/text_embedder/text_embedder_graph.cc +++ b/mediapipe/tasks/cc/text/text_embedder/text_embedder_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/text_embedder/text_embedder_test.cc b/mediapipe/tasks/cc/text/text_embedder/text_embedder_test.cc index 474f0ca35..29a00a2ac 100644 --- a/mediapipe/tasks/cc/text/text_embedder/text_embedder_test.cc +++ b/mediapipe/tasks/cc/text/text_embedder/text_embedder_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/BUILD b/mediapipe/tasks/cc/text/tokenizers/BUILD index 92fac8eaa..a55f91316 100644 --- a/mediapipe/tasks/cc/text/tokenizers/BUILD +++ b/mediapipe/tasks/cc/text/tokenizers/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/bert_tokenizer.cc b/mediapipe/tasks/cc/text/tokenizers/bert_tokenizer.cc index 3348abff5..caec04ded 100644 --- a/mediapipe/tasks/cc/text/tokenizers/bert_tokenizer.cc +++ b/mediapipe/tasks/cc/text/tokenizers/bert_tokenizer.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/bert_tokenizer.h b/mediapipe/tasks/cc/text/tokenizers/bert_tokenizer.h index d655fcadd..67149b788 100644 --- a/mediapipe/tasks/cc/text/tokenizers/bert_tokenizer.h +++ b/mediapipe/tasks/cc/text/tokenizers/bert_tokenizer.h @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/bert_tokenizer_test.cc b/mediapipe/tasks/cc/text/tokenizers/bert_tokenizer_test.cc index 8a21136cc..8a06c5806 100644 --- a/mediapipe/tasks/cc/text/tokenizers/bert_tokenizer_test.cc +++ b/mediapipe/tasks/cc/text/tokenizers/bert_tokenizer_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/regex_tokenizer.cc b/mediapipe/tasks/cc/text/tokenizers/regex_tokenizer.cc index 6a1dc2506..8fe75d8b5 100644 --- a/mediapipe/tasks/cc/text/tokenizers/regex_tokenizer.cc +++ b/mediapipe/tasks/cc/text/tokenizers/regex_tokenizer.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/regex_tokenizer.h b/mediapipe/tasks/cc/text/tokenizers/regex_tokenizer.h index c84dd33d2..0617167af 100644 --- a/mediapipe/tasks/cc/text/tokenizers/regex_tokenizer.h +++ b/mediapipe/tasks/cc/text/tokenizers/regex_tokenizer.h @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/regex_tokenizer_test.cc b/mediapipe/tasks/cc/text/tokenizers/regex_tokenizer_test.cc index 150304d71..cc13f256b 100644 --- a/mediapipe/tasks/cc/text/tokenizers/regex_tokenizer_test.cc +++ b/mediapipe/tasks/cc/text/tokenizers/regex_tokenizer_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/sentencepiece_tokenizer.h b/mediapipe/tasks/cc/text/tokenizers/sentencepiece_tokenizer.h index 9798f7bde..e1aab0ec5 100644 --- a/mediapipe/tasks/cc/text/tokenizers/sentencepiece_tokenizer.h +++ b/mediapipe/tasks/cc/text/tokenizers/sentencepiece_tokenizer.h @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/sentencepiece_tokenizer_test.cc b/mediapipe/tasks/cc/text/tokenizers/sentencepiece_tokenizer_test.cc index 88afabe1e..eb9032cc0 100644 --- a/mediapipe/tasks/cc/text/tokenizers/sentencepiece_tokenizer_test.cc +++ b/mediapipe/tasks/cc/text/tokenizers/sentencepiece_tokenizer_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/tokenizer.h b/mediapipe/tasks/cc/text/tokenizers/tokenizer.h index ae984808e..d5d7d8894 100644 --- a/mediapipe/tasks/cc/text/tokenizers/tokenizer.h +++ b/mediapipe/tasks/cc/text/tokenizers/tokenizer.h @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.cc b/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.cc index 839c0818e..1c2faa677 100644 --- a/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.cc +++ b/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.h b/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.h index c6bea1418..039c6dd5e 100644 --- a/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.h +++ b/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.h @@ -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. diff --git a/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils_test.cc b/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils_test.cc index 337d5ec7d..7c2344e3c 100644 --- a/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils_test.cc +++ b/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/utils/BUILD b/mediapipe/tasks/cc/text/utils/BUILD index cd8c7512c..d13d6b304 100644 --- a/mediapipe/tasks/cc/text/utils/BUILD +++ b/mediapipe/tasks/cc/text/utils/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/text/utils/text_model_utils.cc b/mediapipe/tasks/cc/text/utils/text_model_utils.cc index 7cd03d848..1100e83f7 100644 --- a/mediapipe/tasks/cc/text/utils/text_model_utils.cc +++ b/mediapipe/tasks/cc/text/utils/text_model_utils.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/utils/text_model_utils.h b/mediapipe/tasks/cc/text/utils/text_model_utils.h index da8783d33..730616787 100644 --- a/mediapipe/tasks/cc/text/utils/text_model_utils.h +++ b/mediapipe/tasks/cc/text/utils/text_model_utils.h @@ -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. diff --git a/mediapipe/tasks/cc/text/utils/text_model_utils_test.cc b/mediapipe/tasks/cc/text/utils/text_model_utils_test.cc index 2ec5686f7..a0d9cf0c9 100644 --- a/mediapipe/tasks/cc/text/utils/text_model_utils_test.cc +++ b/mediapipe/tasks/cc/text/utils/text_model_utils_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/utils/vocab_utils.cc b/mediapipe/tasks/cc/text/utils/vocab_utils.cc index a006da6d1..66b0587d6 100644 --- a/mediapipe/tasks/cc/text/utils/vocab_utils.cc +++ b/mediapipe/tasks/cc/text/utils/vocab_utils.cc @@ -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. diff --git a/mediapipe/tasks/cc/text/utils/vocab_utils.h b/mediapipe/tasks/cc/text/utils/vocab_utils.h index a2da349dc..80c448e86 100644 --- a/mediapipe/tasks/cc/text/utils/vocab_utils.h +++ b/mediapipe/tasks/cc/text/utils/vocab_utils.h @@ -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. diff --git a/mediapipe/tasks/cc/text/utils/vocab_utils_test.cc b/mediapipe/tasks/cc/text/utils/vocab_utils_test.cc index e4db9628d..a255458e6 100644 --- a/mediapipe/tasks/cc/text/utils/vocab_utils_test.cc +++ b/mediapipe/tasks/cc/text/utils/vocab_utils_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/core/BUILD b/mediapipe/tasks/cc/vision/core/BUILD index 0815b5b2b..59fb45622 100644 --- a/mediapipe/tasks/cc/vision/core/BUILD +++ b/mediapipe/tasks/cc/vision/core/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/core/base_vision_task_api.h b/mediapipe/tasks/cc/vision/core/base_vision_task_api.h index 8e6105e18..e65e67bdc 100644 --- a/mediapipe/tasks/cc/vision/core/base_vision_task_api.h +++ b/mediapipe/tasks/cc/vision/core/base_vision_task_api.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/core/image_processing_options.h b/mediapipe/tasks/cc/vision/core/image_processing_options.h index e2647be71..03610e983 100644 --- a/mediapipe/tasks/cc/vision/core/image_processing_options.h +++ b/mediapipe/tasks/cc/vision/core/image_processing_options.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/core/running_mode.h b/mediapipe/tasks/cc/vision/core/running_mode.h index 330c335f2..068045142 100644 --- a/mediapipe/tasks/cc/vision/core/running_mode.h +++ b/mediapipe/tasks/cc/vision/core/running_mode.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/core/vision_task_api_factory.h b/mediapipe/tasks/cc/vision/core/vision_task_api_factory.h index 8872a2a04..c68e432c3 100644 --- a/mediapipe/tasks/cc/vision/core/vision_task_api_factory.h +++ b/mediapipe/tasks/cc/vision/core/vision_task_api_factory.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/face_detector/BUILD b/mediapipe/tasks/cc/vision/face_detector/BUILD index 2cae8b79b..8fd171dab 100644 --- a/mediapipe/tasks/cc/vision/face_detector/BUILD +++ b/mediapipe/tasks/cc/vision/face_detector/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/vision/face_detector/face_detector.cc b/mediapipe/tasks/cc/vision/face_detector/face_detector.cc index 80e114bf8..a21b6edcf 100644 --- a/mediapipe/tasks/cc/vision/face_detector/face_detector.cc +++ b/mediapipe/tasks/cc/vision/face_detector/face_detector.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_detector/face_detector.h b/mediapipe/tasks/cc/vision/face_detector/face_detector.h index ae485819d..545b7d6bc 100644 --- a/mediapipe/tasks/cc/vision/face_detector/face_detector.h +++ b/mediapipe/tasks/cc/vision/face_detector/face_detector.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc b/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc index bf62d2988..545bdb275 100644 --- a/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_detector/face_detector_graph_test.cc b/mediapipe/tasks/cc/vision/face_detector/face_detector_graph_test.cc index 7be08ec2d..72eb4cb56 100644 --- a/mediapipe/tasks/cc/vision/face_detector/face_detector_graph_test.cc +++ b/mediapipe/tasks/cc/vision/face_detector/face_detector_graph_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_detector/face_detector_test.cc b/mediapipe/tasks/cc/vision/face_detector/face_detector_test.cc index b2db21e7e..97c64ac16 100644 --- a/mediapipe/tasks/cc/vision/face_detector/face_detector_test.cc +++ b/mediapipe/tasks/cc/vision/face_detector/face_detector_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_detector/proto/BUILD b/mediapipe/tasks/cc/vision/face_detector/proto/BUILD index ca9a6f8c4..12b26abdf 100644 --- a/mediapipe/tasks/cc/vision/face_detector/proto/BUILD +++ b/mediapipe/tasks/cc/vision/face_detector/proto/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/vision/face_detector/proto/face_detector_graph_options.proto b/mediapipe/tasks/cc/vision/face_detector/proto/face_detector_graph_options.proto index 3d0f1288d..0b082c650 100644 --- a/mediapipe/tasks/cc/vision/face_detector/proto/face_detector_graph_options.proto +++ b/mediapipe/tasks/cc/vision/face_detector/proto/face_detector_graph_options.proto @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_geometry/face_geometry_from_landmarks_graph.cc b/mediapipe/tasks/cc/vision/face_geometry/face_geometry_from_landmarks_graph.cc index 8c69a31fd..bf4006a94 100644 --- a/mediapipe/tasks/cc/vision/face_geometry/face_geometry_from_landmarks_graph.cc +++ b/mediapipe/tasks/cc/vision/face_geometry/face_geometry_from_landmarks_graph.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_geometry/face_geometry_from_landmarks_graph_test.cc b/mediapipe/tasks/cc/vision/face_geometry/face_geometry_from_landmarks_graph_test.cc index 74baff5d8..933ad75c7 100644 --- a/mediapipe/tasks/cc/vision/face_geometry/face_geometry_from_landmarks_graph_test.cc +++ b/mediapipe/tasks/cc/vision/face_geometry/face_geometry_from_landmarks_graph_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/BUILD b/mediapipe/tasks/cc/vision/face_landmarker/BUILD index 1004069bd..1287ef223 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/BUILD +++ b/mediapipe/tasks/cc/vision/face_landmarker/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_blendshapes_graph.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_blendshapes_graph.cc index e1c743a9b..68b87bb6b 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_blendshapes_graph.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_blendshapes_graph.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_blendshapes_graph_test.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_blendshapes_graph_test.cc index 5c342a8e9..e83f16da5 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_blendshapes_graph_test.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_blendshapes_graph_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker.cc index b40ea3324..88b0b5eb1 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker.h b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker.h index 2c93fcba5..0b23fffd4 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker.h +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_graph.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_graph.cc index c681cd2de..0515e78bd 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_graph.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_graph.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_graph_test.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_graph_test.cc index 063d6835e..a6fade602 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_graph_test.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_graph_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_result.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_result.cc index 53a171ed5..090781cc2 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_result.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_result.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_result.h b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_result.h index bc097d6c3..f7f06cf03 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_result.h +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_result.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_result_test.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_result_test.cc index 4123a81f3..42a08e431 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_result_test.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_result_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_test.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_test.cc index 97af42da7..41b5ede6a 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_test.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph.cc index 7ce0fcaa2..8f518217f 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph_test.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph_test.cc index a415125d9..c498934f2 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph_test.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/proto/BUILD b/mediapipe/tasks/cc/vision/face_landmarker/proto/BUILD index d3e236619..1931921e0 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/proto/BUILD +++ b/mediapipe/tasks/cc/vision/face_landmarker/proto/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/proto/face_blendshapes_graph_options.proto b/mediapipe/tasks/cc/vision/face_landmarker/proto/face_blendshapes_graph_options.proto index 36e712ad8..c535f0e2e 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/proto/face_blendshapes_graph_options.proto +++ b/mediapipe/tasks/cc/vision/face_landmarker/proto/face_blendshapes_graph_options.proto @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarker_graph_options.proto b/mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarker_graph_options.proto index dc8654608..219437166 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarker_graph_options.proto +++ b/mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarker_graph_options.proto @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarks_detector_graph_options.proto b/mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarks_detector_graph_options.proto index c2fa49607..23a541a31 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarks_detector_graph_options.proto +++ b/mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarks_detector_graph_options.proto @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/proto/tensors_to_face_landmarks_graph_options.proto b/mediapipe/tasks/cc/vision/face_landmarker/proto/tensors_to_face_landmarks_graph_options.proto index 22414b361..d9772ea1f 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/proto/tensors_to_face_landmarks_graph_options.proto +++ b/mediapipe/tasks/cc/vision/face_landmarker/proto/tensors_to_face_landmarks_graph_options.proto @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_landmarker/tensors_to_face_landmarks_graph.cc b/mediapipe/tasks/cc/vision/face_landmarker/tensors_to_face_landmarks_graph.cc index 4073c9e18..a765f4424 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/tensors_to_face_landmarks_graph.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/tensors_to_face_landmarks_graph.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_stylizer/BUILD b/mediapipe/tasks/cc/vision/face_stylizer/BUILD index 27b2f482d..e7e6724cc 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/BUILD +++ b/mediapipe/tasks/cc/vision/face_stylizer/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/vision/face_stylizer/calculators/BUILD b/mediapipe/tasks/cc/vision/face_stylizer/calculators/BUILD index 4e070b43e..74b174015 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/calculators/BUILD +++ b/mediapipe/tasks/cc/vision/face_stylizer/calculators/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/vision/face_stylizer/calculators/strip_rotation_calculator.cc b/mediapipe/tasks/cc/vision/face_stylizer/calculators/strip_rotation_calculator.cc index c290f2725..11ae112c6 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/calculators/strip_rotation_calculator.cc +++ b/mediapipe/tasks/cc/vision/face_stylizer/calculators/strip_rotation_calculator.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer.cc b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer.cc index 7ae8d1b26..975676fba 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer.cc +++ b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer.h b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer.h index 36bb11bd7..df9970bf9 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer.h +++ b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc index 27b8dacc1..89394c53a 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc +++ b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/face_stylizer/proto/BUILD b/mediapipe/tasks/cc/vision/face_stylizer/proto/BUILD index 1800591d7..9773b0924 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/proto/BUILD +++ b/mediapipe/tasks/cc/vision/face_stylizer/proto/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/vision/face_stylizer/proto/face_stylizer_graph_options.proto b/mediapipe/tasks/cc/vision/face_stylizer/proto/face_stylizer_graph_options.proto index 6357b0655..68abee43c 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/proto/face_stylizer_graph_options.proto +++ b/mediapipe/tasks/cc/vision/face_stylizer/proto/face_stylizer_graph_options.proto @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/BUILD b/mediapipe/tasks/cc/vision/gesture_recognizer/BUILD index 7ffae6ff2..fe925db57 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/BUILD +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/BUILD b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/BUILD index 8c2c2e593..b5c7f2bc7 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/BUILD +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/combined_prediction_calculator.cc b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/combined_prediction_calculator.cc index cb95091d4..d06c610b8 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/combined_prediction_calculator.cc +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/combined_prediction_calculator.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/combined_prediction_calculator.proto b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/combined_prediction_calculator.proto index 730e7dd78..1afe3d8be 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/combined_prediction_calculator.proto +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/combined_prediction_calculator.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/combined_prediction_calculator_test.cc b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/combined_prediction_calculator_test.cc index 509fac5f0..0c63c9e69 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/combined_prediction_calculator_test.cc +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/combined_prediction_calculator_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/handedness_to_matrix_calculator.cc b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/handedness_to_matrix_calculator.cc index b6c973a1b..0d0419d09 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/handedness_to_matrix_calculator.cc +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/handedness_to_matrix_calculator.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/handedness_to_matrix_calculator_test.cc b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/handedness_to_matrix_calculator_test.cc index 30e5a958a..70012aa5b 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/handedness_to_matrix_calculator_test.cc +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/handedness_to_matrix_calculator_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/landmarks_to_matrix_calculator.cc b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/landmarks_to_matrix_calculator.cc index 088f97c29..624d8a822 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/landmarks_to_matrix_calculator.cc +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/landmarks_to_matrix_calculator.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/landmarks_to_matrix_calculator.proto b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/landmarks_to_matrix_calculator.proto index 10b034447..6f1472cdd 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/landmarks_to_matrix_calculator.proto +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/landmarks_to_matrix_calculator.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/landmarks_to_matrix_calculator_test.cc b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/landmarks_to_matrix_calculator_test.cc index 70234a32d..064dc479f 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/landmarks_to_matrix_calculator_test.cc +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/calculators/landmarks_to_matrix_calculator_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer.cc b/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer.cc index a9f8fa8a1..f04d7d71a 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer.cc +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer.h b/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer.h index 392aa586f..b752840da 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer.h +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer_graph.cc b/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer_graph.cc index 55db07cb8..0f4c88f5c 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer_graph.cc +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer_result.h b/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer_result.h index 914217801..9c7a8c714 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer_result.h +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/gesture_recognizer_result.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/hand_gesture_recognizer_graph.cc b/mediapipe/tasks/cc/vision/gesture_recognizer/hand_gesture_recognizer_graph.cc index 527363d1f..097318be6 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/hand_gesture_recognizer_graph.cc +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/hand_gesture_recognizer_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/handedness_util.cc b/mediapipe/tasks/cc/vision/gesture_recognizer/handedness_util.cc index 60ccae92c..52c679672 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/handedness_util.cc +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/handedness_util.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/handedness_util.h b/mediapipe/tasks/cc/vision/gesture_recognizer/handedness_util.h index ae4137d0f..9abb6e595 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/handedness_util.h +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/handedness_util.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/handedness_util_test.cc b/mediapipe/tasks/cc/vision/gesture_recognizer/handedness_util_test.cc index 40a201ae8..01e214456 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/handedness_util_test.cc +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/handedness_util_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/proto/BUILD b/mediapipe/tasks/cc/vision/gesture_recognizer/proto/BUILD index 0db47da7a..8e4f28060 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/proto/BUILD +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_classifier_graph_options.proto b/mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_classifier_graph_options.proto index edbabc018..51d3203f2 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_classifier_graph_options.proto +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_classifier_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_embedder_graph_options.proto b/mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_embedder_graph_options.proto index df909a6db..dc6593727 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_embedder_graph_options.proto +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_embedder_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_recognizer_graph_options.proto b/mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_recognizer_graph_options.proto index fef22c07c..ef66a2d3b 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_recognizer_graph_options.proto +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_recognizer_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/gesture_recognizer/proto/hand_gesture_recognizer_graph_options.proto b/mediapipe/tasks/cc/vision/gesture_recognizer/proto/hand_gesture_recognizer_graph_options.proto index ae85509da..ceff67392 100644 --- a/mediapipe/tasks/cc/vision/gesture_recognizer/proto/hand_gesture_recognizer_graph_options.proto +++ b/mediapipe/tasks/cc/vision/gesture_recognizer/proto/hand_gesture_recognizer_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_detector/BUILD b/mediapipe/tasks/cc/vision/hand_detector/BUILD index 55162d09b..7fc943d87 100644 --- a/mediapipe/tasks/cc/vision/hand_detector/BUILD +++ b/mediapipe/tasks/cc/vision/hand_detector/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_detector/hand_detector_graph.cc b/mediapipe/tasks/cc/vision/hand_detector/hand_detector_graph.cc index 923eab1ca..1b964c5d8 100644 --- a/mediapipe/tasks/cc/vision/hand_detector/hand_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/hand_detector/hand_detector_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_detector/hand_detector_graph_test.cc b/mediapipe/tasks/cc/vision/hand_detector/hand_detector_graph_test.cc index f4e5f8c7d..2e47f693e 100644 --- a/mediapipe/tasks/cc/vision/hand_detector/hand_detector_graph_test.cc +++ b/mediapipe/tasks/cc/vision/hand_detector/hand_detector_graph_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_detector/proto/BUILD b/mediapipe/tasks/cc/vision/hand_detector/proto/BUILD index 77f3b2649..c1453f420 100644 --- a/mediapipe/tasks/cc/vision/hand_detector/proto/BUILD +++ b/mediapipe/tasks/cc/vision/hand_detector/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_detector/proto/hand_detector_graph_options.proto b/mediapipe/tasks/cc/vision/hand_detector/proto/hand_detector_graph_options.proto index bede70da5..670d1e41f 100644 --- a/mediapipe/tasks/cc/vision/hand_detector/proto/hand_detector_graph_options.proto +++ b/mediapipe/tasks/cc/vision/hand_detector/proto/hand_detector_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_detector/proto/hand_detector_result.proto b/mediapipe/tasks/cc/vision/hand_detector/proto/hand_detector_result.proto index 00c179ca9..170ed7c39 100644 --- a/mediapipe/tasks/cc/vision/hand_detector/proto/hand_detector_result.proto +++ b/mediapipe/tasks/cc/vision/hand_detector/proto/hand_detector_result.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/BUILD b/mediapipe/tasks/cc/vision/hand_landmarker/BUILD index 7a83816b8..2eecb61bf 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/BUILD +++ b/mediapipe/tasks/cc/vision/hand_landmarker/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/calculators/BUILD b/mediapipe/tasks/cc/vision/hand_landmarker/calculators/BUILD index 73d3f38eb..a30cc5558 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/calculators/BUILD +++ b/mediapipe/tasks/cc/vision/hand_landmarker/calculators/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator.cc b/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator.cc index 011bce2b9..060e7a2dc 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator.proto b/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator.proto index e7229b4a2..b37478860 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator.proto +++ b/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator_test.cc b/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator_test.cc index c22b1a7e6..057d72e10 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator_test.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_association_calculator_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_landmarks_deduplication_calculator.cc b/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_landmarks_deduplication_calculator.cc index d875de98f..ced757546 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_landmarks_deduplication_calculator.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_landmarks_deduplication_calculator.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_landmarks_deduplication_calculator.h b/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_landmarks_deduplication_calculator.h index d7b435487..782565ee0 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_landmarks_deduplication_calculator.h +++ b/mediapipe/tasks/cc/vision/hand_landmarker/calculators/hand_landmarks_deduplication_calculator.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmark.h b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmark.h index c8dbc9254..3f70e7ee7 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmark.h +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmark.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker.cc b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker.cc index 4eec37f20..9190f4052 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker.h b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker.h index 7a43d20d7..726780ff2 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker.h +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph.cc b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph.cc index b37141005..61bccb2a8 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph_test.cc b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph_test.cc index fc73e7787..673d0136b 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph_test.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_graph_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_result.cc b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_result.cc index 9d2ae2be8..9ec7f838d 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_result.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_result.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_result.h b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_result.h index 1bca8e66a..caa3c1790 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_result.h +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_result.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_result_test.cc b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_result_test.cc index 109749b01..d2a6b0b32 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_result_test.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_result_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_test.cc b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_test.cc index bb7d1a905..899e6560d 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_test.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarker_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarks_detector_graph.cc b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarks_detector_graph.cc index 9409303ba..c27322b95 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarks_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarks_detector_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarks_detector_graph_test.cc b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarks_detector_graph_test.cc index bbf3a7cde..62e466f66 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarks_detector_graph_test.cc +++ b/mediapipe/tasks/cc/vision/hand_landmarker/hand_landmarks_detector_graph_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/proto/BUILD b/mediapipe/tasks/cc/vision/hand_landmarker/proto/BUILD index 945b12f3e..d13f0afd5 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/proto/BUILD +++ b/mediapipe/tasks/cc/vision/hand_landmarker/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarker_graph_options.proto b/mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarker_graph_options.proto index d0edf99c0..1ce2305f3 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarker_graph_options.proto +++ b/mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarker_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarks_detector_graph_options.proto b/mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarks_detector_graph_options.proto index a2d520963..04f62c39c 100644 --- a/mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarks_detector_graph_options.proto +++ b/mediapipe/tasks/cc/vision/hand_landmarker/proto/hand_landmarks_detector_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_classifier/BUILD b/mediapipe/tasks/cc/vision/image_classifier/BUILD index 514e601ef..86ac7680c 100644 --- a/mediapipe/tasks/cc/vision/image_classifier/BUILD +++ b/mediapipe/tasks/cc/vision/image_classifier/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_classifier/image_classifier.cc b/mediapipe/tasks/cc/vision/image_classifier/image_classifier.cc index 7dd410e83..5b885045b 100644 --- a/mediapipe/tasks/cc/vision/image_classifier/image_classifier.cc +++ b/mediapipe/tasks/cc/vision/image_classifier/image_classifier.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_classifier/image_classifier.h b/mediapipe/tasks/cc/vision/image_classifier/image_classifier.h index 9b0c376ae..96050cbd0 100644 --- a/mediapipe/tasks/cc/vision/image_classifier/image_classifier.h +++ b/mediapipe/tasks/cc/vision/image_classifier/image_classifier.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_classifier/image_classifier_graph.cc b/mediapipe/tasks/cc/vision/image_classifier/image_classifier_graph.cc index 0adcf842d..5e4363588 100644 --- a/mediapipe/tasks/cc/vision/image_classifier/image_classifier_graph.cc +++ b/mediapipe/tasks/cc/vision/image_classifier/image_classifier_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_classifier/image_classifier_test.cc b/mediapipe/tasks/cc/vision/image_classifier/image_classifier_test.cc index e8812d9fd..88eeb9e4d 100644 --- a/mediapipe/tasks/cc/vision/image_classifier/image_classifier_test.cc +++ b/mediapipe/tasks/cc/vision/image_classifier/image_classifier_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_classifier/proto/BUILD b/mediapipe/tasks/cc/vision/image_classifier/proto/BUILD index 29638bebd..e58efe2fd 100644 --- a/mediapipe/tasks/cc/vision/image_classifier/proto/BUILD +++ b/mediapipe/tasks/cc/vision/image_classifier/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_classifier/proto/image_classifier_graph_options.proto b/mediapipe/tasks/cc/vision/image_classifier/proto/image_classifier_graph_options.proto index 24b126a35..7a84040fd 100644 --- a/mediapipe/tasks/cc/vision/image_classifier/proto/image_classifier_graph_options.proto +++ b/mediapipe/tasks/cc/vision/image_classifier/proto/image_classifier_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_embedder/BUILD b/mediapipe/tasks/cc/vision/image_embedder/BUILD index d729eaf1a..7d22302a1 100644 --- a/mediapipe/tasks/cc/vision/image_embedder/BUILD +++ b/mediapipe/tasks/cc/vision/image_embedder/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_embedder/image_embedder.cc b/mediapipe/tasks/cc/vision/image_embedder/image_embedder.cc index 1425e97cc..53d7c7c9d 100644 --- a/mediapipe/tasks/cc/vision/image_embedder/image_embedder.cc +++ b/mediapipe/tasks/cc/vision/image_embedder/image_embedder.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_embedder/image_embedder.h b/mediapipe/tasks/cc/vision/image_embedder/image_embedder.h index 9320cbc35..586b8cdca 100644 --- a/mediapipe/tasks/cc/vision/image_embedder/image_embedder.h +++ b/mediapipe/tasks/cc/vision/image_embedder/image_embedder.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_embedder/image_embedder_graph.cc b/mediapipe/tasks/cc/vision/image_embedder/image_embedder_graph.cc index 95c4ff379..61d546c7e 100644 --- a/mediapipe/tasks/cc/vision/image_embedder/image_embedder_graph.cc +++ b/mediapipe/tasks/cc/vision/image_embedder/image_embedder_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_embedder/image_embedder_test.cc b/mediapipe/tasks/cc/vision/image_embedder/image_embedder_test.cc index 7a0e9e9dc..6d994789d 100644 --- a/mediapipe/tasks/cc/vision/image_embedder/image_embedder_test.cc +++ b/mediapipe/tasks/cc/vision/image_embedder/image_embedder_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_embedder/proto/BUILD b/mediapipe/tasks/cc/vision/image_embedder/proto/BUILD index ecf8b0242..297675019 100644 --- a/mediapipe/tasks/cc/vision/image_embedder/proto/BUILD +++ b/mediapipe/tasks/cc/vision/image_embedder/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_embedder/proto/image_embedder_graph_options.proto b/mediapipe/tasks/cc/vision/image_embedder/proto/image_embedder_graph_options.proto index 24ee866f2..5441aac41 100644 --- a/mediapipe/tasks/cc/vision/image_embedder/proto/image_embedder_graph_options.proto +++ b/mediapipe/tasks/cc/vision/image_embedder/proto/image_embedder_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/BUILD b/mediapipe/tasks/cc/vision/image_segmenter/BUILD index ee1cd3693..183b1bb86 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/BUILD +++ b/mediapipe/tasks/cc/vision/image_segmenter/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/calculators/BUILD b/mediapipe/tasks/cc/vision/image_segmenter/calculators/BUILD index c621016dc..1860d97dc 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/calculators/BUILD +++ b/mediapipe/tasks/cc/vision/image_segmenter/calculators/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.cc b/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.cc index e6d9ec8af..c2d1520dd 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.proto b/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.proto index dbaf34db0..b728f5046 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.proto +++ b/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator_test.cc b/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator_test.cc index d6a2f3fd9..7b8fb9c9e 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator_test.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.cc b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.cc index 33c868e05..a67843258 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.h b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.h index 352d6b273..0546cef3a 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.h +++ b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_graph.cc b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_graph.cc index 840e7933a..a52d3fa9a 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_graph.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_result.h b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_result.h index f14ee7a90..1e7968ebd 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_result.h +++ b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_result.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_test.cc b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_test.cc index 21f73e103..339ec1424 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_test.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/proto/BUILD b/mediapipe/tasks/cc/vision/image_segmenter/proto/BUILD index 9523dd679..54dc399d3 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/proto/BUILD +++ b/mediapipe/tasks/cc/vision/image_segmenter/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/proto/image_segmenter_graph_options.proto b/mediapipe/tasks/cc/vision/image_segmenter/proto/image_segmenter_graph_options.proto index 5c7d2ec71..8866b3951 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/proto/image_segmenter_graph_options.proto +++ b/mediapipe/tasks/cc/vision/image_segmenter/proto/image_segmenter_graph_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/image_segmenter/proto/segmenter_options.proto b/mediapipe/tasks/cc/vision/image_segmenter/proto/segmenter_options.proto index b1ec529d0..86b9b39ad 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/proto/segmenter_options.proto +++ b/mediapipe/tasks/cc/vision/image_segmenter/proto/segmenter_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/interactive_segmenter/BUILD b/mediapipe/tasks/cc/vision/interactive_segmenter/BUILD index 8552383ac..0a91b97e6 100644 --- a/mediapipe/tasks/cc/vision/interactive_segmenter/BUILD +++ b/mediapipe/tasks/cc/vision/interactive_segmenter/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc index b17b3b0d3..af2a3f50c 100644 --- a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc +++ b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.h b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.h index 350777f31..ad4a238df 100644 --- a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.h +++ b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_graph.cc b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_graph.cc index b907e2156..a765997d8 100644 --- a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_graph.cc +++ b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_graph.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_test.cc b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_test.cc index c761678d0..443247aea 100644 --- a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_test.cc +++ b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/object_detector/BUILD b/mediapipe/tasks/cc/vision/object_detector/BUILD index 0238449c7..855fc29f5 100644 --- a/mediapipe/tasks/cc/vision/object_detector/BUILD +++ b/mediapipe/tasks/cc/vision/object_detector/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/object_detector/object_detector.cc b/mediapipe/tasks/cc/vision/object_detector/object_detector.cc index fe0651e1e..01fd3eb7b 100644 --- a/mediapipe/tasks/cc/vision/object_detector/object_detector.cc +++ b/mediapipe/tasks/cc/vision/object_detector/object_detector.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/object_detector/object_detector.h b/mediapipe/tasks/cc/vision/object_detector/object_detector.h index 6113ed105..bddbef4bb 100644 --- a/mediapipe/tasks/cc/vision/object_detector/object_detector.h +++ b/mediapipe/tasks/cc/vision/object_detector/object_detector.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/object_detector/object_detector_graph.cc b/mediapipe/tasks/cc/vision/object_detector/object_detector_graph.cc index e0eb32fdd..783ed742a 100644 --- a/mediapipe/tasks/cc/vision/object_detector/object_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/object_detector/object_detector_graph.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/object_detector/object_detector_test.cc b/mediapipe/tasks/cc/vision/object_detector/object_detector_test.cc index c992cf67e..a4fed0f9e 100644 --- a/mediapipe/tasks/cc/vision/object_detector/object_detector_test.cc +++ b/mediapipe/tasks/cc/vision/object_detector/object_detector_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/object_detector/proto/BUILD b/mediapipe/tasks/cc/vision/object_detector/proto/BUILD index edcaff52f..863d69df0 100644 --- a/mediapipe/tasks/cc/vision/object_detector/proto/BUILD +++ b/mediapipe/tasks/cc/vision/object_detector/proto/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/object_detector/proto/object_detector_options.proto b/mediapipe/tasks/cc/vision/object_detector/proto/object_detector_options.proto index 3f6932f8f..471d8d527 100644 --- a/mediapipe/tasks/cc/vision/object_detector/proto/object_detector_options.proto +++ b/mediapipe/tasks/cc/vision/object_detector/proto/object_detector_options.proto @@ -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. diff --git a/mediapipe/tasks/cc/vision/pose_detector/BUILD b/mediapipe/tasks/cc/vision/pose_detector/BUILD index 1fc4b5ba2..4f9bc5944 100644 --- a/mediapipe/tasks/cc/vision/pose_detector/BUILD +++ b/mediapipe/tasks/cc/vision/pose_detector/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/vision/pose_detector/pose_detector_graph.cc b/mediapipe/tasks/cc/vision/pose_detector/pose_detector_graph.cc index 32c125ce2..f1554f8df 100644 --- a/mediapipe/tasks/cc/vision/pose_detector/pose_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/pose_detector/pose_detector_graph.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_detector/pose_detector_graph_test.cc b/mediapipe/tasks/cc/vision/pose_detector/pose_detector_graph_test.cc index 800c05846..711131107 100644 --- a/mediapipe/tasks/cc/vision/pose_detector/pose_detector_graph_test.cc +++ b/mediapipe/tasks/cc/vision/pose_detector/pose_detector_graph_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_detector/proto/BUILD b/mediapipe/tasks/cc/vision/pose_detector/proto/BUILD index 287ed0183..53e7d5a55 100644 --- a/mediapipe/tasks/cc/vision/pose_detector/proto/BUILD +++ b/mediapipe/tasks/cc/vision/pose_detector/proto/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/vision/pose_detector/proto/pose_detector_graph_options.proto b/mediapipe/tasks/cc/vision/pose_detector/proto/pose_detector_graph_options.proto index 693f95262..531bcc7e9 100644 --- a/mediapipe/tasks/cc/vision/pose_detector/proto/pose_detector_graph_options.proto +++ b/mediapipe/tasks/cc/vision/pose_detector/proto/pose_detector_graph_options.proto @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/BUILD b/mediapipe/tasks/cc/vision/pose_landmarker/BUILD index 19f546257..f97857ddc 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/BUILD +++ b/mediapipe/tasks/cc/vision/pose_landmarker/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.cc index 01c86c122..f421c7376 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.h b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.h index 058ab0b1e..314356aa0 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.h +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph.cc index 456a6efd1..826de5ec4 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph_test.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph_test.cc index 6a4cc93b6..92bc80c5a 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph_test.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.cc index 6222bbd68..77f374d1e 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.h b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.h index 07adb87f5..f45994837 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.h +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.h @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result_test.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result_test.cc index 10e0d61a3..14916215c 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result_test.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_test.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_test.cc index 87bc97274..afc58b1dc 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_test.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarks_detector_graph.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarks_detector_graph.cc index f8488db02..e8397192b 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarks_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarks_detector_graph.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarks_detector_graph_test.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarks_detector_graph_test.cc index d5108decf..08842b211 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarks_detector_graph_test.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarks_detector_graph_test.cc @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/proto/BUILD b/mediapipe/tasks/cc/vision/pose_landmarker/proto/BUILD index a2ad7b0b1..869a1ea60 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/proto/BUILD +++ b/mediapipe/tasks/cc/vision/pose_landmarker/proto/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/proto/pose_landmarker_graph_options.proto b/mediapipe/tasks/cc/vision/pose_landmarker/proto/pose_landmarker_graph_options.proto index bde314bad..d11395669 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/proto/pose_landmarker_graph_options.proto +++ b/mediapipe/tasks/cc/vision/pose_landmarker/proto/pose_landmarker_graph_options.proto @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/proto/pose_landmarks_detector_graph_options.proto b/mediapipe/tasks/cc/vision/pose_landmarker/proto/pose_landmarks_detector_graph_options.proto index 3b88491bb..9eb835d6a 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/proto/pose_landmarks_detector_graph_options.proto +++ b/mediapipe/tasks/cc/vision/pose_landmarker/proto/pose_landmarks_detector_graph_options.proto @@ -1,4 +1,4 @@ -/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. +/* 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. diff --git a/mediapipe/tasks/cc/vision/utils/BUILD b/mediapipe/tasks/cc/vision/utils/BUILD index 7e5a4dc8c..ae303441c 100644 --- a/mediapipe/tasks/cc/vision/utils/BUILD +++ b/mediapipe/tasks/cc/vision/utils/BUILD @@ -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. diff --git a/mediapipe/tasks/cc/vision/utils/image_tensor_specs.cc b/mediapipe/tasks/cc/vision/utils/image_tensor_specs.cc index 3f0425a69..1041dd1f9 100644 --- a/mediapipe/tasks/cc/vision/utils/image_tensor_specs.cc +++ b/mediapipe/tasks/cc/vision/utils/image_tensor_specs.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/utils/image_tensor_specs.h b/mediapipe/tasks/cc/vision/utils/image_tensor_specs.h index f1ad2a807..d60b8a1da 100644 --- a/mediapipe/tasks/cc/vision/utils/image_tensor_specs.h +++ b/mediapipe/tasks/cc/vision/utils/image_tensor_specs.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/utils/image_tensor_specs_test.cc b/mediapipe/tasks/cc/vision/utils/image_tensor_specs_test.cc index 8c7b7d595..7293d58b6 100644 --- a/mediapipe/tasks/cc/vision/utils/image_tensor_specs_test.cc +++ b/mediapipe/tasks/cc/vision/utils/image_tensor_specs_test.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/utils/image_utils.cc b/mediapipe/tasks/cc/vision/utils/image_utils.cc index 4dc169f12..596d4da25 100644 --- a/mediapipe/tasks/cc/vision/utils/image_utils.cc +++ b/mediapipe/tasks/cc/vision/utils/image_utils.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/utils/image_utils.h b/mediapipe/tasks/cc/vision/utils/image_utils.h index 23833de20..9d67125df 100644 --- a/mediapipe/tasks/cc/vision/utils/image_utils.h +++ b/mediapipe/tasks/cc/vision/utils/image_utils.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/utils/landmarks_duplicates_finder.h b/mediapipe/tasks/cc/vision/utils/landmarks_duplicates_finder.h index e1632e6f0..ac5627e62 100644 --- a/mediapipe/tasks/cc/vision/utils/landmarks_duplicates_finder.h +++ b/mediapipe/tasks/cc/vision/utils/landmarks_duplicates_finder.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/utils/landmarks_utils.cc b/mediapipe/tasks/cc/vision/utils/landmarks_utils.cc index fe4e63824..6db046156 100644 --- a/mediapipe/tasks/cc/vision/utils/landmarks_utils.cc +++ b/mediapipe/tasks/cc/vision/utils/landmarks_utils.cc @@ -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. diff --git a/mediapipe/tasks/cc/vision/utils/landmarks_utils.h b/mediapipe/tasks/cc/vision/utils/landmarks_utils.h index 4d1fac62f..59bc52773 100644 --- a/mediapipe/tasks/cc/vision/utils/landmarks_utils.h +++ b/mediapipe/tasks/cc/vision/utils/landmarks_utils.h @@ -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. diff --git a/mediapipe/tasks/cc/vision/utils/landmarks_utils_test.cc b/mediapipe/tasks/cc/vision/utils/landmarks_utils_test.cc index c30a5225b..55aef554d 100644 --- a/mediapipe/tasks/cc/vision/utils/landmarks_utils_test.cc +++ b/mediapipe/tasks/cc/vision/utils/landmarks_utils_test.cc @@ -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. diff --git a/mediapipe/tasks/examples/android/BUILD b/mediapipe/tasks/examples/android/BUILD index c07af2d2c..f2c90236b 100644 --- a/mediapipe/tasks/examples/android/BUILD +++ b/mediapipe/tasks/examples/android/BUILD @@ -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. diff --git a/mediapipe/tasks/examples/android/objectdetector/src/main/BUILD b/mediapipe/tasks/examples/android/objectdetector/src/main/BUILD index 89c1edcb3..28bd38f9f 100644 --- a/mediapipe/tasks/examples/android/objectdetector/src/main/BUILD +++ b/mediapipe/tasks/examples/android/objectdetector/src/main/BUILD @@ -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. diff --git a/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/MainActivity.java b/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/MainActivity.java index 18c010a00..abfd7c7d1 100644 --- a/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/MainActivity.java +++ b/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/MainActivity.java @@ -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. diff --git a/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/ObjectDetectionResultImageView.java b/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/ObjectDetectionResultImageView.java index 283e48857..e37c64156 100644 --- a/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/ObjectDetectionResultImageView.java +++ b/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/ObjectDetectionResultImageView.java @@ -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. diff --git a/mediapipe/tasks/ios/common/BUILD b/mediapipe/tasks/ios/common/BUILD index 5f13f8d5c..84f537f03 100644 --- a/mediapipe/tasks/ios/common/BUILD +++ b/mediapipe/tasks/ios/common/BUILD @@ -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. diff --git a/mediapipe/tasks/ios/common/sources/MPPCommon.h b/mediapipe/tasks/ios/common/sources/MPPCommon.h index d76123fa0..d543e2dd8 100644 --- a/mediapipe/tasks/ios/common/sources/MPPCommon.h +++ b/mediapipe/tasks/ios/common/sources/MPPCommon.h @@ -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. diff --git a/mediapipe/tasks/ios/common/utils/BUILD b/mediapipe/tasks/ios/common/utils/BUILD index da093a775..015cb05d2 100644 --- a/mediapipe/tasks/ios/common/utils/BUILD +++ b/mediapipe/tasks/ios/common/utils/BUILD @@ -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. diff --git a/mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h b/mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h index 36d90f223..761ad0461 100644 --- a/mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h +++ b/mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h @@ -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. diff --git a/mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.mm b/mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.mm index 65b551c32..9a2aab6ae 100644 --- a/mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.mm +++ b/mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.mm @@ -1,4 +1,4 @@ -// Copyright 2022 The TensorFlow Authors. All Rights Reserved. +// Copyright 2022 The TensorFlow Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h b/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h index 66f9c5ccc..8433baaaf 100644 --- a/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h +++ b/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h @@ -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. diff --git a/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm b/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm index 183ed4365..b7d486e80 100644 --- a/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm +++ b/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm @@ -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. diff --git a/mediapipe/tasks/ios/components/containers/BUILD b/mediapipe/tasks/ios/components/containers/BUILD index 8873847af..9ad5c22fd 100644 --- a/mediapipe/tasks/ios/components/containers/BUILD +++ b/mediapipe/tasks/ios/components/containers/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/components/containers/utils/BUILD b/mediapipe/tasks/ios/components/containers/utils/BUILD index 59431db13..5f0311f51 100644 --- a/mediapipe/tasks/ios/components/containers/utils/BUILD +++ b/mediapipe/tasks/ios/components/containers/utils/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/components/processors/BUILD b/mediapipe/tasks/ios/components/processors/BUILD index 29bef771b..c5715db7e 100644 --- a/mediapipe/tasks/ios/components/processors/BUILD +++ b/mediapipe/tasks/ios/components/processors/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/components/processors/sources/MPPClassifierOptions.h b/mediapipe/tasks/ios/components/processors/sources/MPPClassifierOptions.h index a40c2e391..7bebdf485 100644 --- a/mediapipe/tasks/ios/components/processors/sources/MPPClassifierOptions.h +++ b/mediapipe/tasks/ios/components/processors/sources/MPPClassifierOptions.h @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/ios/components/processors/sources/MPPClassifierOptions.m b/mediapipe/tasks/ios/components/processors/sources/MPPClassifierOptions.m index 9b2207203..e3438db6d 100644 --- a/mediapipe/tasks/ios/components/processors/sources/MPPClassifierOptions.m +++ b/mediapipe/tasks/ios/components/processors/sources/MPPClassifierOptions.m @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/ios/components/processors/utils/BUILD b/mediapipe/tasks/ios/components/processors/utils/BUILD index 0e4c3b09d..b0eefedb4 100644 --- a/mediapipe/tasks/ios/components/processors/utils/BUILD +++ b/mediapipe/tasks/ios/components/processors/utils/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/components/utils/BUILD b/mediapipe/tasks/ios/components/utils/BUILD index f762c2f96..554f726b5 100644 --- a/mediapipe/tasks/ios/components/utils/BUILD +++ b/mediapipe/tasks/ios/components/utils/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/components/utils/sources/MPPCosineSimilarity.h b/mediapipe/tasks/ios/components/utils/sources/MPPCosineSimilarity.h index 8883dbd4c..b9cc1c72b 100644 --- a/mediapipe/tasks/ios/components/utils/sources/MPPCosineSimilarity.h +++ b/mediapipe/tasks/ios/components/utils/sources/MPPCosineSimilarity.h @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/ios/components/utils/sources/MPPCosineSimilarity.mm b/mediapipe/tasks/ios/components/utils/sources/MPPCosineSimilarity.mm index 34c62aafe..4e1ab0eb6 100644 --- a/mediapipe/tasks/ios/components/utils/sources/MPPCosineSimilarity.mm +++ b/mediapipe/tasks/ios/components/utils/sources/MPPCosineSimilarity.mm @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/ios/core/BUILD b/mediapipe/tasks/ios/core/BUILD index f9489acfe..eb6c45819 100644 --- a/mediapipe/tasks/ios/core/BUILD +++ b/mediapipe/tasks/ios/core/BUILD @@ -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. diff --git a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h index 088d2d5da..603be803d 100644 --- a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h +++ b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h @@ -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. diff --git a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m index eaf2aa895..c3571c4b4 100644 --- a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m +++ b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m @@ -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. diff --git a/mediapipe/tasks/ios/core/sources/MPPTaskOptions.h b/mediapipe/tasks/ios/core/sources/MPPTaskOptions.h index e10678348..ecb3da4b2 100644 --- a/mediapipe/tasks/ios/core/sources/MPPTaskOptions.h +++ b/mediapipe/tasks/ios/core/sources/MPPTaskOptions.h @@ -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. diff --git a/mediapipe/tasks/ios/core/sources/MPPTaskOptions.m b/mediapipe/tasks/ios/core/sources/MPPTaskOptions.m index fe74517c3..adc08f03b 100644 --- a/mediapipe/tasks/ios/core/sources/MPPTaskOptions.m +++ b/mediapipe/tasks/ios/core/sources/MPPTaskOptions.m @@ -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. diff --git a/mediapipe/tasks/ios/core/sources/MPPTaskOptionsProtocol.h b/mediapipe/tasks/ios/core/sources/MPPTaskOptionsProtocol.h index c03165c1d..5f76131c0 100644 --- a/mediapipe/tasks/ios/core/sources/MPPTaskOptionsProtocol.h +++ b/mediapipe/tasks/ios/core/sources/MPPTaskOptionsProtocol.h @@ -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. diff --git a/mediapipe/tasks/ios/core/sources/MPPTaskResult.h b/mediapipe/tasks/ios/core/sources/MPPTaskResult.h index 664a94ba6..9bd724e89 100644 --- a/mediapipe/tasks/ios/core/sources/MPPTaskResult.h +++ b/mediapipe/tasks/ios/core/sources/MPPTaskResult.h @@ -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. diff --git a/mediapipe/tasks/ios/core/sources/MPPTaskResult.m b/mediapipe/tasks/ios/core/sources/MPPTaskResult.m index 8a7fa6b5b..100040bc3 100644 --- a/mediapipe/tasks/ios/core/sources/MPPTaskResult.m +++ b/mediapipe/tasks/ios/core/sources/MPPTaskResult.m @@ -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. diff --git a/mediapipe/tasks/ios/core/utils/BUILD b/mediapipe/tasks/ios/core/utils/BUILD index 6577b03b2..3cd8bf231 100644 --- a/mediapipe/tasks/ios/core/utils/BUILD +++ b/mediapipe/tasks/ios/core/utils/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/text/core/BUILD b/mediapipe/tasks/ios/text/core/BUILD index e07d92979..3648ef775 100644 --- a/mediapipe/tasks/ios/text/core/BUILD +++ b/mediapipe/tasks/ios/text/core/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/text/text_classifier/BUILD b/mediapipe/tasks/ios/text/text_classifier/BUILD index 7913340ac..22f9c4af5 100644 --- a/mediapipe/tasks/ios/text/text_classifier/BUILD +++ b/mediapipe/tasks/ios/text/text_classifier/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/text/text_classifier/utils/BUILD b/mediapipe/tasks/ios/text/text_classifier/utils/BUILD index 6795194fb..060a48ff8 100644 --- a/mediapipe/tasks/ios/text/text_classifier/utils/BUILD +++ b/mediapipe/tasks/ios/text/text_classifier/utils/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/text/text_embedder/BUILD b/mediapipe/tasks/ios/text/text_embedder/BUILD index a600d5366..07797e4ce 100644 --- a/mediapipe/tasks/ios/text/text_embedder/BUILD +++ b/mediapipe/tasks/ios/text/text_embedder/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/text/text_embedder/utils/BUILD b/mediapipe/tasks/ios/text/text_embedder/utils/BUILD index eeb4981fb..392ec6f22 100644 --- a/mediapipe/tasks/ios/text/text_embedder/utils/BUILD +++ b/mediapipe/tasks/ios/text/text_embedder/utils/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/vision/core/sources/MPPRunningMode.h b/mediapipe/tasks/ios/vision/core/sources/MPPRunningMode.h index ee52a693a..a3b3ad705 100644 --- a/mediapipe/tasks/ios/vision/core/sources/MPPRunningMode.h +++ b/mediapipe/tasks/ios/vision/core/sources/MPPRunningMode.h @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/BUILD b/mediapipe/tasks/ios/vision/gesture_recognizer/BUILD index 1c6f0eeeb..26fa4d6cf 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/BUILD +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/vision/image_classifier/BUILD b/mediapipe/tasks/ios/vision/image_classifier/BUILD index 4ebcd2b29..69490f716 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/BUILD +++ b/mediapipe/tasks/ios/vision/image_classifier/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/vision/image_classifier/utils/BUILD b/mediapipe/tasks/ios/vision/image_classifier/utils/BUILD index c1928b6ff..25955f4da 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/utils/BUILD +++ b/mediapipe/tasks/ios/vision/image_classifier/utils/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/vision/object_detector/BUILD b/mediapipe/tasks/ios/vision/object_detector/BUILD index abbd1e046..aee92a2f1 100644 --- a/mediapipe/tasks/ios/vision/object_detector/BUILD +++ b/mediapipe/tasks/ios/vision/object_detector/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/ios/vision/object_detector/utils/BUILD b/mediapipe/tasks/ios/vision/object_detector/utils/BUILD index 70499e98d..d4597b239 100644 --- a/mediapipe/tasks/ios/vision/object_detector/utils/BUILD +++ b/mediapipe/tasks/ios/vision/object_detector/utils/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/java/BUILD b/mediapipe/tasks/java/BUILD index 13a319bb7..7b5778703 100644 --- a/mediapipe/tasks/java/BUILD +++ b/mediapipe/tasks/java/BUILD @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/BUILD index 7e6283261..6092601f6 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/BUILD @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/BUILD index 7f9363340..29f121ac1 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/BUILD @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioclassifier/AudioClassifier.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioclassifier/AudioClassifier.java index 4e5cd7655..a33f19953 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioclassifier/AudioClassifier.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioclassifier/AudioClassifier.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioclassifier/AudioClassifierResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioclassifier/AudioClassifierResult.java index 258e5725b..5cb1beff7 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioclassifier/AudioClassifierResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioclassifier/AudioClassifierResult.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioembedder/AudioEmbedder.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioembedder/AudioEmbedder.java index 67d3f8b5f..8cc3b45a3 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioembedder/AudioEmbedder.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioembedder/AudioEmbedder.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioembedder/AudioEmbedderResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioembedder/AudioEmbedderResult.java index 0cfd2297c..ef485c5b7 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioembedder/AudioEmbedderResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/audioembedder/AudioEmbedderResult.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/core/BaseAudioTaskApi.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/core/BaseAudioTaskApi.java index f577a361b..bd65e6d44 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/core/BaseAudioTaskApi.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/core/BaseAudioTaskApi.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/core/RunningMode.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/core/RunningMode.java index a778eae46..b6506d090 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/core/RunningMode.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/audio/core/RunningMode.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/AudioData.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/AudioData.java index 40a05b1e4..2758e07bf 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/AudioData.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/AudioData.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/BUILD index d70aa94a5..2c76f9a0b 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/BUILD @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Category.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Category.java index ab3fd0bd8..65996c2af 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Category.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Category.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/ClassificationResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/ClassificationResult.java index d30099d8b..0ef9b4abc 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/ClassificationResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/ClassificationResult.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Classifications.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Classifications.java index 12f14e628..9e53590d7 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Classifications.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Classifications.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Detection.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Detection.java index b776da66a..7ef7c4b5d 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Detection.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Detection.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Embedding.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Embedding.java index 6cb0e325b..05e3ea2df 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Embedding.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Embedding.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/EmbeddingResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/EmbeddingResult.java index 32fa7b47d..95b7aac55 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/EmbeddingResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/EmbeddingResult.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Landmark.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Landmark.java index 7fb1b99d0..c3e9f2715 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Landmark.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Landmark.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/NormalizedKeypoint.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/NormalizedKeypoint.java index 1a4c1ebab..be55746b2 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/NormalizedKeypoint.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/NormalizedKeypoint.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/NormalizedLandmark.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/NormalizedLandmark.java index e77f3c3d4..f96e434ca 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/NormalizedLandmark.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/NormalizedLandmark.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/processors/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/processors/BUILD index b4d453935..7acc4280c 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/processors/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/processors/BUILD @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/processors/ClassifierOptions.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/processors/ClassifierOptions.java index 76da4b446..131bf9707 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/processors/ClassifierOptions.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/processors/ClassifierOptions.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/utils/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/utils/BUILD index 6c724106f..a9c07947d 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/utils/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/utils/BUILD @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/utils/CosineSimilarity.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/utils/CosineSimilarity.java index 6b995731f..77d107ee2 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/utils/CosineSimilarity.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/utils/CosineSimilarity.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/BUILD index df7fe5b11..d04fc4258 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/BUILD @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/BaseOptions.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/BaseOptions.java index d1db08893..8eec72ef9 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/BaseOptions.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/BaseOptions.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/Delegate.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/Delegate.java index 84bf7270f..8a3174c66 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/Delegate.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/Delegate.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/ErrorListener.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/ErrorListener.java index 3f62d5d4f..d1f9163eb 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/ErrorListener.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/ErrorListener.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/ModelResourcesCache.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/ModelResourcesCache.java index 4e81a3805..87f89d39c 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/ModelResourcesCache.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/ModelResourcesCache.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/ModelResourcesCacheService.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/ModelResourcesCacheService.java index 2cf2f096b..7a0b52114 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/ModelResourcesCacheService.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/ModelResourcesCacheService.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/OutputHandler.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/OutputHandler.java index c330b1a56..dba918483 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/OutputHandler.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/OutputHandler.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskInfo.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskInfo.java index 31af80f5c..3c422a8b2 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskInfo.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskInfo.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskOptions.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskOptions.java index 0fc48742e..9c6f1adca 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskOptions.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskOptions.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskResult.java index 03b11e877..1d1fbe883 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskResult.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskRunner.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskRunner.java index 155536a4e..d162d39d4 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskRunner.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskRunner.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/BUILD index 8f8abf06f..2033d727f 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/BUILD @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/BUILD.bazel b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/BUILD.bazel index 0eb74e7ff..4a8235200 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/BUILD.bazel +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/BUILD.bazel @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/model_resources_cache_jni.cc b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/model_resources_cache_jni.cc index c7e015639..24c536149 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/model_resources_cache_jni.cc +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/model_resources_cache_jni.cc @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/model_resources_cache_jni.h b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/model_resources_cache_jni.h index 9b0478939..7e8280702 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/model_resources_cache_jni.h +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/jni/model_resources_cache_jni.h @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/logging/TasksStatsDummyLogger.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/logging/TasksStatsDummyLogger.java index c10b5d224..50e192483 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/logging/TasksStatsDummyLogger.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/logging/TasksStatsDummyLogger.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/logging/TasksStatsLogger.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/logging/TasksStatsLogger.java index c726e7d0d..f4f5551c7 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/logging/TasksStatsLogger.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/logging/TasksStatsLogger.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/mediapipe_tasks_aar.bzl b/mediapipe/tasks/java/com/google/mediapipe/tasks/mediapipe_tasks_aar.bzl index d63b0e358..d5188ae55 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/mediapipe_tasks_aar.bzl +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/mediapipe_tasks_aar.bzl @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/BUILD index 74ca87b5d..558f687a4 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/BUILD @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/languagedetector/LanguageDetector.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/languagedetector/LanguageDetector.java index 216fae6d7..0ad425de3 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/languagedetector/LanguageDetector.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/languagedetector/LanguageDetector.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/languagedetector/LanguageDetectorResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/languagedetector/LanguageDetectorResult.java index 10b8dac46..e2d42f08b 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/languagedetector/LanguageDetectorResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/languagedetector/LanguageDetectorResult.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/languagedetector/LanguagePrediction.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/languagedetector/LanguagePrediction.java index e2e4321a3..103be7f2f 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/languagedetector/LanguagePrediction.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/languagedetector/LanguagePrediction.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textclassifier/TextClassifier.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textclassifier/TextClassifier.java index edb78a191..92a19783e 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textclassifier/TextClassifier.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textclassifier/TextClassifier.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textclassifier/TextClassifierResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textclassifier/TextClassifierResult.java index 64de0ee8d..26163d20e 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textclassifier/TextClassifierResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textclassifier/TextClassifierResult.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textembedder/TextEmbedder.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textembedder/TextEmbedder.java index 28f351d4b..77caae86b 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textembedder/TextEmbedder.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textembedder/TextEmbedder.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textembedder/TextEmbedderResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textembedder/TextEmbedderResult.java index 9d8e108ec..4fe81c6d7 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textembedder/TextEmbedderResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/text/textembedder/TextEmbedderResult.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD index fc933b6f3..5be0e233f 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java index b6e244d1f..070806522 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/ImageProcessingOptions.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/ImageProcessingOptions.java index a34a9787d..9e7161b5a 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/ImageProcessingOptions.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/ImageProcessingOptions.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/RunningMode.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/RunningMode.java index 8b0ffb8fd..80ff4e021 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/RunningMode.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/RunningMode.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facedetector/FaceDetector.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facedetector/FaceDetector.java index c23432c1b..09dad443a 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facedetector/FaceDetector.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facedetector/FaceDetector.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facedetector/FaceDetectorResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facedetector/FaceDetectorResult.java index 9a9fd45ec..9b7592cb2 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facedetector/FaceDetectorResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facedetector/FaceDetectorResult.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarker.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarker.java index 599113aa2..6a10f52ed 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarker.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarker.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarkerResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarkerResult.java index 7054856fc..c91477e10 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarkerResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarkerResult.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarksConnections.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarksConnections.java index 05a21cb1f..ad996f369 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarksConnections.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarksConnections.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facestylizer/FaceStylizer.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facestylizer/FaceStylizer.java index d6f565c78..741c87e7c 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facestylizer/FaceStylizer.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facestylizer/FaceStylizer.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facestylizer/FaceStylizerResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facestylizer/FaceStylizerResult.java index bbabea6a7..318a529b5 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facestylizer/FaceStylizerResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facestylizer/FaceStylizerResult.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizer.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizer.java index 5b2d7191f..03c2d03f0 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizer.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizer.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizerResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizerResult.java index 90b92175d..d4438efe7 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizerResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizerResult.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmark.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmark.java index 7b21ebddf..62ba29d0f 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmark.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmark.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarker.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarker.java index 1d08ab928..2af893128 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarker.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarker.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarkerResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarkerResult.java index 9092c0a2d..467e871b2 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarkerResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarkerResult.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageclassifier/ImageClassifier.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageclassifier/ImageClassifier.java index 38482797c..8da7c0267 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageclassifier/ImageClassifier.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageclassifier/ImageClassifier.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageclassifier/ImageClassifierResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageclassifier/ImageClassifierResult.java index 924542158..21fbb51c7 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageclassifier/ImageClassifierResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageclassifier/ImageClassifierResult.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageembedder/ImageEmbedder.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageembedder/ImageEmbedder.java index 488927257..0c1d24366 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageembedder/ImageEmbedder.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageembedder/ImageEmbedder.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageembedder/ImageEmbedderResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageembedder/ImageEmbedderResult.java index ee3f4abc9..e2dee9ea1 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageembedder/ImageEmbedderResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imageembedder/ImageEmbedderResult.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java index be761907d..200fbeabb 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterResult.java index 4030c6f93..cbc5211cc 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterResult.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java index 6f47797b4..2a5d148e4 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectionResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectionResult.java index 295c88b0a..120cddd46 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectionResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectionResult.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetector.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetector.java index d706189ee..5287ba325 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetector.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetector.java @@ -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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java index 2d9aafc4b..2ebdc0732 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerResult.java index bb632d3b8..488f2a556 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerResult.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/components/utils/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/components/utils/BUILD index a7f804c64..2ec85d1a2 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/components/utils/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/components/utils/BUILD @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/components/utils/CosineSimilarityTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/components/utils/CosineSimilarityTest.java index f7a1ae002..1ee0a50f5 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/components/utils/CosineSimilarityTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/components/utils/CosineSimilarityTest.java @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/core/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/core/BUILD index 74bf48c59..01e7ad0fa 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/core/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/core/BUILD @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/core/TestUtils.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/core/TestUtils.java index 130c413b9..5aac23b4d 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/core/TestUtils.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/core/TestUtils.java @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/languagedetector/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/languagedetector/BUILD index c14486766..287602c85 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/languagedetector/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/languagedetector/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/languagedetector/LanguageDetectorTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/languagedetector/LanguageDetectorTest.java index fe6d28f4d..fd205f5dc 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/languagedetector/LanguageDetectorTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/languagedetector/LanguageDetectorTest.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textclassifier/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textclassifier/BUILD index a7f804c64..2ec85d1a2 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textclassifier/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textclassifier/BUILD @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textclassifier/TextClassifierTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textclassifier/TextClassifierTest.java index 5ed413f6a..60b2ab480 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textclassifier/TextClassifierTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textclassifier/TextClassifierTest.java @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textembedder/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textembedder/BUILD index a7f804c64..2ec85d1a2 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textembedder/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textembedder/BUILD @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textembedder/TextEmbedderTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textembedder/TextEmbedderTest.java index 79628826b..ed7573b2a 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textembedder/TextEmbedderTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/text/textembedder/TextEmbedderTest.java @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/core/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/core/BUILD index a7f804c64..2ec85d1a2 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/core/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/core/BUILD @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/core/ImageProcessingOptionsTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/core/ImageProcessingOptionsTest.java index 078b62af1..d998ccf35 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/core/ImageProcessingOptionsTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/core/ImageProcessingOptionsTest.java @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facedetector/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facedetector/BUILD index c14486766..287602c85 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facedetector/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facedetector/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facedetector/FaceDetectorTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facedetector/FaceDetectorTest.java index d995accd5..f377b9959 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facedetector/FaceDetectorTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facedetector/FaceDetectorTest.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facelandmarker/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facelandmarker/BUILD index c14486766..287602c85 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facelandmarker/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facelandmarker/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarkerTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarkerTest.java index 0b21e863c..6f117f94a 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarkerTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarkerTest.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facestylizer/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facestylizer/BUILD index c14486766..287602c85 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facestylizer/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facestylizer/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facestylizer/FaceStylizerTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facestylizer/FaceStylizerTest.java index 4f6cc2d68..b93796314 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facestylizer/FaceStylizerTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/facestylizer/FaceStylizerTest.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/gesturerecognizer/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/gesturerecognizer/BUILD index a7f804c64..2ec85d1a2 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/gesturerecognizer/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/gesturerecognizer/BUILD @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizerTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizerTest.java index 5821b36cc..5f461a4c1 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizerTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/gesturerecognizer/GestureRecognizerTest.java @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/handlandmarker/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/handlandmarker/BUILD index a7f804c64..2ec85d1a2 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/handlandmarker/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/handlandmarker/BUILD @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarkerTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarkerTest.java index c313d385d..94434a217 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarkerTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarkerTest.java @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageclassifier/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageclassifier/BUILD index a7f804c64..2ec85d1a2 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageclassifier/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageclassifier/BUILD @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageclassifier/ImageClassifierTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageclassifier/ImageClassifierTest.java index 3da4ea9b5..d33b7f1b5 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageclassifier/ImageClassifierTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageclassifier/ImageClassifierTest.java @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageembedder/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageembedder/BUILD index a7f804c64..2ec85d1a2 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageembedder/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageembedder/BUILD @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageembedder/ImageEmbedderTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageembedder/ImageEmbedderTest.java index d54586f6f..99d2a749b 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageembedder/ImageEmbedderTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imageembedder/ImageEmbedderTest.java @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imagesegmenter/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imagesegmenter/BUILD index c14486766..287602c85 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imagesegmenter/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imagesegmenter/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterTest.java index 0cbbec4af..959f444cd 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterTest.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/interactivesegmenter/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/interactivesegmenter/BUILD index c14486766..287602c85 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/interactivesegmenter/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/interactivesegmenter/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenterTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenterTest.java index 3a6854949..506036ba2 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenterTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenterTest.java @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/BUILD index a7f804c64..2ec85d1a2 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/BUILD @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorTest.java index 58bcaafda..33aa025d2 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorTest.java @@ -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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/poselandmarker/BUILD b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/poselandmarker/BUILD index c14486766..287602c85 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/poselandmarker/BUILD +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/poselandmarker/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerTest.java index 30ced66f5..1d0b1decd 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerTest.java @@ -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. diff --git a/mediapipe/tasks/metadata/image_segmenter_metadata_schema.fbs b/mediapipe/tasks/metadata/image_segmenter_metadata_schema.fbs index 850109074..c57fdb924 100644 --- a/mediapipe/tasks/metadata/image_segmenter_metadata_schema.fbs +++ b/mediapipe/tasks/metadata/image_segmenter_metadata_schema.fbs @@ -1,4 +1,4 @@ -// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// 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. diff --git a/mediapipe/tasks/metadata/metadata_schema.fbs b/mediapipe/tasks/metadata/metadata_schema.fbs index 8660ba38c..e6df1ac62 100644 --- a/mediapipe/tasks/metadata/metadata_schema.fbs +++ b/mediapipe/tasks/metadata/metadata_schema.fbs @@ -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. diff --git a/mediapipe/tasks/python/BUILD b/mediapipe/tasks/python/BUILD index 1efb28d02..451a42b2d 100644 --- a/mediapipe/tasks/python/BUILD +++ b/mediapipe/tasks/python/BUILD @@ -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. diff --git a/mediapipe/tasks/python/__init__.py b/mediapipe/tasks/python/__init__.py index 9a9573445..953855645 100644 --- a/mediapipe/tasks/python/__init__.py +++ b/mediapipe/tasks/python/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/audio/BUILD b/mediapipe/tasks/python/audio/BUILD index 9d8af1463..9f1fdd975 100644 --- a/mediapipe/tasks/python/audio/BUILD +++ b/mediapipe/tasks/python/audio/BUILD @@ -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. diff --git a/mediapipe/tasks/python/audio/__init__.py b/mediapipe/tasks/python/audio/__init__.py index e129800a3..df217be69 100644 --- a/mediapipe/tasks/python/audio/__init__.py +++ b/mediapipe/tasks/python/audio/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/audio/audio_classifier.py b/mediapipe/tasks/python/audio/audio_classifier.py index cc87d6221..44795dcac 100644 --- a/mediapipe/tasks/python/audio/audio_classifier.py +++ b/mediapipe/tasks/python/audio/audio_classifier.py @@ -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. diff --git a/mediapipe/tasks/python/audio/audio_embedder.py b/mediapipe/tasks/python/audio/audio_embedder.py index 835dd0e31..806379014 100644 --- a/mediapipe/tasks/python/audio/audio_embedder.py +++ b/mediapipe/tasks/python/audio/audio_embedder.py @@ -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. diff --git a/mediapipe/tasks/python/audio/core/BUILD b/mediapipe/tasks/python/audio/core/BUILD index ad22faa98..b3c0076da 100644 --- a/mediapipe/tasks/python/audio/core/BUILD +++ b/mediapipe/tasks/python/audio/core/BUILD @@ -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. diff --git a/mediapipe/tasks/python/audio/core/audio_record.py b/mediapipe/tasks/python/audio/core/audio_record.py index bc12e3755..6b326bff5 100644 --- a/mediapipe/tasks/python/audio/core/audio_record.py +++ b/mediapipe/tasks/python/audio/core/audio_record.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/audio/core/audio_task_running_mode.py b/mediapipe/tasks/python/audio/core/audio_task_running_mode.py index 0fa36d40e..2ad57af97 100644 --- a/mediapipe/tasks/python/audio/core/audio_task_running_mode.py +++ b/mediapipe/tasks/python/audio/core/audio_task_running_mode.py @@ -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. diff --git a/mediapipe/tasks/python/audio/core/base_audio_task_api.py b/mediapipe/tasks/python/audio/core/base_audio_task_api.py index be8ff9324..98236c030 100644 --- a/mediapipe/tasks/python/audio/core/base_audio_task_api.py +++ b/mediapipe/tasks/python/audio/core/base_audio_task_api.py @@ -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. diff --git a/mediapipe/tasks/python/components/__init__.py b/mediapipe/tasks/python/components/__init__.py index 65c1214af..3fbc1e8a7 100644 --- a/mediapipe/tasks/python/components/__init__.py +++ b/mediapipe/tasks/python/components/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/components/containers/BUILD b/mediapipe/tasks/python/components/containers/BUILD index b84ab744d..8c80decb2 100644 --- a/mediapipe/tasks/python/components/containers/BUILD +++ b/mediapipe/tasks/python/components/containers/BUILD @@ -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. diff --git a/mediapipe/tasks/python/components/containers/__init__.py b/mediapipe/tasks/python/components/containers/__init__.py index 17464db36..1a3f0c339 100644 --- a/mediapipe/tasks/python/components/containers/__init__.py +++ b/mediapipe/tasks/python/components/containers/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/components/containers/audio_data.py b/mediapipe/tasks/python/components/containers/audio_data.py index 1d0267998..c65912967 100644 --- a/mediapipe/tasks/python/components/containers/audio_data.py +++ b/mediapipe/tasks/python/components/containers/audio_data.py @@ -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. diff --git a/mediapipe/tasks/python/components/containers/bounding_box.py b/mediapipe/tasks/python/components/containers/bounding_box.py index 7cfbdf794..9ff15c755 100644 --- a/mediapipe/tasks/python/components/containers/bounding_box.py +++ b/mediapipe/tasks/python/components/containers/bounding_box.py @@ -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. diff --git a/mediapipe/tasks/python/components/containers/category.py b/mediapipe/tasks/python/components/containers/category.py index 9b5419883..b669301e4 100644 --- a/mediapipe/tasks/python/components/containers/category.py +++ b/mediapipe/tasks/python/components/containers/category.py @@ -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. diff --git a/mediapipe/tasks/python/components/containers/classification_result.py b/mediapipe/tasks/python/components/containers/classification_result.py index 000468041..fbaadee29 100644 --- a/mediapipe/tasks/python/components/containers/classification_result.py +++ b/mediapipe/tasks/python/components/containers/classification_result.py @@ -1,4 +1,4 @@ -# Copyright 2022 The TensorFlow Authors. All Rights Reserved. +# Copyright 2022 The TensorFlow Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/mediapipe/tasks/python/components/containers/detections.py b/mediapipe/tasks/python/components/containers/detections.py index 935d294a6..833552c42 100644 --- a/mediapipe/tasks/python/components/containers/detections.py +++ b/mediapipe/tasks/python/components/containers/detections.py @@ -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. diff --git a/mediapipe/tasks/python/components/containers/embedding_result.py b/mediapipe/tasks/python/components/containers/embedding_result.py index 999f74535..c85e00d1c 100644 --- a/mediapipe/tasks/python/components/containers/embedding_result.py +++ b/mediapipe/tasks/python/components/containers/embedding_result.py @@ -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. diff --git a/mediapipe/tasks/python/components/containers/keypoint.py b/mediapipe/tasks/python/components/containers/keypoint.py index 3d957f3d8..1585fb8c4 100644 --- a/mediapipe/tasks/python/components/containers/keypoint.py +++ b/mediapipe/tasks/python/components/containers/keypoint.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/components/containers/landmark.py b/mediapipe/tasks/python/components/containers/landmark.py index dee2a16ad..d4ab0f311 100644 --- a/mediapipe/tasks/python/components/containers/landmark.py +++ b/mediapipe/tasks/python/components/containers/landmark.py @@ -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. diff --git a/mediapipe/tasks/python/components/containers/landmark_detection_result.py b/mediapipe/tasks/python/components/containers/landmark_detection_result.py index a5b205dfa..c60ad850c 100644 --- a/mediapipe/tasks/python/components/containers/landmark_detection_result.py +++ b/mediapipe/tasks/python/components/containers/landmark_detection_result.py @@ -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. diff --git a/mediapipe/tasks/python/components/containers/rect.py b/mediapipe/tasks/python/components/containers/rect.py index 4fdccbafb..867eabb01 100644 --- a/mediapipe/tasks/python/components/containers/rect.py +++ b/mediapipe/tasks/python/components/containers/rect.py @@ -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. diff --git a/mediapipe/tasks/python/components/processors/BUILD b/mediapipe/tasks/python/components/processors/BUILD index 695f6df91..881e3e356 100644 --- a/mediapipe/tasks/python/components/processors/BUILD +++ b/mediapipe/tasks/python/components/processors/BUILD @@ -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. diff --git a/mediapipe/tasks/python/components/processors/__init__.py b/mediapipe/tasks/python/components/processors/__init__.py index 0eb73abe0..99a894e27 100644 --- a/mediapipe/tasks/python/components/processors/__init__.py +++ b/mediapipe/tasks/python/components/processors/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/components/processors/classifier_options.py b/mediapipe/tasks/python/components/processors/classifier_options.py index 2e77f93b5..82a7add1a 100644 --- a/mediapipe/tasks/python/components/processors/classifier_options.py +++ b/mediapipe/tasks/python/components/processors/classifier_options.py @@ -1,4 +1,4 @@ -# Copyright 2022 The TensorFlow Authors. All Rights Reserved. +# Copyright 2022 The TensorFlow Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/mediapipe/tasks/python/components/utils/BUILD b/mediapipe/tasks/python/components/utils/BUILD index 1a18531c6..64231fde0 100644 --- a/mediapipe/tasks/python/components/utils/BUILD +++ b/mediapipe/tasks/python/components/utils/BUILD @@ -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. diff --git a/mediapipe/tasks/python/components/utils/__init__.py b/mediapipe/tasks/python/components/utils/__init__.py index 65c1214af..3fbc1e8a7 100644 --- a/mediapipe/tasks/python/components/utils/__init__.py +++ b/mediapipe/tasks/python/components/utils/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/components/utils/cosine_similarity.py b/mediapipe/tasks/python/components/utils/cosine_similarity.py index a6245a579..1c60a71b2 100644 --- a/mediapipe/tasks/python/components/utils/cosine_similarity.py +++ b/mediapipe/tasks/python/components/utils/cosine_similarity.py @@ -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. diff --git a/mediapipe/tasks/python/core/BUILD b/mediapipe/tasks/python/core/BUILD index 6098fb5f5..f90826354 100644 --- a/mediapipe/tasks/python/core/BUILD +++ b/mediapipe/tasks/python/core/BUILD @@ -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. diff --git a/mediapipe/tasks/python/core/__init__.py b/mediapipe/tasks/python/core/__init__.py index 65c1214af..3fbc1e8a7 100644 --- a/mediapipe/tasks/python/core/__init__.py +++ b/mediapipe/tasks/python/core/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/core/base_options.py b/mediapipe/tasks/python/core/base_options.py index b48fa2ccc..90ef045b8 100644 --- a/mediapipe/tasks/python/core/base_options.py +++ b/mediapipe/tasks/python/core/base_options.py @@ -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. diff --git a/mediapipe/tasks/python/core/optional_dependencies.py b/mediapipe/tasks/python/core/optional_dependencies.py index b1a0ed538..108caa0e0 100644 --- a/mediapipe/tasks/python/core/optional_dependencies.py +++ b/mediapipe/tasks/python/core/optional_dependencies.py @@ -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. diff --git a/mediapipe/tasks/python/core/pybind/BUILD b/mediapipe/tasks/python/core/pybind/BUILD index b59635dc3..88ea05f4f 100644 --- a/mediapipe/tasks/python/core/pybind/BUILD +++ b/mediapipe/tasks/python/core/pybind/BUILD @@ -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. diff --git a/mediapipe/tasks/python/core/pybind/task_runner.cc b/mediapipe/tasks/python/core/pybind/task_runner.cc index 250c0fa62..f95cddde8 100644 --- a/mediapipe/tasks/python/core/pybind/task_runner.cc +++ b/mediapipe/tasks/python/core/pybind/task_runner.cc @@ -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. diff --git a/mediapipe/tasks/python/core/pybind/task_runner.h b/mediapipe/tasks/python/core/pybind/task_runner.h index 3f6e998c9..c153893bd 100644 --- a/mediapipe/tasks/python/core/pybind/task_runner.h +++ b/mediapipe/tasks/python/core/pybind/task_runner.h @@ -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. diff --git a/mediapipe/tasks/python/core/task_info.py b/mediapipe/tasks/python/core/task_info.py index 6ea2cee7b..1816d60e0 100644 --- a/mediapipe/tasks/python/core/task_info.py +++ b/mediapipe/tasks/python/core/task_info.py @@ -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. diff --git a/mediapipe/tasks/python/metadata/__init__.py b/mediapipe/tasks/python/metadata/__init__.py index 7ca2f9216..5b1a4244c 100644 --- a/mediapipe/tasks/python/metadata/__init__.py +++ b/mediapipe/tasks/python/metadata/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/metadata/flatbuffers_lib/flatbuffers_lib.cc b/mediapipe/tasks/python/metadata/flatbuffers_lib/flatbuffers_lib.cc index 34407620c..aa61ec910 100644 --- a/mediapipe/tasks/python/metadata/flatbuffers_lib/flatbuffers_lib.cc +++ b/mediapipe/tasks/python/metadata/flatbuffers_lib/flatbuffers_lib.cc @@ -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. diff --git a/mediapipe/tasks/python/metadata/metadata.py b/mediapipe/tasks/python/metadata/metadata.py index 6a107c8d8..9821e0ca9 100644 --- a/mediapipe/tasks/python/metadata/metadata.py +++ b/mediapipe/tasks/python/metadata/metadata.py @@ -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. diff --git a/mediapipe/tasks/python/metadata/metadata_displayer_cli.py b/mediapipe/tasks/python/metadata/metadata_displayer_cli.py index 745da1f25..0e416efec 100644 --- a/mediapipe/tasks/python/metadata/metadata_displayer_cli.py +++ b/mediapipe/tasks/python/metadata/metadata_displayer_cli.py @@ -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. diff --git a/mediapipe/tasks/python/metadata/metadata_parser.py.template b/mediapipe/tasks/python/metadata/metadata_parser.py.template index b5a64dee6..63ecd582f 100644 --- a/mediapipe/tasks/python/metadata/metadata_parser.py.template +++ b/mediapipe/tasks/python/metadata/metadata_parser.py.template @@ -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. diff --git a/mediapipe/tasks/python/metadata/metadata_writers/__init__.py b/mediapipe/tasks/python/metadata/metadata_writers/__init__.py index 7ca2f9216..5b1a4244c 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/__init__.py +++ b/mediapipe/tasks/python/metadata/metadata_writers/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/metadata/metadata_writers/image_classifier.py b/mediapipe/tasks/python/metadata/metadata_writers/image_classifier.py index 7f2685792..6c1ba704e 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/image_classifier.py +++ b/mediapipe/tasks/python/metadata/metadata_writers/image_classifier.py @@ -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. diff --git a/mediapipe/tasks/python/metadata/metadata_writers/image_segmenter.py b/mediapipe/tasks/python/metadata/metadata_writers/image_segmenter.py index 3268f3b1f..8e38731a5 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/image_segmenter.py +++ b/mediapipe/tasks/python/metadata/metadata_writers/image_segmenter.py @@ -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. diff --git a/mediapipe/tasks/python/metadata/metadata_writers/metadata_info.py b/mediapipe/tasks/python/metadata/metadata_writers/metadata_info.py index 10b66ff18..3b47e9b3b 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/metadata_info.py +++ b/mediapipe/tasks/python/metadata/metadata_writers/metadata_info.py @@ -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. diff --git a/mediapipe/tasks/python/metadata/metadata_writers/metadata_writer.py b/mediapipe/tasks/python/metadata/metadata_writers/metadata_writer.py index e0be9beea..302b717a1 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/metadata_writer.py +++ b/mediapipe/tasks/python/metadata/metadata_writers/metadata_writer.py @@ -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. diff --git a/mediapipe/tasks/python/metadata/metadata_writers/model_asset_bundle_utils.py b/mediapipe/tasks/python/metadata/metadata_writers/model_asset_bundle_utils.py index b626dc7b1..87236b5ae 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/model_asset_bundle_utils.py +++ b/mediapipe/tasks/python/metadata/metadata_writers/model_asset_bundle_utils.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/metadata/metadata_writers/object_detector.py b/mediapipe/tasks/python/metadata/metadata_writers/object_detector.py index 863c1bb2f..f070534c1 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/object_detector.py +++ b/mediapipe/tasks/python/metadata/metadata_writers/object_detector.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/metadata/metadata_writers/text_classifier.py b/mediapipe/tasks/python/metadata/metadata_writers/text_classifier.py index b9abb6b5d..787fcd7a4 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/text_classifier.py +++ b/mediapipe/tasks/python/metadata/metadata_writers/text_classifier.py @@ -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. diff --git a/mediapipe/tasks/python/metadata/metadata_writers/writer_utils.py b/mediapipe/tasks/python/metadata/metadata_writers/writer_utils.py index 13586f63c..803f06e18 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/writer_utils.py +++ b/mediapipe/tasks/python/metadata/metadata_writers/writer_utils.py @@ -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. diff --git a/mediapipe/tasks/python/test/BUILD b/mediapipe/tasks/python/test/BUILD index fb608f123..252440bf8 100644 --- a/mediapipe/tasks/python/test/BUILD +++ b/mediapipe/tasks/python/test/BUILD @@ -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. diff --git a/mediapipe/tasks/python/test/__init__.py b/mediapipe/tasks/python/test/__init__.py index 65c1214af..3fbc1e8a7 100644 --- a/mediapipe/tasks/python/test/__init__.py +++ b/mediapipe/tasks/python/test/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/test/audio/BUILD b/mediapipe/tasks/python/test/audio/BUILD index 3df783180..48f7bffe4 100644 --- a/mediapipe/tasks/python/test/audio/BUILD +++ b/mediapipe/tasks/python/test/audio/BUILD @@ -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. diff --git a/mediapipe/tasks/python/test/audio/__init__.py b/mediapipe/tasks/python/test/audio/__init__.py index 65c1214af..3fbc1e8a7 100644 --- a/mediapipe/tasks/python/test/audio/__init__.py +++ b/mediapipe/tasks/python/test/audio/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/test/audio/audio_classifier_test.py b/mediapipe/tasks/python/test/audio/audio_classifier_test.py index 33f66786d..7ace77f6a 100644 --- a/mediapipe/tasks/python/test/audio/audio_classifier_test.py +++ b/mediapipe/tasks/python/test/audio/audio_classifier_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/audio/audio_embedder_test.py b/mediapipe/tasks/python/test/audio/audio_embedder_test.py index e5735b6b5..31c0f63fc 100644 --- a/mediapipe/tasks/python/test/audio/audio_embedder_test.py +++ b/mediapipe/tasks/python/test/audio/audio_embedder_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/audio/core/BUILD b/mediapipe/tasks/python/test/audio/core/BUILD index 2f9c66be3..b7a8d6e1f 100644 --- a/mediapipe/tasks/python/test/audio/core/BUILD +++ b/mediapipe/tasks/python/test/audio/core/BUILD @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/test/audio/core/audio_record_test.py b/mediapipe/tasks/python/test/audio/core/audio_record_test.py index ac804b894..dea7de9b0 100644 --- a/mediapipe/tasks/python/test/audio/core/audio_record_test.py +++ b/mediapipe/tasks/python/test/audio/core/audio_record_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/test/metadata/metadata_parser_test.py b/mediapipe/tasks/python/test/metadata/metadata_parser_test.py index 93b851082..29f170389 100644 --- a/mediapipe/tasks/python/test/metadata/metadata_parser_test.py +++ b/mediapipe/tasks/python/test/metadata/metadata_parser_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/metadata/metadata_test.py b/mediapipe/tasks/python/test/metadata/metadata_test.py index c91bcce6e..4f7d34072 100644 --- a/mediapipe/tasks/python/test/metadata/metadata_test.py +++ b/mediapipe/tasks/python/test/metadata/metadata_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/metadata/metadata_writers/image_classifier_test.py b/mediapipe/tasks/python/test/metadata/metadata_writers/image_classifier_test.py index 51f248d1e..2e0b24777 100644 --- a/mediapipe/tasks/python/test/metadata/metadata_writers/image_classifier_test.py +++ b/mediapipe/tasks/python/test/metadata/metadata_writers/image_classifier_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/metadata/metadata_writers/image_segmenter_test.py b/mediapipe/tasks/python/test/metadata/metadata_writers/image_segmenter_test.py index a12f009cd..9e0267b16 100644 --- a/mediapipe/tasks/python/test/metadata/metadata_writers/image_segmenter_test.py +++ b/mediapipe/tasks/python/test/metadata/metadata_writers/image_segmenter_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/metadata/metadata_writers/metadata_info_test.py b/mediapipe/tasks/python/test/metadata/metadata_writers/metadata_info_test.py index fd4462631..fdf8a2204 100644 --- a/mediapipe/tasks/python/test/metadata/metadata_writers/metadata_info_test.py +++ b/mediapipe/tasks/python/test/metadata/metadata_writers/metadata_info_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/metadata/metadata_writers/metadata_writer_test.py b/mediapipe/tasks/python/test/metadata/metadata_writers/metadata_writer_test.py index 846274914..f2bcb2a0f 100644 --- a/mediapipe/tasks/python/test/metadata/metadata_writers/metadata_writer_test.py +++ b/mediapipe/tasks/python/test/metadata/metadata_writers/metadata_writer_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/metadata/metadata_writers/model_asset_bundle_utils_test.py b/mediapipe/tasks/python/test/metadata/metadata_writers/model_asset_bundle_utils_test.py index e42613932..1cca04581 100644 --- a/mediapipe/tasks/python/test/metadata/metadata_writers/model_asset_bundle_utils_test.py +++ b/mediapipe/tasks/python/test/metadata/metadata_writers/model_asset_bundle_utils_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/test/metadata/metadata_writers/object_detector_test.py b/mediapipe/tasks/python/test/metadata/metadata_writers/object_detector_test.py index 195a9c8ec..89e2d67d7 100644 --- a/mediapipe/tasks/python/test/metadata/metadata_writers/object_detector_test.py +++ b/mediapipe/tasks/python/test/metadata/metadata_writers/object_detector_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/test/metadata/metadata_writers/text_classifier_test.py b/mediapipe/tasks/python/test/metadata/metadata_writers/text_classifier_test.py index b8793d965..22ca00b7d 100644 --- a/mediapipe/tasks/python/test/metadata/metadata_writers/text_classifier_test.py +++ b/mediapipe/tasks/python/test/metadata/metadata_writers/text_classifier_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/test_utils.py b/mediapipe/tasks/python/test/test_utils.py index 23ee4abe1..2dfc5a8c4 100644 --- a/mediapipe/tasks/python/test/test_utils.py +++ b/mediapipe/tasks/python/test/test_utils.py @@ -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. diff --git a/mediapipe/tasks/python/test/text/BUILD b/mediapipe/tasks/python/test/text/BUILD index 5f2d18bc5..44f584b66 100644 --- a/mediapipe/tasks/python/test/text/BUILD +++ b/mediapipe/tasks/python/test/text/BUILD @@ -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. diff --git a/mediapipe/tasks/python/test/text/__init__.py b/mediapipe/tasks/python/test/text/__init__.py index 65c1214af..3fbc1e8a7 100644 --- a/mediapipe/tasks/python/test/text/__init__.py +++ b/mediapipe/tasks/python/test/text/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/test/text/text_classifier_test.py b/mediapipe/tasks/python/test/text/text_classifier_test.py index 6fea4c6f6..c9deda7ca 100644 --- a/mediapipe/tasks/python/test/text/text_classifier_test.py +++ b/mediapipe/tasks/python/test/text/text_classifier_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/text/text_embedder_test.py b/mediapipe/tasks/python/test/text/text_embedder_test.py index 62d162f6e..27726b707 100644 --- a/mediapipe/tasks/python/test/text/text_embedder_test.py +++ b/mediapipe/tasks/python/test/text/text_embedder_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/vision/BUILD b/mediapipe/tasks/python/test/vision/BUILD index 704e1af5c..d5d7f4671 100644 --- a/mediapipe/tasks/python/test/vision/BUILD +++ b/mediapipe/tasks/python/test/vision/BUILD @@ -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. diff --git a/mediapipe/tasks/python/test/vision/__init__.py b/mediapipe/tasks/python/test/vision/__init__.py index 65c1214af..3fbc1e8a7 100644 --- a/mediapipe/tasks/python/test/vision/__init__.py +++ b/mediapipe/tasks/python/test/vision/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/test/vision/face_detector_test.py b/mediapipe/tasks/python/test/vision/face_detector_test.py index 4ae8101b7..c9246c0b1 100644 --- a/mediapipe/tasks/python/test/vision/face_detector_test.py +++ b/mediapipe/tasks/python/test/vision/face_detector_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/test/vision/face_landmarker_test.py b/mediapipe/tasks/python/test/vision/face_landmarker_test.py index 0cf16f3ea..b91999191 100644 --- a/mediapipe/tasks/python/test/vision/face_landmarker_test.py +++ b/mediapipe/tasks/python/test/vision/face_landmarker_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/test/vision/hand_landmarker_test.py b/mediapipe/tasks/python/test/vision/hand_landmarker_test.py index a7aea1cb2..1e8ebe7f2 100644 --- a/mediapipe/tasks/python/test/vision/hand_landmarker_test.py +++ b/mediapipe/tasks/python/test/vision/hand_landmarker_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/vision/image_classifier_test.py b/mediapipe/tasks/python/test/vision/image_classifier_test.py index f1bbc1285..54be34282 100644 --- a/mediapipe/tasks/python/test/vision/image_classifier_test.py +++ b/mediapipe/tasks/python/test/vision/image_classifier_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/vision/image_embedder_test.py b/mediapipe/tasks/python/test/vision/image_embedder_test.py index 8c7fb59a2..029fe15b4 100644 --- a/mediapipe/tasks/python/test/vision/image_embedder_test.py +++ b/mediapipe/tasks/python/test/vision/image_embedder_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/vision/image_segmenter_test.py b/mediapipe/tasks/python/test/vision/image_segmenter_test.py index 1a534c98d..50cb2f4ca 100644 --- a/mediapipe/tasks/python/test/vision/image_segmenter_test.py +++ b/mediapipe/tasks/python/test/vision/image_segmenter_test.py @@ -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. diff --git a/mediapipe/tasks/python/test/vision/interactive_segmenter_test.py b/mediapipe/tasks/python/test/vision/interactive_segmenter_test.py index 2e0039b15..1ebb81a71 100644 --- a/mediapipe/tasks/python/test/vision/interactive_segmenter_test.py +++ b/mediapipe/tasks/python/test/vision/interactive_segmenter_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/test/vision/object_detector_test.py b/mediapipe/tasks/python/test/vision/object_detector_test.py index 8fdd81c17..7878e7f52 100644 --- a/mediapipe/tasks/python/test/vision/object_detector_test.py +++ b/mediapipe/tasks/python/test/vision/object_detector_test.py @@ -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. diff --git a/mediapipe/tasks/python/text/BUILD b/mediapipe/tasks/python/text/BUILD index 9d5d23261..cdc41672b 100644 --- a/mediapipe/tasks/python/text/BUILD +++ b/mediapipe/tasks/python/text/BUILD @@ -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. diff --git a/mediapipe/tasks/python/text/__init__.py b/mediapipe/tasks/python/text/__init__.py index ecf3a0ad2..5aa221c33 100644 --- a/mediapipe/tasks/python/text/__init__.py +++ b/mediapipe/tasks/python/text/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/text/core/BUILD b/mediapipe/tasks/python/text/core/BUILD index e76bd4b6d..8de4c6a0d 100644 --- a/mediapipe/tasks/python/text/core/BUILD +++ b/mediapipe/tasks/python/text/core/BUILD @@ -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. diff --git a/mediapipe/tasks/python/text/core/base_text_task_api.py b/mediapipe/tasks/python/text/core/base_text_task_api.py index 1d6311561..20958e82f 100644 --- a/mediapipe/tasks/python/text/core/base_text_task_api.py +++ b/mediapipe/tasks/python/text/core/base_text_task_api.py @@ -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. diff --git a/mediapipe/tasks/python/text/text_classifier.py b/mediapipe/tasks/python/text/text_classifier.py index fdb20f0ef..7c2cd4933 100644 --- a/mediapipe/tasks/python/text/text_classifier.py +++ b/mediapipe/tasks/python/text/text_classifier.py @@ -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. diff --git a/mediapipe/tasks/python/text/text_embedder.py b/mediapipe/tasks/python/text/text_embedder.py index be899636d..b34a2e49e 100644 --- a/mediapipe/tasks/python/text/text_embedder.py +++ b/mediapipe/tasks/python/text/text_embedder.py @@ -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. diff --git a/mediapipe/tasks/python/vision/BUILD b/mediapipe/tasks/python/vision/BUILD index 716757790..733631a22 100644 --- a/mediapipe/tasks/python/vision/BUILD +++ b/mediapipe/tasks/python/vision/BUILD @@ -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. diff --git a/mediapipe/tasks/python/vision/__init__.py b/mediapipe/tasks/python/vision/__init__.py index 53cbf026e..75a8bd323 100644 --- a/mediapipe/tasks/python/vision/__init__.py +++ b/mediapipe/tasks/python/vision/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/vision/core/BUILD b/mediapipe/tasks/python/vision/core/BUILD index 18df690a0..435a3b1e5 100644 --- a/mediapipe/tasks/python/vision/core/BUILD +++ b/mediapipe/tasks/python/vision/core/BUILD @@ -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. diff --git a/mediapipe/tasks/python/vision/core/__init__.py b/mediapipe/tasks/python/vision/core/__init__.py index ad7f0fd95..701d72379 100644 --- a/mediapipe/tasks/python/vision/core/__init__.py +++ b/mediapipe/tasks/python/vision/core/__init__.py @@ -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. diff --git a/mediapipe/tasks/python/vision/core/base_vision_task_api.py b/mediapipe/tasks/python/vision/core/base_vision_task_api.py index 3775f2232..a88c6350e 100644 --- a/mediapipe/tasks/python/vision/core/base_vision_task_api.py +++ b/mediapipe/tasks/python/vision/core/base_vision_task_api.py @@ -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. diff --git a/mediapipe/tasks/python/vision/core/image_processing_options.py b/mediapipe/tasks/python/vision/core/image_processing_options.py index 9a0cd2b4d..b6dbeefed 100644 --- a/mediapipe/tasks/python/vision/core/image_processing_options.py +++ b/mediapipe/tasks/python/vision/core/image_processing_options.py @@ -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. diff --git a/mediapipe/tasks/python/vision/core/vision_task_running_mode.py b/mediapipe/tasks/python/vision/core/vision_task_running_mode.py index ba5510849..f4e96ebce 100644 --- a/mediapipe/tasks/python/vision/core/vision_task_running_mode.py +++ b/mediapipe/tasks/python/vision/core/vision_task_running_mode.py @@ -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. diff --git a/mediapipe/tasks/python/vision/face_detector.py b/mediapipe/tasks/python/vision/face_detector.py index cf09a378d..9d28123e8 100644 --- a/mediapipe/tasks/python/vision/face_detector.py +++ b/mediapipe/tasks/python/vision/face_detector.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/vision/face_landmarker.py b/mediapipe/tasks/python/vision/face_landmarker.py index c5b24499f..a6750c71c 100644 --- a/mediapipe/tasks/python/vision/face_landmarker.py +++ b/mediapipe/tasks/python/vision/face_landmarker.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/vision/face_stylizer.py b/mediapipe/tasks/python/vision/face_stylizer.py index 0b10a2b40..3fe3dd1b5 100644 --- a/mediapipe/tasks/python/vision/face_stylizer.py +++ b/mediapipe/tasks/python/vision/face_stylizer.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/vision/gesture_recognizer.py b/mediapipe/tasks/python/vision/gesture_recognizer.py index 7d480c95f..ab43408a1 100644 --- a/mediapipe/tasks/python/vision/gesture_recognizer.py +++ b/mediapipe/tasks/python/vision/gesture_recognizer.py @@ -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. diff --git a/mediapipe/tasks/python/vision/hand_landmarker.py b/mediapipe/tasks/python/vision/hand_landmarker.py index e6fcca2e2..33f72ba1f 100644 --- a/mediapipe/tasks/python/vision/hand_landmarker.py +++ b/mediapipe/tasks/python/vision/hand_landmarker.py @@ -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. diff --git a/mediapipe/tasks/python/vision/image_classifier.py b/mediapipe/tasks/python/vision/image_classifier.py index eda348fc7..1f76ba9f5 100644 --- a/mediapipe/tasks/python/vision/image_classifier.py +++ b/mediapipe/tasks/python/vision/image_classifier.py @@ -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. diff --git a/mediapipe/tasks/python/vision/image_embedder.py b/mediapipe/tasks/python/vision/image_embedder.py index 511fc3c56..def5a90a4 100644 --- a/mediapipe/tasks/python/vision/image_embedder.py +++ b/mediapipe/tasks/python/vision/image_embedder.py @@ -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. diff --git a/mediapipe/tasks/python/vision/image_segmenter.py b/mediapipe/tasks/python/vision/image_segmenter.py index 5d9af86ce..2878c9c88 100644 --- a/mediapipe/tasks/python/vision/image_segmenter.py +++ b/mediapipe/tasks/python/vision/image_segmenter.py @@ -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. diff --git a/mediapipe/tasks/python/vision/interactive_segmenter.py b/mediapipe/tasks/python/vision/interactive_segmenter.py index ad93c798c..9ee3cb467 100644 --- a/mediapipe/tasks/python/vision/interactive_segmenter.py +++ b/mediapipe/tasks/python/vision/interactive_segmenter.py @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# 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. diff --git a/mediapipe/tasks/python/vision/object_detector.py b/mediapipe/tasks/python/vision/object_detector.py index 023467234..3bdd1b5de 100644 --- a/mediapipe/tasks/python/vision/object_detector.py +++ b/mediapipe/tasks/python/vision/object_detector.py @@ -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. diff --git a/mediapipe/tasks/testdata/text/BUILD b/mediapipe/tasks/testdata/text/BUILD index 9813b6543..f1f60afdc 100644 --- a/mediapipe/tasks/testdata/text/BUILD +++ b/mediapipe/tasks/testdata/text/BUILD @@ -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. diff --git a/mediapipe/tasks/web/audio/audio_classifier/audio_classifier.ts b/mediapipe/tasks/web/audio/audio_classifier/audio_classifier.ts index 907461d01..d39964199 100644 --- a/mediapipe/tasks/web/audio/audio_classifier/audio_classifier.ts +++ b/mediapipe/tasks/web/audio/audio_classifier/audio_classifier.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_options.d.ts b/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_options.d.ts index dc3c494bf..64ca96e83 100644 --- a/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_options.d.ts +++ b/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_result.d.ts b/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_result.d.ts index 0b616126a..cb4b9bb3c 100644 --- a/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_result.d.ts +++ b/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_test.ts b/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_test.ts index b7bb158de..a0e906095 100644 --- a/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_test.ts +++ b/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/audio/audio_embedder/audio_embedder.ts b/mediapipe/tasks/web/audio/audio_embedder/audio_embedder.ts index 35531382a..afb1df640 100644 --- a/mediapipe/tasks/web/audio/audio_embedder/audio_embedder.ts +++ b/mediapipe/tasks/web/audio/audio_embedder/audio_embedder.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_options.d.ts b/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_options.d.ts index ac22728ab..07fe5865e 100644 --- a/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_options.d.ts +++ b/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_result.d.ts b/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_result.d.ts index 13abc28d9..e7ad379f3 100644 --- a/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_result.d.ts +++ b/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_test.ts b/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_test.ts index 9e37e5987..8c79ceb21 100644 --- a/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_test.ts +++ b/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/audio/core/audio_task_runner.ts b/mediapipe/tasks/web/audio/core/audio_task_runner.ts index 7462a31fa..cf3e348c8 100644 --- a/mediapipe/tasks/web/audio/core/audio_task_runner.ts +++ b/mediapipe/tasks/web/audio/core/audio_task_runner.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/audio/index.ts b/mediapipe/tasks/web/audio/index.ts index e7465878b..ef48c5d6f 100644 --- a/mediapipe/tasks/web/audio/index.ts +++ b/mediapipe/tasks/web/audio/index.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/audio/types.ts b/mediapipe/tasks/web/audio/types.ts index 19073b708..4e4e47799 100644 --- a/mediapipe/tasks/web/audio/types.ts +++ b/mediapipe/tasks/web/audio/types.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/components/containers/bounding_box.d.ts b/mediapipe/tasks/web/components/containers/bounding_box.d.ts index 69174f4c7..77f2837d1 100644 --- a/mediapipe/tasks/web/components/containers/bounding_box.d.ts +++ b/mediapipe/tasks/web/components/containers/bounding_box.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/components/containers/category.d.ts b/mediapipe/tasks/web/components/containers/category.d.ts index 8ab8e6b84..c3ca76095 100644 --- a/mediapipe/tasks/web/components/containers/category.d.ts +++ b/mediapipe/tasks/web/components/containers/category.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/components/containers/classification_result.d.ts b/mediapipe/tasks/web/components/containers/classification_result.d.ts index 30590ab43..f7294dcac 100644 --- a/mediapipe/tasks/web/components/containers/classification_result.d.ts +++ b/mediapipe/tasks/web/components/containers/classification_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/components/containers/detection_result.d.ts b/mediapipe/tasks/web/components/containers/detection_result.d.ts index 37817307c..3d0e86a0b 100644 --- a/mediapipe/tasks/web/components/containers/detection_result.d.ts +++ b/mediapipe/tasks/web/components/containers/detection_result.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/components/containers/embedding_result.d.ts b/mediapipe/tasks/web/components/containers/embedding_result.d.ts index 43d14d30e..a4b4ec203 100644 --- a/mediapipe/tasks/web/components/containers/embedding_result.d.ts +++ b/mediapipe/tasks/web/components/containers/embedding_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/components/containers/keypoint.d.ts b/mediapipe/tasks/web/components/containers/keypoint.d.ts index 3aaf9eb06..c30d36c49 100644 --- a/mediapipe/tasks/web/components/containers/keypoint.d.ts +++ b/mediapipe/tasks/web/components/containers/keypoint.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/components/containers/landmark.d.ts b/mediapipe/tasks/web/components/containers/landmark.d.ts index 0f916bf88..bb6104d89 100644 --- a/mediapipe/tasks/web/components/containers/landmark.d.ts +++ b/mediapipe/tasks/web/components/containers/landmark.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/components/containers/matrix.d.ts b/mediapipe/tasks/web/components/containers/matrix.d.ts index e0bad58c8..029ca73e7 100644 --- a/mediapipe/tasks/web/components/containers/matrix.d.ts +++ b/mediapipe/tasks/web/components/containers/matrix.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/components/containers/rect.d.ts b/mediapipe/tasks/web/components/containers/rect.d.ts index 9afece9ca..49767b510 100644 --- a/mediapipe/tasks/web/components/containers/rect.d.ts +++ b/mediapipe/tasks/web/components/containers/rect.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/components/processors/classifier_options.test.ts b/mediapipe/tasks/web/components/processors/classifier_options.test.ts index 928bda426..895d9f6d8 100644 --- a/mediapipe/tasks/web/components/processors/classifier_options.test.ts +++ b/mediapipe/tasks/web/components/processors/classifier_options.test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/components/processors/classifier_options.ts b/mediapipe/tasks/web/components/processors/classifier_options.ts index 5b8ae796e..3d30b4344 100644 --- a/mediapipe/tasks/web/components/processors/classifier_options.ts +++ b/mediapipe/tasks/web/components/processors/classifier_options.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/components/processors/classifier_result.test.ts b/mediapipe/tasks/web/components/processors/classifier_result.test.ts index 2e8f9956c..3e8b1dd1c 100644 --- a/mediapipe/tasks/web/components/processors/classifier_result.test.ts +++ b/mediapipe/tasks/web/components/processors/classifier_result.test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/components/processors/classifier_result.ts b/mediapipe/tasks/web/components/processors/classifier_result.ts index ae58252e8..03ba1ccdd 100644 --- a/mediapipe/tasks/web/components/processors/classifier_result.ts +++ b/mediapipe/tasks/web/components/processors/classifier_result.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/components/processors/detection_result.test.ts b/mediapipe/tasks/web/components/processors/detection_result.test.ts index 289043506..28b37ab0e 100644 --- a/mediapipe/tasks/web/components/processors/detection_result.test.ts +++ b/mediapipe/tasks/web/components/processors/detection_result.test.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/components/processors/detection_result.ts b/mediapipe/tasks/web/components/processors/detection_result.ts index 6b38820bf..304b51a8e 100644 --- a/mediapipe/tasks/web/components/processors/detection_result.ts +++ b/mediapipe/tasks/web/components/processors/detection_result.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/components/processors/embedder_options.test.ts b/mediapipe/tasks/web/components/processors/embedder_options.test.ts index b879a6b29..1f44f7dd0 100644 --- a/mediapipe/tasks/web/components/processors/embedder_options.test.ts +++ b/mediapipe/tasks/web/components/processors/embedder_options.test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/components/processors/embedder_options.ts b/mediapipe/tasks/web/components/processors/embedder_options.ts index f000dbd64..fa7ce98b0 100644 --- a/mediapipe/tasks/web/components/processors/embedder_options.ts +++ b/mediapipe/tasks/web/components/processors/embedder_options.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/components/processors/embedder_result.test.ts b/mediapipe/tasks/web/components/processors/embedder_result.test.ts index 97ba935c8..ef54e2d30 100644 --- a/mediapipe/tasks/web/components/processors/embedder_result.test.ts +++ b/mediapipe/tasks/web/components/processors/embedder_result.test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/components/processors/embedder_result.ts b/mediapipe/tasks/web/components/processors/embedder_result.ts index 285afe68a..b10416173 100644 --- a/mediapipe/tasks/web/components/processors/embedder_result.ts +++ b/mediapipe/tasks/web/components/processors/embedder_result.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/components/processors/landmark_result.test.ts b/mediapipe/tasks/web/components/processors/landmark_result.test.ts index 3a2635107..b0a46b3c6 100644 --- a/mediapipe/tasks/web/components/processors/landmark_result.test.ts +++ b/mediapipe/tasks/web/components/processors/landmark_result.test.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/components/processors/landmark_result.ts b/mediapipe/tasks/web/components/processors/landmark_result.ts index 3a4fa0245..9bb563384 100644 --- a/mediapipe/tasks/web/components/processors/landmark_result.ts +++ b/mediapipe/tasks/web/components/processors/landmark_result.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/components/processors/landmark_result_test_lib.ts b/mediapipe/tasks/web/components/processors/landmark_result_test_lib.ts index 318ab2f63..d06288176 100644 --- a/mediapipe/tasks/web/components/processors/landmark_result_test_lib.ts +++ b/mediapipe/tasks/web/components/processors/landmark_result_test_lib.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/components/utils/cosine_similarity.test.ts b/mediapipe/tasks/web/components/utils/cosine_similarity.test.ts index 2a82f388d..623ddaa6f 100644 --- a/mediapipe/tasks/web/components/utils/cosine_similarity.test.ts +++ b/mediapipe/tasks/web/components/utils/cosine_similarity.test.ts @@ -1,5 +1,5 @@ /** - * 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. You may obtain a diff --git a/mediapipe/tasks/web/components/utils/cosine_similarity.ts b/mediapipe/tasks/web/components/utils/cosine_similarity.ts index b512478f4..a022129a8 100644 --- a/mediapipe/tasks/web/components/utils/cosine_similarity.ts +++ b/mediapipe/tasks/web/components/utils/cosine_similarity.ts @@ -1,5 +1,5 @@ /** - * 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. You may obtain a diff --git a/mediapipe/tasks/web/core/classifier_options.d.ts b/mediapipe/tasks/web/core/classifier_options.d.ts index 08e7a7664..bd8ad6e8a 100644 --- a/mediapipe/tasks/web/core/classifier_options.d.ts +++ b/mediapipe/tasks/web/core/classifier_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/core/embedder_options.d.ts b/mediapipe/tasks/web/core/embedder_options.d.ts index 8669acfcb..cd8331b24 100644 --- a/mediapipe/tasks/web/core/embedder_options.d.ts +++ b/mediapipe/tasks/web/core/embedder_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/core/fileset_resolver.ts b/mediapipe/tasks/web/core/fileset_resolver.ts index 5c845b80c..1e13548a9 100644 --- a/mediapipe/tasks/web/core/fileset_resolver.ts +++ b/mediapipe/tasks/web/core/fileset_resolver.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/core/task_runner.ts b/mediapipe/tasks/web/core/task_runner.ts index 238564f1d..9a36b6487 100644 --- a/mediapipe/tasks/web/core/task_runner.ts +++ b/mediapipe/tasks/web/core/task_runner.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/core/task_runner_options.d.ts b/mediapipe/tasks/web/core/task_runner_options.d.ts index 5f23cd4bf..6b0960896 100644 --- a/mediapipe/tasks/web/core/task_runner_options.d.ts +++ b/mediapipe/tasks/web/core/task_runner_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/core/task_runner_test.ts b/mediapipe/tasks/web/core/task_runner_test.ts index 8c9a1a5db..873e6fea1 100644 --- a/mediapipe/tasks/web/core/task_runner_test.ts +++ b/mediapipe/tasks/web/core/task_runner_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/core/task_runner_test_utils.ts b/mediapipe/tasks/web/core/task_runner_test_utils.ts index b0aa34095..d911b2c89 100644 --- a/mediapipe/tasks/web/core/task_runner_test_utils.ts +++ b/mediapipe/tasks/web/core/task_runner_test_utils.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/core/wasm_fileset.d.ts b/mediapipe/tasks/web/core/wasm_fileset.d.ts index 18227eab9..558aa3faf 100644 --- a/mediapipe/tasks/web/core/wasm_fileset.d.ts +++ b/mediapipe/tasks/web/core/wasm_fileset.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/index.ts b/mediapipe/tasks/web/text/index.ts index 2fbdd548f..74ab2ad6b 100644 --- a/mediapipe/tasks/web/text/index.ts +++ b/mediapipe/tasks/web/text/index.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/language_detector/language_detector.ts b/mediapipe/tasks/web/text/language_detector/language_detector.ts index 13343fab3..f028b99ec 100644 --- a/mediapipe/tasks/web/text/language_detector/language_detector.ts +++ b/mediapipe/tasks/web/text/language_detector/language_detector.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/language_detector/language_detector_options.d.ts b/mediapipe/tasks/web/text/language_detector/language_detector_options.d.ts index 54b735538..422e86e29 100644 --- a/mediapipe/tasks/web/text/language_detector/language_detector_options.d.ts +++ b/mediapipe/tasks/web/text/language_detector/language_detector_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/language_detector/language_detector_result.d.ts b/mediapipe/tasks/web/text/language_detector/language_detector_result.d.ts index b21285ef4..c040e27ec 100644 --- a/mediapipe/tasks/web/text/language_detector/language_detector_result.d.ts +++ b/mediapipe/tasks/web/text/language_detector/language_detector_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/language_detector/language_detector_test.ts b/mediapipe/tasks/web/text/language_detector/language_detector_test.ts index 6e91b6662..71ab60a59 100644 --- a/mediapipe/tasks/web/text/language_detector/language_detector_test.ts +++ b/mediapipe/tasks/web/text/language_detector/language_detector_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/text_classifier/text_classifier.ts b/mediapipe/tasks/web/text/text_classifier/text_classifier.ts index e9a2940d0..1da039506 100644 --- a/mediapipe/tasks/web/text/text_classifier/text_classifier.ts +++ b/mediapipe/tasks/web/text/text_classifier/text_classifier.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/text_classifier/text_classifier_options.d.ts b/mediapipe/tasks/web/text/text_classifier/text_classifier_options.d.ts index 25592deb5..8f5c953d7 100644 --- a/mediapipe/tasks/web/text/text_classifier/text_classifier_options.d.ts +++ b/mediapipe/tasks/web/text/text_classifier/text_classifier_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/text_classifier/text_classifier_result.d.ts b/mediapipe/tasks/web/text/text_classifier/text_classifier_result.d.ts index 707ba5da2..b1215ae20 100644 --- a/mediapipe/tasks/web/text/text_classifier/text_classifier_result.d.ts +++ b/mediapipe/tasks/web/text/text_classifier/text_classifier_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/text_classifier/text_classifier_test.ts b/mediapipe/tasks/web/text/text_classifier/text_classifier_test.ts index d9eb14865..2b22c0006 100644 --- a/mediapipe/tasks/web/text/text_classifier/text_classifier_test.ts +++ b/mediapipe/tasks/web/text/text_classifier/text_classifier_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/text_embedder/text_embedder.ts b/mediapipe/tasks/web/text/text_embedder/text_embedder.ts index 66aca4a67..8bbf471d2 100644 --- a/mediapipe/tasks/web/text/text_embedder/text_embedder.ts +++ b/mediapipe/tasks/web/text/text_embedder/text_embedder.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/text_embedder/text_embedder_options.d.ts b/mediapipe/tasks/web/text/text_embedder/text_embedder_options.d.ts index 7689ee0c1..13cdc5607 100644 --- a/mediapipe/tasks/web/text/text_embedder/text_embedder_options.d.ts +++ b/mediapipe/tasks/web/text/text_embedder/text_embedder_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/text_embedder/text_embedder_result.d.ts b/mediapipe/tasks/web/text/text_embedder/text_embedder_result.d.ts index 65640b507..8a3cf54f0 100644 --- a/mediapipe/tasks/web/text/text_embedder/text_embedder_result.d.ts +++ b/mediapipe/tasks/web/text/text_embedder/text_embedder_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/text_embedder/text_embedder_test.ts b/mediapipe/tasks/web/text/text_embedder/text_embedder_test.ts index e26b85bf4..7adeeb1b0 100644 --- a/mediapipe/tasks/web/text/text_embedder/text_embedder_test.ts +++ b/mediapipe/tasks/web/text/text_embedder/text_embedder_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/text/types.ts b/mediapipe/tasks/web/text/types.ts index 9f9e48c5a..d7b5c9d96 100644 --- a/mediapipe/tasks/web/text/types.ts +++ b/mediapipe/tasks/web/text/types.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/core/drawing_utils.ts b/mediapipe/tasks/web/vision/core/drawing_utils.ts index a4013a003..e94621891 100644 --- a/mediapipe/tasks/web/vision/core/drawing_utils.ts +++ b/mediapipe/tasks/web/vision/core/drawing_utils.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/core/image.test.ts b/mediapipe/tasks/web/vision/core/image.test.ts index 7373ea385..891fafad0 100644 --- a/mediapipe/tasks/web/vision/core/image.test.ts +++ b/mediapipe/tasks/web/vision/core/image.test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index a4bbdfe1e..9059fcb78 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/core/image_processing_options.d.ts b/mediapipe/tasks/web/vision/core/image_processing_options.d.ts index b76731546..9d463591a 100644 --- a/mediapipe/tasks/web/vision/core/image_processing_options.d.ts +++ b/mediapipe/tasks/web/vision/core/image_processing_options.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/core/render_utils.ts b/mediapipe/tasks/web/vision/core/render_utils.ts index 903d789f5..13af61761 100644 --- a/mediapipe/tasks/web/vision/core/render_utils.ts +++ b/mediapipe/tasks/web/vision/core/render_utils.ts @@ -1,7 +1,7 @@ /** @fileoverview Utility functions used in the vision demos. */ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/core/types.d.ts b/mediapipe/tasks/web/vision/core/types.d.ts index 344d4db85..c43956f87 100644 --- a/mediapipe/tasks/web/vision/core/types.d.ts +++ b/mediapipe/tasks/web/vision/core/types.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/core/vision_task_options.d.ts b/mediapipe/tasks/web/vision/core/vision_task_options.d.ts index a45efd6d3..67792180c 100644 --- a/mediapipe/tasks/web/vision/core/vision_task_options.d.ts +++ b/mediapipe/tasks/web/vision/core/vision_task_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/core/vision_task_runner.test.ts b/mediapipe/tasks/web/vision/core/vision_task_runner.test.ts index f45035b6b..c8be900ca 100644 --- a/mediapipe/tasks/web/vision/core/vision_task_runner.test.ts +++ b/mediapipe/tasks/web/vision/core/vision_task_runner.test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/core/vision_task_runner.ts b/mediapipe/tasks/web/vision/core/vision_task_runner.ts index b815a24d2..a79cee559 100644 --- a/mediapipe/tasks/web/vision/core/vision_task_runner.ts +++ b/mediapipe/tasks/web/vision/core/vision_task_runner.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/face_detector/face_detector.ts b/mediapipe/tasks/web/vision/face_detector/face_detector.ts index 039f7dd44..d9a69037f 100644 --- a/mediapipe/tasks/web/vision/face_detector/face_detector.ts +++ b/mediapipe/tasks/web/vision/face_detector/face_detector.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/face_detector/face_detector_options.d.ts b/mediapipe/tasks/web/vision/face_detector/face_detector_options.d.ts index 665035f7e..d2539ecb5 100644 --- a/mediapipe/tasks/web/vision/face_detector/face_detector_options.d.ts +++ b/mediapipe/tasks/web/vision/face_detector/face_detector_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/face_detector/face_detector_result.d.ts b/mediapipe/tasks/web/vision/face_detector/face_detector_result.d.ts index 6a36559f7..5e52bb988 100644 --- a/mediapipe/tasks/web/vision/face_detector/face_detector_result.d.ts +++ b/mediapipe/tasks/web/vision/face_detector/face_detector_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/face_detector/face_detector_test.ts b/mediapipe/tasks/web/vision/face_detector/face_detector_test.ts index 88dd20d2b..9f9d00732 100644 --- a/mediapipe/tasks/web/vision/face_detector/face_detector_test.ts +++ b/mediapipe/tasks/web/vision/face_detector/face_detector_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts index 2a30f0606..c0122da28 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts +++ b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_options.d.ts b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_options.d.ts index f537ca2f6..67739b895 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_options.d.ts +++ b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_options.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_result.d.ts b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_result.d.ts index 123c0a82a..4bbe3b0c9 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_result.d.ts +++ b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_result.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_test.ts b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_test.ts index b590b4a4a..b6f16a721 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_test.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/face_landmarker/face_landmarks_connections.ts b/mediapipe/tasks/web/vision/face_landmarker/face_landmarks_connections.ts index 337f663e3..9bd4b1b92 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/face_landmarks_connections.ts +++ b/mediapipe/tasks/web/vision/face_landmarker/face_landmarks_connections.ts @@ -1,5 +1,5 @@ /** - * CopyRIGHT 2023 The MediaPipe Authors. All RIGHTs Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts index dfce03030..c7c04a40c 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_options.d.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_options.d.ts index 38f5028c0..73942badc 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_options.d.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts index 72d540797..b042ebac5 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer.ts b/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer.ts index df9c91282..806a794f8 100644 --- a/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer.ts +++ b/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_options.d.ts b/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_options.d.ts index 9e9728af8..3a5b0b5d7 100644 --- a/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_options.d.ts +++ b/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_result.d.ts b/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_result.d.ts index 323290008..f3dadf413 100644 --- a/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_result.d.ts +++ b/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_test.ts b/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_test.ts index 2331f5e21..4b064500e 100644 --- a/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_test.ts +++ b/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmark.d.ts b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmark.d.ts index ca2543f78..37d3c7470 100644 --- a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmark.d.ts +++ b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmark.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker.ts b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker.ts index 2d2d05f9f..6def4fb86 100644 --- a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker.ts +++ b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_options.d.ts b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_options.d.ts index fe79b7089..2fde24bef 100644 --- a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_options.d.ts +++ b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_result.d.ts b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_result.d.ts index dc0f2fe0f..69bf6a78f 100644 --- a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_result.d.ts +++ b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_test.ts b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_test.ts index f439e66e6..7499444f4 100644 --- a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarks_connections.ts b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarks_connections.ts index edb789c8f..c5195ef3a 100644 --- a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarks_connections.ts +++ b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarks_connections.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/image_classifier/image_classifier.ts b/mediapipe/tasks/web/vision/image_classifier/image_classifier.ts index 5cd690816..60a097c65 100644 --- a/mediapipe/tasks/web/vision/image_classifier/image_classifier.ts +++ b/mediapipe/tasks/web/vision/image_classifier/image_classifier.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/image_classifier/image_classifier_options.d.ts b/mediapipe/tasks/web/vision/image_classifier/image_classifier_options.d.ts index e99dd2b69..b3f37764b 100644 --- a/mediapipe/tasks/web/vision/image_classifier/image_classifier_options.d.ts +++ b/mediapipe/tasks/web/vision/image_classifier/image_classifier_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/image_classifier/image_classifier_result.d.ts b/mediapipe/tasks/web/vision/image_classifier/image_classifier_result.d.ts index 44032234c..3a30a93b9 100644 --- a/mediapipe/tasks/web/vision/image_classifier/image_classifier_result.d.ts +++ b/mediapipe/tasks/web/vision/image_classifier/image_classifier_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/image_classifier/image_classifier_test.ts b/mediapipe/tasks/web/vision/image_classifier/image_classifier_test.ts index 7058e2a5b..40e50c531 100644 --- a/mediapipe/tasks/web/vision/image_classifier/image_classifier_test.ts +++ b/mediapipe/tasks/web/vision/image_classifier/image_classifier_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/image_embedder/image_embedder.ts b/mediapipe/tasks/web/vision/image_embedder/image_embedder.ts index 229647e47..7900746a2 100644 --- a/mediapipe/tasks/web/vision/image_embedder/image_embedder.ts +++ b/mediapipe/tasks/web/vision/image_embedder/image_embedder.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/image_embedder/image_embedder_options.d.ts b/mediapipe/tasks/web/vision/image_embedder/image_embedder_options.d.ts index 8a04be5e1..b43af6bea 100644 --- a/mediapipe/tasks/web/vision/image_embedder/image_embedder_options.d.ts +++ b/mediapipe/tasks/web/vision/image_embedder/image_embedder_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/image_embedder/image_embedder_result.d.ts b/mediapipe/tasks/web/vision/image_embedder/image_embedder_result.d.ts index 156636505..ee7c7092d 100644 --- a/mediapipe/tasks/web/vision/image_embedder/image_embedder_result.d.ts +++ b/mediapipe/tasks/web/vision/image_embedder/image_embedder_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/image_embedder/image_embedder_test.ts b/mediapipe/tasks/web/vision/image_embedder/image_embedder_test.ts index 5a8293c44..7dc0c32ef 100644 --- a/mediapipe/tasks/web/vision/image_embedder/image_embedder_test.ts +++ b/mediapipe/tasks/web/vision/image_embedder/image_embedder_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts index c32423e12..4089a2b17 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.d.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.d.ts index f80a792a5..5e7fe7a45 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.d.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts index be082d516..b731e032d 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts index 6b5c90080..f7d1f1f87 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/index.ts b/mediapipe/tasks/web/vision/index.ts index 6a3de450e..2ea0e7278 100644 --- a/mediapipe/tasks/web/vision/index.ts +++ b/mediapipe/tasks/web/vision/index.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts index df00b2cee..70d2c1f4e 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.d.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.d.ts index 269403d97..952a5190a 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.d.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts index f7e1f3a19..f1f134a77 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts index 884be032d..3e108309d 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/object_detector/object_detector.ts b/mediapipe/tasks/web/vision/object_detector/object_detector.ts index 5d406f1a0..7bfcc0f0b 100644 --- a/mediapipe/tasks/web/vision/object_detector/object_detector.ts +++ b/mediapipe/tasks/web/vision/object_detector/object_detector.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/object_detector/object_detector_options.d.ts b/mediapipe/tasks/web/vision/object_detector/object_detector_options.d.ts index 7564e7760..d0ead197d 100644 --- a/mediapipe/tasks/web/vision/object_detector/object_detector_options.d.ts +++ b/mediapipe/tasks/web/vision/object_detector/object_detector_options.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/object_detector/object_detector_result.d.ts b/mediapipe/tasks/web/vision/object_detector/object_detector_result.d.ts index 54bc6f907..531fef592 100644 --- a/mediapipe/tasks/web/vision/object_detector/object_detector_result.d.ts +++ b/mediapipe/tasks/web/vision/object_detector/object_detector_result.d.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/object_detector/object_detector_test.ts b/mediapipe/tasks/web/vision/object_detector/object_detector_test.ts index 18e4a2062..a9d951e94 100644 --- a/mediapipe/tasks/web/vision/object_detector/object_detector_test.ts +++ b/mediapipe/tasks/web/vision/object_detector/object_detector_test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts index a3c0450fe..0b119780c 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.d.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.d.ts index 46f96e6d8..fdd29c6ac 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.d.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts index 7bfca807b..4ddd085df 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts index 1862cc433..1a5afba50 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/tasks/web/vision/types.ts b/mediapipe/tasks/web/vision/types.ts index f818b46a6..1c0466bc1 100644 --- a/mediapipe/tasks/web/vision/types.ts +++ b/mediapipe/tasks/web/vision/types.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/mediapipe/util/tflite/operations/max_pool_argmax.cc b/mediapipe/util/tflite/operations/max_pool_argmax.cc index c55c16f5d..71d08e127 100644 --- a/mediapipe/util/tflite/operations/max_pool_argmax.cc +++ b/mediapipe/util/tflite/operations/max_pool_argmax.cc @@ -1,4 +1,4 @@ -// Copyright 2018 The TensorFlow Authors. All Rights Reserved. +// Copyright 2018 The TensorFlow Authors. // Copyright 2019 The MediaPipe Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/mediapipe/util/tflite/operations/transpose_conv_bias.cc b/mediapipe/util/tflite/operations/transpose_conv_bias.cc index 1fe5acd74..32b7c400e 100644 --- a/mediapipe/util/tflite/operations/transpose_conv_bias.cc +++ b/mediapipe/util/tflite/operations/transpose_conv_bias.cc @@ -1,4 +1,4 @@ -// Copyright 2018 The TensorFlow Authors. All Rights Reserved. +// Copyright 2018 The TensorFlow Authors. // Copyright 2019 The MediaPipe Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/mediapipe/web/graph_runner/platform_utils.test.ts b/mediapipe/web/graph_runner/platform_utils.test.ts index 080260cfe..89325b899 100644 --- a/mediapipe/web/graph_runner/platform_utils.test.ts +++ b/mediapipe/web/graph_runner/platform_utils.test.ts @@ -1,5 +1,5 @@ /** - * 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. diff --git a/mediapipe/web/graph_runner/platform_utils.ts b/mediapipe/web/graph_runner/platform_utils.ts index 59359a14f..71239abab 100644 --- a/mediapipe/web/graph_runner/platform_utils.ts +++ b/mediapipe/web/graph_runner/platform_utils.ts @@ -1,5 +1,5 @@ /** - * Copyright 2023 The MediaPipe Authors. All Rights Reserved. + * 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. diff --git a/setup.py b/setup.py index c94f14aff..202917ef2 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -"""Copyright 2020-2022 The MediaPipe Authors. All Rights Reserved. +"""Copyright 2020-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. diff --git a/third_party/halide/halide.bzl b/third_party/halide/halide.bzl index f1e8b5375..bbb0a1f97 100644 --- a/third_party/halide/halide.bzl +++ b/third_party/halide/halide.bzl @@ -1,4 +1,4 @@ -# Copyright 2023 The MediaPipe Authors. All rights reserved. +# 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. diff --git a/third_party/repo.bzl b/third_party/repo.bzl index ca9e4a807..691905549 100644 --- a/third_party/repo.bzl +++ b/third_party/repo.bzl @@ -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. From 9e30b00685fa8c39c9a2ee20ec47b119ce6ac2b0 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Tue, 25 Apr 2023 10:32:49 -0700 Subject: [PATCH 081/753] Invoke the FaceStylizer callback even if no faces are detected PiperOrigin-RevId: 527008261 --- mediapipe/tasks/web/vision/core/types.d.ts | 10 ------ .../web/vision/face_stylizer/face_stylizer.ts | 32 ++++++++++++------- .../face_stylizer/face_stylizer_test.ts | 24 ++++++++++++++ 3 files changed, 45 insertions(+), 21 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/types.d.ts b/mediapipe/tasks/web/vision/core/types.d.ts index c43956f87..1cc2e36fd 100644 --- a/mediapipe/tasks/web/vision/core/types.d.ts +++ b/mediapipe/tasks/web/vision/core/types.d.ts @@ -25,16 +25,6 @@ import {NormalizedKeypoint} from '../../../../tasks/web/components/containers/ke */ export type SegmentationMask = Uint8ClampedArray|Float32Array|WebGLTexture; -/** - * A callback that receives an `ImageData` object from a Vision task. The - * lifetime of the underlying data is limited to the duration of the callback. - * If asynchronous processing is needed, all data needs to be copied before the - * callback returns. - * - * The `WebGLTexture` output type is reserved for future usage. - */ -export type ImageCallback = - (image: ImageData|WebGLTexture, width: number, height: number) => void; /** A Region-Of-Interest (ROI) to represent a region within an image. */ export declare interface RegionOfInterest { diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts index c7c04a40c..13558e235 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts @@ -20,7 +20,6 @@ import {BaseOptions as BaseOptionsProto} from '../../../../tasks/cc/core/proto/b import {FaceStylizerGraphOptions as FaceStylizerGraphOptionsProto} from '../../../../tasks/cc/vision/face_stylizer/proto/face_stylizer_graph_options_pb'; import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; -import {ImageCallback} from '../../../../tasks/web/vision/core/types'; import {VisionGraphRunner, VisionTaskRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; import {ImageSource, WasmModule} from '../../../../web/graph_runner/graph_runner'; // Placeholder for internal dependency on trusted resource url @@ -39,11 +38,20 @@ const FACE_STYLIZER_GRAPH = // The OSS JS API does not support the builder pattern. // tslint:disable:jspb-use-builder-pattern -export {ImageCallback}; +/** + * A callback that receives an image from the face stylizer, or `null` if no + * face was detected. The lifetime of the underlying data is limited to the + * duration of the callback. If asynchronous processing is needed, all data + * needs to be copied before the callback returns. + * + * The `WebGLTexture` output type is reserved for future usage. + */ +export type FaceStylizerCallback = + (image: ImageData|WebGLTexture|null, width: number, height: number) => void; /** Performs face stylization on images. */ export class FaceStylizer extends VisionTaskRunner { - private userCallback: ImageCallback = () => {}; + private userCallback: FaceStylizerCallback = () => {}; private readonly options: FaceStylizerGraphOptionsProto; /** @@ -134,7 +142,7 @@ export class FaceStylizer extends VisionTaskRunner { * lifetime of the returned data is only guaranteed for the duration of the * callback. */ - stylize(image: ImageSource, callback: ImageCallback): void; + stylize(image: ImageSource, callback: FaceStylizerCallback): void; /** * Performs face stylization on the provided single image. The method returns * synchronously once the callback returns. Only use this method when the @@ -158,11 +166,12 @@ export class FaceStylizer extends VisionTaskRunner { */ stylize( image: ImageSource, imageProcessingOptions: ImageProcessingOptions, - callback: ImageCallback): void; + callback: FaceStylizerCallback): void; stylize( image: ImageSource, - imageProcessingOptionsOrCallback: ImageProcessingOptions|ImageCallback, - callback?: ImageCallback): void { + imageProcessingOptionsOrCallback: ImageProcessingOptions| + FaceStylizerCallback, + callback?: FaceStylizerCallback): void { const imageProcessingOptions = typeof imageProcessingOptionsOrCallback !== 'function' ? imageProcessingOptionsOrCallback : @@ -191,7 +200,7 @@ export class FaceStylizer extends VisionTaskRunner { */ stylizeForVideo( videoFrame: ImageSource, timestamp: number, - callback: ImageCallback): void; + callback: FaceStylizerCallback): void; /** * Performs face stylization on the provided video frame. Only use this * method when the FaceStylizer is created with the video running mode. @@ -219,12 +228,12 @@ export class FaceStylizer extends VisionTaskRunner { */ stylizeForVideo( videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, - timestamp: number, callback: ImageCallback): void; + timestamp: number, callback: FaceStylizerCallback): void; stylizeForVideo( videoFrame: ImageSource, timestampOrImageProcessingOptions: number|ImageProcessingOptions, - timestampOrCallback: number|ImageCallback, - callback?: ImageCallback): void { + timestampOrCallback: number|FaceStylizerCallback, + callback?: FaceStylizerCallback): void { const imageProcessingOptions = typeof timestampOrImageProcessingOptions !== 'number' ? timestampOrImageProcessingOptions : @@ -272,6 +281,7 @@ export class FaceStylizer extends VisionTaskRunner { }); this.graphRunner.attachEmptyPacketListener( STYLIZED_IMAGE_STREAM, timestamp => { + this.userCallback(null, /* width= */ 0, /* height= */ 0); this.setLatestOutputTimestamp(timestamp); }); diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts index b042ebac5..3ef35728d 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts @@ -30,6 +30,7 @@ class FaceStylizerFake extends FaceStylizer implements MediapipeTasksFake { fakeWasmModule: SpyWasmModule; imageListener: ((images: WasmImage, timestamp: number) => void)|undefined; + emptyPacketListener: ((timestamp: number) => void)|undefined; constructor() { super(createSpyWasmModule(), /* glCanvas= */ null); @@ -42,6 +43,12 @@ class FaceStylizerFake extends FaceStylizer implements MediapipeTasksFake { expect(stream).toEqual('stylized_image'); this.imageListener = listener; }); + this.attachListenerSpies[1] = + spyOn(this.graphRunner, 'attachEmptyPacketListener') + .and.callFake((stream, listener) => { + expect(stream).toEqual('stylized_image'); + this.emptyPacketListener = listener; + }); spyOn(this.graphRunner, 'setGraph').and.callFake(binaryGraph => { this.graph = CalculatorGraphConfig.deserializeBinary(binaryGraph); }); @@ -111,4 +118,21 @@ describe('FaceStylizer', () => { done(); }); }); + + it('invokes callback even when no faes are detected', (done) => { + // Pass the test data to our listener + faceStylizer.fakeWasmModule._waitUntilIdle.and.callFake(() => { + verifyListenersRegistered(faceStylizer); + faceStylizer.emptyPacketListener!(/* timestamp= */ 1337); + }); + + // Invoke the face stylizeer + faceStylizer.stylize({} as HTMLImageElement, (image, width, height) => { + expect(faceStylizer.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); + expect(image).toBeNull(); + expect(width).toEqual(0); + expect(height).toEqual(0); + done(); + }); + }); }); From 17f5b95387e1f77b5ba468ed67d6c8cfa591b0ef Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 25 Apr 2023 10:39:36 -0700 Subject: [PATCH 082/753] Internal change. PiperOrigin-RevId: 527010360 --- docs/framework_concepts/graphs.md | 2 +- mediapipe/framework/api2/contract.h | 2 +- mediapipe/framework/calculator_base.h | 2 +- mediapipe/framework/calculator_context.h | 2 +- mediapipe/framework/calculator_runner.h | 2 +- mediapipe/framework/output_side_packet.h | 2 +- mediapipe/framework/output_side_packet_impl.h | 2 +- mediapipe/framework/output_stream.h | 2 +- mediapipe/framework/scheduler_queue.h | 2 +- .../calculators/tracked_anchor_manager_calculator.cc | 2 +- .../com/google/mediapipe/glutil/ExternalTextureRenderer.java | 2 +- mediapipe/tasks/cc/text/tokenizers/BUILD | 5 ++++- .../calculators/segmentation_postprocessor_gl.cc | 2 +- mediapipe/util/tracking/box_tracker.h | 4 ++-- 14 files changed, 18 insertions(+), 15 deletions(-) diff --git a/docs/framework_concepts/graphs.md b/docs/framework_concepts/graphs.md index 5f9c68e08..23e20d052 100644 --- a/docs/framework_concepts/graphs.md +++ b/docs/framework_concepts/graphs.md @@ -273,7 +273,7 @@ defined in the enclosing protobuf in order to be traversed using ## Cycles - + By default, MediaPipe requires calculator graphs to be acyclic and treats cycles in a graph as errors. If a graph is intended to have cycles, the cycles need to diff --git a/mediapipe/framework/api2/contract.h b/mediapipe/framework/api2/contract.h index 90e4c38cd..9b92212cb 100644 --- a/mediapipe/framework/api2/contract.h +++ b/mediapipe/framework/api2/contract.h @@ -164,7 +164,7 @@ class Contract { std::tuple items; - // TODO: when forwarding nested items (e.g. ports), check for conflicts. + // TODO -, check for conflicts. decltype(ExtractNestedItems(items)) all_items{ExtractNestedItems(items)}; constexpr auto inputs() const { diff --git a/mediapipe/framework/calculator_base.h b/mediapipe/framework/calculator_base.h index 19f37f9de..4bd3d7398 100644 --- a/mediapipe/framework/calculator_base.h +++ b/mediapipe/framework/calculator_base.h @@ -150,7 +150,7 @@ class CalculatorBase { // Packets may be output during a call to Close(). However, output packets // are silently discarded if Close() is called after a graph run has ended. // - // NOTE: If Close() needs to perform an action only when processing is + // NOTE - needs to perform an action only when processing is // complete, Close() must check if cc->GraphStatus() is OK. virtual absl::Status Close(CalculatorContext* cc) { return absl::OkStatus(); } diff --git a/mediapipe/framework/calculator_context.h b/mediapipe/framework/calculator_context.h index 284226d92..4eafea79f 100644 --- a/mediapipe/framework/calculator_context.h +++ b/mediapipe/framework/calculator_context.h @@ -111,7 +111,7 @@ class CalculatorContext { // Returns the status of the graph run. // - // NOTE: This method should only be called during CalculatorBase::Close(). + // NOTE -. absl::Status GraphStatus() const { return graph_status_; } ProfilingContext* GetProfilingContext() const { diff --git a/mediapipe/framework/calculator_runner.h b/mediapipe/framework/calculator_runner.h index fb1020de1..350fb535c 100644 --- a/mediapipe/framework/calculator_runner.h +++ b/mediapipe/framework/calculator_runner.h @@ -66,7 +66,7 @@ class CalculatorRunner { explicit CalculatorRunner(const std::string& node_config_string); // Convenience constructor to initialize a calculator which uses indexes // (not tags) for all its fields. - // NOTE: This constructor calls proto_ns::TextFormat::ParseFromString(), which + // NOTE -, which // is not available when using lite protos. CalculatorRunner(const std::string& calculator_type, const std::string& options_string, int num_inputs, diff --git a/mediapipe/framework/output_side_packet.h b/mediapipe/framework/output_side_packet.h index 9a0c8cbd2..44eb07085 100644 --- a/mediapipe/framework/output_side_packet.h +++ b/mediapipe/framework/output_side_packet.h @@ -30,7 +30,7 @@ class OutputSidePacket { // Sets the output side packet. The Packet must contain the data. // - // NOTE: Set() cannot report errors via the return value. It uses an error + // NOTE - cannot report errors via the return value. It uses an error // callback function to report errors. virtual void Set(const Packet& packet) = 0; }; diff --git a/mediapipe/framework/output_side_packet_impl.h b/mediapipe/framework/output_side_packet_impl.h index 7e7d639cd..7b16eb32b 100644 --- a/mediapipe/framework/output_side_packet_impl.h +++ b/mediapipe/framework/output_side_packet_impl.h @@ -48,7 +48,7 @@ class OutputSidePacketImpl : public OutputSidePacket { // Sets the output side packet. The Packet must contain the data. // - // NOTE: Set() cannot report errors via the return value. It uses an error + // NOTE - cannot report errors via the return value. It uses an error // callback function to report errors. void Set(const Packet& packet) override; diff --git a/mediapipe/framework/output_stream.h b/mediapipe/framework/output_stream.h index 191c26fd7..55679066d 100644 --- a/mediapipe/framework/output_stream.h +++ b/mediapipe/framework/output_stream.h @@ -50,7 +50,7 @@ class OutputStream { // the only packet in the stream. // Violation of any of these conditions causes a CHECK-failure. // - // NOTE: AddPacket() cannot report errors via the return value. Instead of a + // NOTE - cannot report errors via the return value. Instead of a // CHECK-failure, a subclass of OutputStream should use a callback function // to report errors. virtual void AddPacket(const Packet& packet) = 0; diff --git a/mediapipe/framework/scheduler_queue.h b/mediapipe/framework/scheduler_queue.h index f6777f42b..345da7dc2 100644 --- a/mediapipe/framework/scheduler_queue.h +++ b/mediapipe/framework/scheduler_queue.h @@ -102,7 +102,7 @@ class SchedulerQueue : public TaskQueue { // Implements the TaskQueue interface. void RunNextTask() override; - // NOTE: After calling SetRunning(true), the caller must call + // NOTE -, the caller must call // SubmitWaitingTasksToExecutor since tasks may have been added while the // queue was not running. void SetRunning(bool running) ABSL_LOCKS_EXCLUDED(mutex_); diff --git a/mediapipe/graphs/instant_motion_tracking/calculators/tracked_anchor_manager_calculator.cc b/mediapipe/graphs/instant_motion_tracking/calculators/tracked_anchor_manager_calculator.cc index 446aee781..9468b901e 100644 --- a/mediapipe/graphs/instant_motion_tracking/calculators/tracked_anchor_manager_calculator.cc +++ b/mediapipe/graphs/instant_motion_tracking/calculators/tracked_anchor_manager_calculator.cc @@ -25,7 +25,7 @@ constexpr char kAnchorsTag[] = "ANCHORS"; constexpr char kBoxesInputTag[] = "BOXES"; constexpr char kBoxesOutputTag[] = "START_POS"; constexpr char kCancelTag[] = "CANCEL_ID"; -// TODO: Find optimal Height/Width (0.1-0.3) +// TODO - constexpr float kBoxEdgeSize = 0.2f; // Used to establish tracking box dimensions constexpr float kUsToMs = diff --git a/mediapipe/java/com/google/mediapipe/glutil/ExternalTextureRenderer.java b/mediapipe/java/com/google/mediapipe/glutil/ExternalTextureRenderer.java index 4dd35f865..2dc6112a3 100644 --- a/mediapipe/java/com/google/mediapipe/glutil/ExternalTextureRenderer.java +++ b/mediapipe/java/com/google/mediapipe/glutil/ExternalTextureRenderer.java @@ -106,7 +106,7 @@ public class ExternalTextureRenderer { * *

Before calling this, {@link #setup} must have been called. * - *

NOTE: Calls {@link SurfaceTexture#updateTexImage()} on passed surface texture. + *

NOTE -} on passed surface texture. */ public void render(SurfaceTexture surfaceTexture) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); diff --git a/mediapipe/tasks/cc/text/tokenizers/BUILD b/mediapipe/tasks/cc/text/tokenizers/BUILD index a55f91316..01908cd2c 100644 --- a/mediapipe/tasks/cc/text/tokenizers/BUILD +++ b/mediapipe/tasks/cc/text/tokenizers/BUILD @@ -12,7 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -package(default_visibility = ["//mediapipe/calculators/tensor:__subpackages__"]) +default_visibility = ["//mediapipe/calculators/tensor:__subpackages__"] + +package(default_visibility = default_visibility) licenses(["notice"]) @@ -34,6 +36,7 @@ cc_library( hdrs = [ "bert_tokenizer.h", ], + visibility = default_visibility + ["//mediapipe/tasks:users"], deps = [ ":tokenizer", "//mediapipe/framework/port:integral_types", diff --git a/mediapipe/tasks/cc/vision/image_segmenter/calculators/segmentation_postprocessor_gl.cc b/mediapipe/tasks/cc/vision/image_segmenter/calculators/segmentation_postprocessor_gl.cc index 5b212069f..96451617f 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/calculators/segmentation_postprocessor_gl.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/calculators/segmentation_postprocessor_gl.cc @@ -581,7 +581,7 @@ SegmentationPostprocessorGl::GetSegmentationResultGpu( // Step 2.5: For SOFTMAX, apply softmax shaders (max, transformAndSum, and // normalization) to create softmax-transformed chunks before channel // extraction. - // NOTE: exp(x-C) / sum_over_x(exp(x-C)) = exp(x) / sum_over_x(exp(x)). So + // NOTE - / sum_over_x(exp(x-C)) = exp(x) / sum_over_x(exp(x)). So // theoretically we can skip the max shader step entirely. However, // applying it does bring all our values into a nice (0, 1] range, so it // will likely be better for precision, especially when dealing with an diff --git a/mediapipe/util/tracking/box_tracker.h b/mediapipe/util/tracking/box_tracker.h index 8654e97fd..31ac5c117 100644 --- a/mediapipe/util/tracking/box_tracker.h +++ b/mediapipe/util/tracking/box_tracker.h @@ -200,7 +200,7 @@ class BoxTracker { // Cancels all ongoing tracks. To avoid race conditions all NewBoxTrack's in // flight will also be canceled. Future NewBoxTrack's will be canceled. - // NOTE: To resume execution, you have to call ResumeTracking() before + // NOTE - before // issuing more NewBoxTrack calls. void CancelAllOngoingTracks() ABSL_LOCKS_EXCLUDED(status_mutex_); void ResumeTracking() ABSL_LOCKS_EXCLUDED(status_mutex_); @@ -208,7 +208,7 @@ class BoxTracker { // Waits for all ongoing tracks to complete. // Optionally accepts a timeout in microseconds (== 0 for infinite wait). // Returns true on success, false if timeout is reached. - // NOTE: If WaitForAllOngoingTracks timed out, CancelAllOngoingTracks() must + // NOTE - must // be called before destructing the BoxTracker object or dangeling running // threads might try to access invalid data. bool WaitForAllOngoingTracks(int timeout_us = 0) From 507ed0d91de4d82fbc6053e510c42514f2307221 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 25 Apr 2023 14:56:38 -0700 Subject: [PATCH 083/753] Add custom metadata for object detection model with out-of-graph nms. PiperOrigin-RevId: 527083453 --- .../vision/object_detector/object_detector.py | 2 +- mediapipe/tasks/metadata/BUILD | 10 + .../object_detector_metadata_schema.fbs | 98 + .../python/metadata/metadata_writers/BUILD | 10 +- .../metadata_writers/metadata_info.py | 79 + .../metadata_writers/metadata_writer.py | 29 +- .../metadata_writers/object_detector.py | 268 +- .../test/metadata/metadata_writers/BUILD | 1 + .../metadata_writers/object_detector_test.py | 73 +- mediapipe/tasks/testdata/metadata/BUILD | 6 +- ...co_ssd_mobilenet_v1_score_calibration.json | 21 +- ...efficientdet_lite0_fp16_no_nms_anchors.csv | 19206 ++++++++++++++++ .../metadata/efficientdet_lite0_v1.json | 21 +- .../ssd_mobilenet_v1_no_metadata.json | 21 +- third_party/external_files.bzl | 30 +- 15 files changed, 19798 insertions(+), 77 deletions(-) create mode 100644 mediapipe/tasks/metadata/object_detector_metadata_schema.fbs create mode 100644 mediapipe/tasks/testdata/metadata/efficientdet_lite0_fp16_no_nms_anchors.csv diff --git a/mediapipe/model_maker/python/vision/object_detector/object_detector.py b/mediapipe/model_maker/python/vision/object_detector/object_detector.py index 1282e1a16..d208a9b28 100644 --- a/mediapipe/model_maker/python/vision/object_detector/object_detector.py +++ b/mediapipe/model_maker/python/vision/object_detector/object_detector.py @@ -328,7 +328,7 @@ class ObjectDetector(classifier.Classifier): converter.target_spec.supported_ops = (tf.lite.OpsSet.TFLITE_BUILTINS,) tflite_model = converter.convert() - writer = object_detector_writer.MetadataWriter.create( + writer = object_detector_writer.MetadataWriter.create_for_models_with_nms( tflite_model, self._model_spec.mean_rgb, self._model_spec.stddev_rgb, diff --git a/mediapipe/tasks/metadata/BUILD b/mediapipe/tasks/metadata/BUILD index de6350685..38960c8db 100644 --- a/mediapipe/tasks/metadata/BUILD +++ b/mediapipe/tasks/metadata/BUILD @@ -36,3 +36,13 @@ flatbuffer_py_library( name = "image_segmenter_metadata_schema_py", srcs = ["image_segmenter_metadata_schema.fbs"], ) + +flatbuffer_cc_library( + name = "object_detector_metadata_schema_cc", + srcs = ["object_detector_metadata_schema.fbs"], +) + +flatbuffer_py_library( + name = "object_detector_metadata_schema_py", + srcs = ["object_detector_metadata_schema.fbs"], +) diff --git a/mediapipe/tasks/metadata/object_detector_metadata_schema.fbs b/mediapipe/tasks/metadata/object_detector_metadata_schema.fbs new file mode 100644 index 000000000..30e0f9127 --- /dev/null +++ b/mediapipe/tasks/metadata/object_detector_metadata_schema.fbs @@ -0,0 +1,98 @@ +// Copyright 2023 The MediaPipe Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace mediapipe.tasks; + +// ObjectDetectorOptions.min_parser_version indicates the minimum necessary +// object detector metadata parser version to fully understand all fields in a +// given metadata flatbuffer. This min_parser_version is specific for the +// object detector metadata defined in this schema file. +// +// New fields and types will have associated comments with the schema version +// for which they were added. +// +// Schema Semantic version: 1.0.0 + +// This indicates the flatbuffer compatibility. The number will bump up when a +// break change is applied to the schema, such as removing fields or adding new +// fields to the middle of a table. +file_identifier "V001"; + + +// History: +// 1.0.0 - Initial version. + +// A fixed size anchor. +table FixedAnchor { + x_center: float; + y_center: float; + width: float; + height: float; +} + +// The schema for a list of anchors with fixed size. +table FixedAnchorsSchema { + anchors: [FixedAnchor]; +} + +// The ssd anchors options used in the object detector. +table SsdAnchorsOptions { + fixed_anchors_schema: FixedAnchorsSchema; +} + +// The options for decoding the raw model output tensors. The options are mostly +// used in TensorsToDetectionsCalculatorOptions. +table TensorsDecodingOptions { + // The number of output classes predicted by the detection model. + num_classes: int; + // The number of output boxes predicted by the detection model. + num_boxes: int; + // The number of output values per boxes predicted by the detection + // model. The values contain bounding boxes, keypoints, etc. + num_coords: int; + // The offset of keypoint coordinates in the location tensor. + keypoint_coord_offset: int; + // The number of predicted keypoints. + num_keypoints: int; + // The dimension of each keypoint, e.g. number of values predicted for each + // keypoint. + num_values_per_keypoint: int; + // Parameters for decoding SSD detection model. + x_scale: float; + y_scale: float; + w_scale: float; + h_scale: float; + // Whether to apply exponential on box size. + apply_exponential_on_box_size: bool; + // Whether to apply sigmod function on the score. + sigmoid_score: bool; +} + +table ObjectDetectorOptions { + // TODO: automatically populate min parser string. + // The minimum necessary object detector metadata parser version to fully + // understand all fields in a given metadata flatbuffer. This field is + // automatically populated by the MetadataPopulator when the metadata is + // populated into a TFLite model. This min_parser_version is specific for the + // object detector metadata defined in this schema file. + min_parser_version:string; + + // The options of ssd anchors configs used by the detection model. + ssd_anchors_options:SsdAnchorsOptions; + + // The tensors decoding options to convert raw tensors to detection results. + tensors_decoding_options:TensorsDecodingOptions; +} + +root_type ObjectDetectorOptions; diff --git a/mediapipe/tasks/python/metadata/metadata_writers/BUILD b/mediapipe/tasks/python/metadata/metadata_writers/BUILD index 1f126c30b..f7db16682 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/BUILD +++ b/mediapipe/tasks/python/metadata/metadata_writers/BUILD @@ -67,7 +67,15 @@ py_library( py_library( name = "object_detector", srcs = ["object_detector.py"], - deps = [":metadata_writer"], + data = ["//mediapipe/tasks/metadata:object_detector_metadata_schema.fbs"], + deps = [ + ":metadata_info", + ":metadata_writer", + "//mediapipe/tasks/metadata:metadata_schema_py", + "//mediapipe/tasks/metadata:object_detector_metadata_schema_py", + "//mediapipe/tasks/python/metadata", + "@flatbuffers//:runtime_py", + ], ) py_library( diff --git a/mediapipe/tasks/python/metadata/metadata_writers/metadata_info.py b/mediapipe/tasks/python/metadata/metadata_writers/metadata_info.py index 3b47e9b3b..01d725f17 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/metadata_info.py +++ b/mediapipe/tasks/python/metadata/metadata_writers/metadata_info.py @@ -17,6 +17,7 @@ import abc import collections import csv +import enum import os from typing import List, Optional, Type, Union @@ -1004,6 +1005,84 @@ class DetectionOutputTensorsMd: return self._output_mds +class RawDetectionOutputTensorsOrder(enum.Enum): + """Output tensors order for detection models without postprocessing. + + Because it is not able to determined the order of output tensors for models + without postprocessing, it is needed to specify the output tensors order for + metadata writer. + """ + + UNSPECIFIED = 0 + # The first tensor is score, and the second tensor is location. + SCORE_LOCATION = 1 + # The first tensor is location, and the second tensor is score. + LOCATION_SCORE = 2 + + +class RawDetectionOutputTensorsMd: + """A container for the output tensor metadata of detection models without postprocessing.""" + + _LOCATION_NAME = "location" + _LOCATION_DESCRIPTION = "The locations of the detected boxes." + _SCORE_NAME = "score" + _SCORE_DESCRIPTION = "The scores of the detected boxes." + _CONTENT_VALUE_DIM = 2 + + def __init__( + self, + model_buffer: bytearray, + label_files: Optional[List[LabelFileMd]] = None, + output_tensors_order: RawDetectionOutputTensorsOrder = RawDetectionOutputTensorsOrder.UNSPECIFIED, + ) -> None: + """Initializes the instance of DetectionOutputTensorsMd. + + Args: + model_buffer: A valid flatbuffer loaded from the TFLite model file. + label_files: information of the label files [1] in the classification + tensor. + output_tensors_order: the order of the output tensors. + [1]: + https://github.com/google/mediapipe/blob/f8af41b1eb49ff4bdad756ff19d1d36f486be614/mediapipe/tasks/metadata/metadata_schema.fbs#L9 + """ + # Get the output tensor indices and names from the tflite model. + tensor_indices_and_names = list( + zip( + writer_utils.get_output_tensor_indices(model_buffer), + writer_utils.get_output_tensor_names(model_buffer), + ) + ) + location_md = LocationTensorMd( + name=self._LOCATION_NAME, + description=self._LOCATION_DESCRIPTION, + ) + score_md = ClassificationTensorMd( + name=self._SCORE_NAME, + description=self._SCORE_DESCRIPTION, + label_files=label_files, + ) + + if output_tensors_order == RawDetectionOutputTensorsOrder.SCORE_LOCATION: + self._output_mds = [score_md, location_md] + elif output_tensors_order == RawDetectionOutputTensorsOrder.LOCATION_SCORE: + self._output_mds = [location_md, score_md] + else: + raise ValueError( + f"Unsupported OutputTensorsOrder value: {output_tensors_order}" + ) + + if len(self._output_mds) != len(tensor_indices_and_names): + raise ValueError( + "The size of TFLite output should be " + str(len(self._output_mds)) + ) + for i, output_md in enumerate(self._output_mds): + output_md.tensor_name = tensor_indices_and_names[i][1] + + @property + def output_mds(self) -> List[TensorMd]: + return self._output_mds + + class TensorGroupMd: """A container for a group of tensor metadata information.""" diff --git a/mediapipe/tasks/python/metadata/metadata_writers/metadata_writer.py b/mediapipe/tasks/python/metadata/metadata_writers/metadata_writer.py index 302b717a1..659a89b8e 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/metadata_writer.py +++ b/mediapipe/tasks/python/metadata/metadata_writers/metadata_writer.py @@ -632,7 +632,7 @@ class MetadataWriter(object): score_calibration: Optional[ScoreCalibration] = None, group_name: str = _DETECTION_GROUP_NAME, ) -> 'MetadataWriter': - """Adds a detection head metadata for detection output tensor. + """Adds a detection head metadata for detection output tensor of models with postprocessing. Args: labels: an instance of Labels helper class. @@ -661,6 +661,33 @@ class MetadataWriter(object): self._output_group_mds.append(group_md) return self + def add_raw_detection_output( + self, + labels: Optional[Labels] = None, + output_tensors_order: metadata_info.RawDetectionOutputTensorsOrder = metadata_info.RawDetectionOutputTensorsOrder.UNSPECIFIED, + ) -> 'MetadataWriter': + """Adds a detection head metadata for detection output tensor of models without postprocessing. + + Args: + labels: an instance of Labels helper class. + output_tensors_order: the order of the output tensors. For models of + out-of-graph non-maximum-suppression only. + + Returns: + The current Writer instance to allow chained operation. + """ + label_files = self._create_label_file_md(labels) + detection_output_mds = metadata_info.RawDetectionOutputTensorsMd( + self._model_buffer, + label_files=label_files, + output_tensors_order=output_tensors_order, + ).output_mds + self._output_mds.extend(detection_output_mds) + # Outputs are location, score. + if len(detection_output_mds) != 2: + raise ValueError('The size of detections output should be 2.') + return self + def add_segmentation_output( self, labels: Optional[Labels] = None, diff --git a/mediapipe/tasks/python/metadata/metadata_writers/object_detector.py b/mediapipe/tasks/python/metadata/metadata_writers/object_detector.py index f070534c1..9944ecfb8 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/object_detector.py +++ b/mediapipe/tasks/python/metadata/metadata_writers/object_detector.py @@ -14,8 +14,14 @@ # ============================================================================== """Writes metadata and label file to the Object Detector models.""" +import dataclasses from typing import List, Optional +import flatbuffers +from mediapipe.tasks.metadata import metadata_schema_py_generated as _metadata_fb +from mediapipe.tasks.metadata import object_detector_metadata_schema_py_generated as _detector_metadata_fb +from mediapipe.tasks.python.metadata import metadata +from mediapipe.tasks.python.metadata.metadata_writers import metadata_info from mediapipe.tasks.python.metadata.metadata_writers import metadata_writer _MODEL_NAME = "ObjectDetector" @@ -25,12 +31,187 @@ _MODEL_DESCRIPTION = ( "stream." ) +# Metadata Schema file for object detector. +_FLATC_METADATA_SCHEMA_FILE = metadata.get_path_to_datafile( + "../../../metadata/object_detector_metadata_schema.fbs", +) + +# Metadata name in custom metadata field. The metadata name is used to get +# object detector metadata from SubGraphMetadata.custom_metadata and shouldn't +# be changed. +_METADATA_NAME = "DETECTOR_METADATA" + + +@dataclasses.dataclass +class FixedAnchor: + """A fixed size anchor.""" + + x_center: float + y_center: float + width: Optional[float] + height: Optional[float] + + +@dataclasses.dataclass +class FixedAnchorsSchema: + """The schema for a list of anchors with fixed size.""" + + anchors: List[FixedAnchor] + + +@dataclasses.dataclass +class SsdAnchorsOptions: + """The ssd anchors options used in object detector model.""" + + fixed_anchors_schema: Optional[FixedAnchorsSchema] + + +@dataclasses.dataclass +class TensorsDecodingOptions: + """The decoding options to convert model output tensors to detections.""" + + # The number of output classes predicted by the detection model. + num_classes: int + # The number of output boxes predicted by the detection model. + num_boxes: int + # The number of output values per boxes predicted by the detection + # model. The values contain bounding boxes, keypoints, etc. + num_coords: int + # The offset of keypoint coordinates in the location tensor. + keypoint_coord_offset: int + # The number of predicted keypoints. + num_keypoints: int + # The dimension of each keypoint, e.g. number of values predicted for each + # keypoint. + num_values_per_keypoint: int + # Parameters for decoding SSD detection model. + x_scale: float + y_scale: float + w_scale: float + h_scale: float + # Whether to apply exponential on box size. + apply_exponential_on_box_size: bool + # Whether to apply sigmod function on the score. + sigmoid_score: bool + + +# Create an individual method for getting the metadata json file, so that it can +# be used as a standalone util. +def convert_to_json(metadata_buffer: bytearray) -> str: + """Converts the metadata into a json string. + + Args: + metadata_buffer: valid metadata buffer in bytes. + + Returns: + Metadata in JSON format. + + Raises: + ValueError: error occurred when parsing the metadata schema file. + """ + return metadata.convert_to_json( + metadata_buffer, + custom_metadata_schema={_METADATA_NAME: _FLATC_METADATA_SCHEMA_FILE}, + ) + + +class ObjectDetectorOptionsMd(metadata_info.CustomMetadataMd): + """Object detector options metadata.""" + + _METADATA_FILE_IDENTIFIER = b"V001" + + def __init__( + self, + ssd_anchors_options: SsdAnchorsOptions, + tensors_decoding_options: TensorsDecodingOptions, + ) -> None: + """Creates an ObjectDetectorOptionsMd object. + + Args: + ssd_anchors_options: the ssd anchors options associated to the object + detector model. + tensors_decoding_options: the tensors decoding options used to decode the + object detector model output. + """ + if ssd_anchors_options.fixed_anchors_schema is None: + raise ValueError( + "Currently only support FixedAnchorsSchema, which cannot be found" + " in ssd_anchors_options." + ) + self.ssd_anchors_options = ssd_anchors_options + self.tensors_decoding_options = tensors_decoding_options + super().__init__(name=_METADATA_NAME) + + def create_metadata(self) -> _metadata_fb.CustomMetadataT: + """Creates the image segmenter options metadata. + + Returns: + A Flatbuffers Python object of the custom metadata including object + detector options metadata. + """ + detector_options = _detector_metadata_fb.ObjectDetectorOptionsT() + + # Set ssd_anchors_options. + ssd_anchors_options = _detector_metadata_fb.SsdAnchorsOptionsT() + fixed_anchors_schema = _detector_metadata_fb.FixedAnchorsSchemaT() + fixed_anchors_schema.anchors = [] + for anchor in self.ssd_anchors_options.fixed_anchors_schema.anchors: + anchor_t = _detector_metadata_fb.FixedAnchorT() + anchor_t.xCenter = anchor.x_center + anchor_t.yCenter = anchor.y_center + anchor_t.width = anchor.width + anchor_t.height = anchor.height + fixed_anchors_schema.anchors.append(anchor_t) + ssd_anchors_options.fixedAnchorsSchema = fixed_anchors_schema + detector_options.ssdAnchorsOptions = ssd_anchors_options + + # Set tensors_decoding_options. + tensors_decoding_options = _detector_metadata_fb.TensorsDecodingOptionsT() + tensors_decoding_options.numClasses = ( + self.tensors_decoding_options.num_classes + ) + tensors_decoding_options.numBoxes = self.tensors_decoding_options.num_boxes + tensors_decoding_options.numCoords = ( + self.tensors_decoding_options.num_coords + ) + tensors_decoding_options.keypointCoordOffset = ( + self.tensors_decoding_options.keypoint_coord_offset + ) + tensors_decoding_options.numKeypoints = ( + self.tensors_decoding_options.num_keypoints + ) + tensors_decoding_options.numValuesPerKeypoint = ( + self.tensors_decoding_options.num_values_per_keypoint + ) + tensors_decoding_options.xScale = self.tensors_decoding_options.x_scale + tensors_decoding_options.yScale = self.tensors_decoding_options.y_scale + tensors_decoding_options.wScale = self.tensors_decoding_options.w_scale + tensors_decoding_options.hScale = self.tensors_decoding_options.h_scale + tensors_decoding_options.applyExponentialOnBoxSize = ( + self.tensors_decoding_options.apply_exponential_on_box_size + ) + tensors_decoding_options.sigmoidScore = ( + self.tensors_decoding_options.sigmoid_score + ) + detector_options.tensorsDecodingOptions = tensors_decoding_options + + # Get the object detector options flatbuffer. + b = flatbuffers.Builder(0) + b.Finish(detector_options.Pack(b), self._METADATA_FILE_IDENTIFIER) + detector_options_buf = b.Output() + + # Add the object detector options flatbuffer in custom metadata. + custom_metadata = _metadata_fb.CustomMetadataT() + custom_metadata.name = self.name + custom_metadata.data = detector_options_buf + return custom_metadata + class MetadataWriter(metadata_writer.MetadataWriterBase): """MetadataWriter to write the metadata into the object detector.""" @classmethod - def create( + def create_for_models_with_nms( cls, model_buffer: bytearray, input_norm_mean: List[float], @@ -38,7 +219,9 @@ class MetadataWriter(metadata_writer.MetadataWriterBase): labels: metadata_writer.Labels, score_calibration: Optional[metadata_writer.ScoreCalibration] = None, ) -> "MetadataWriter": - """Creates MetadataWriter to write the metadata for image classifier. + """Creates MetadataWriter to write the metadata for object detector with postprocessing in the model. + + This method create a metadata writer for the models with postprocessing [1]. The parameters required in this method are mandatory when using MediaPipe Tasks. @@ -54,18 +237,20 @@ class MetadataWriter(metadata_writer.MetadataWriterBase): Args: model_buffer: A valid flatbuffer loaded from the TFLite model file. input_norm_mean: the mean value used in the input tensor normalization - [1]. - input_norm_std: the std value used in the input tensor normalizarion [1]. + [2]. + input_norm_std: the std value used in the input tensor normalizarion [2]. labels: an instance of Labels helper class used in the output - classification tensor [2]. - score_calibration: A container of the score calibration operation [3] in + classification tensor [3]. + score_calibration: A container of the score calibration operation [4] in the classification tensor. Optional if the model does not use score calibration. [1]: - https://github.com/google/mediapipe/blob/f8af41b1eb49ff4bdad756ff19d1d36f486be614/mediapipe/tasks/metadata/metadata_schema.fbs#L389 + https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/kernels/detection_postprocess.cc [2]: - https://github.com/google/mediapipe/blob/f8af41b1eb49ff4bdad756ff19d1d36f486be614/mediapipe/tasks/metadata/metadata_schema.fbs#L99 + https://github.com/google/mediapipe/blob/f8af41b1eb49ff4bdad756ff19d1d36f486be614/mediapipe/tasks/metadata/metadata_schema.fbs#L389 [3]: + https://github.com/google/mediapipe/blob/f8af41b1eb49ff4bdad756ff19d1d36f486be614/mediapipe/tasks/metadata/metadata_schema.fbs#L99 + [4]: https://github.com/google/mediapipe/blob/f8af41b1eb49ff4bdad756ff19d1d36f486be614/mediapipe/tasks/metadata/metadata_schema.fbs#L456 Returns: @@ -76,3 +261,70 @@ class MetadataWriter(metadata_writer.MetadataWriterBase): writer.add_image_input(input_norm_mean, input_norm_std) writer.add_detection_output(labels, score_calibration) return cls(writer) + + @classmethod + def create_for_models_without_nms( + cls, + model_buffer: bytearray, + input_norm_mean: List[float], + input_norm_std: List[float], + labels: metadata_writer.Labels, + ssd_anchors_options: SsdAnchorsOptions, + tensors_decoding_options: TensorsDecodingOptions, + output_tensors_order: metadata_info.RawDetectionOutputTensorsOrder = metadata_info.RawDetectionOutputTensorsOrder.UNSPECIFIED, + ) -> "MetadataWriter": + """Creates MetadataWriter to write the metadata for object detector without postprocessing in the model. + + This method create a metadata writer for the models without postprocessing + [1]. + + The parameters required in this method are mandatory when using MediaPipe + Tasks. + + Example usage: + metadata_writer = object_detector.Metadatawriter.create(model_buffer, ...) + tflite_content, json_content = metadata_writer.populate() + + When calling `populate` function in this class, it returns TfLite content + and JSON content. Note that only the output TFLite is used for deployment. + The output JSON content is used to interpret the metadata content. + + Args: + model_buffer: A valid flatbuffer loaded from the TFLite model file. + input_norm_mean: the mean value used in the input tensor normalization + [2]. + input_norm_std: the std value used in the input tensor normalizarion [2]. + labels: an instance of Labels helper class used in the output + classification tensor [3]. + ssd_anchors_options: the ssd anchors options associated to the object + detector model. + tensors_decoding_options: the tensors decoding options used to decode the + object detector model output. + output_tensors_order: the order of the output tensors. + [1]: + https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/kernels/detection_postprocess.cc + [2]: + https://github.com/google/mediapipe/blob/f8af41b1eb49ff4bdad756ff19d1d36f486be614/mediapipe/tasks/metadata/metadata_schema.fbs#L389 + [3]: + https://github.com/google/mediapipe/blob/f8af41b1eb49ff4bdad756ff19d1d36f486be614/mediapipe/tasks/metadata/metadata_schema.fbs#L99 + + Returns: + A MetadataWriter object. + """ + writer = metadata_writer.MetadataWriter(model_buffer) + writer.add_general_info(_MODEL_NAME, _MODEL_DESCRIPTION) + writer.add_image_input(input_norm_mean, input_norm_std) + writer.add_raw_detection_output( + labels, output_tensors_order=output_tensors_order + ) + option_md = ObjectDetectorOptionsMd( + ssd_anchors_options, tensors_decoding_options + ) + writer.add_custom_metadata(option_md) + return cls(writer) + + def populate(self) -> "tuple[bytearray, str]": + model_buf, _ = super().populate() + metadata_buf = metadata.get_metadata_buffer(model_buf) + json_content = convert_to_json(metadata_buf) + return model_buf, json_content diff --git a/mediapipe/tasks/python/test/metadata/metadata_writers/BUILD b/mediapipe/tasks/python/test/metadata/metadata_writers/BUILD index 976ddc9d2..66ddf54b8 100644 --- a/mediapipe/tasks/python/test/metadata/metadata_writers/BUILD +++ b/mediapipe/tasks/python/test/metadata/metadata_writers/BUILD @@ -86,6 +86,7 @@ py_test( deps = [ "//mediapipe/tasks/metadata:metadata_schema_py", "//mediapipe/tasks/python/metadata", + "//mediapipe/tasks/python/metadata/metadata_writers:metadata_info", "//mediapipe/tasks/python/metadata/metadata_writers:metadata_writer", "//mediapipe/tasks/python/metadata/metadata_writers:object_detector", "//mediapipe/tasks/python/test:test_utils", diff --git a/mediapipe/tasks/python/test/metadata/metadata_writers/object_detector_test.py b/mediapipe/tasks/python/test/metadata/metadata_writers/object_detector_test.py index 89e2d67d7..b0e5d4c90 100644 --- a/mediapipe/tasks/python/test/metadata/metadata_writers/object_detector_test.py +++ b/mediapipe/tasks/python/test/metadata/metadata_writers/object_detector_test.py @@ -14,6 +14,7 @@ # ============================================================================== """Tests for metadata_writer.object_detector.""" +import csv import os from absl.testing import absltest @@ -21,6 +22,7 @@ from absl.testing import parameterized from mediapipe.tasks.metadata import metadata_schema_py_generated as metadata_fb from mediapipe.tasks.python.metadata import metadata +from mediapipe.tasks.python.metadata.metadata_writers import metadata_info from mediapipe.tasks.python.metadata.metadata_writers import metadata_writer from mediapipe.tasks.python.metadata.metadata_writers import object_detector from mediapipe.tasks.python.test import test_utils @@ -48,6 +50,39 @@ _JSON_FOR_SCORE_CALIBRATION = test_utils.get_test_data_path( os.path.join(_TEST_DATA_DIR, "coco_ssd_mobilenet_v1_score_calibration.json") ) +_EFFICIENTDET_LITE0_ANCHORS_FILE = test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, "efficientdet_lite0_fp16_no_nms_anchors.csv") +) + + +def read_ssd_anchors_from_csv(file_path): + with open(file_path, "r") as anchors_file: + csv_reader = csv.reader(anchors_file, delimiter=",") + parameters = [] + for row in csv_reader: + if not row: + parameters.append(None) + continue + if len(row) != 4: + raise ValueError( + "Expected empty lines or 4 parameters per line in " + f"anchors file, but got {len(row)}." + ) + parameters.append(row) + anchors = [] + for parameter in parameters: + anchors.append( + object_detector.FixedAnchor( + x_center=float(parameter[1]), + y_center=float(parameter[0]), + width=float(parameter[3]), + height=float(parameter[2]), + ) + ) + return object_detector.SsdAnchorsOptions( + fixed_anchors_schema=object_detector.FixedAnchorsSchema(anchors) + ) + class MetadataWriterTest(parameterized.TestCase, absltest.TestCase): @@ -61,37 +96,41 @@ class MetadataWriterTest(parameterized.TestCase, absltest.TestCase): ) with open(model_path, "rb") as f: model_buffer = f.read() - writer = object_detector.MetadataWriter.create( - model_buffer, - [_NORM_MEAN], - [_NORM_STD], - labels=metadata_writer.Labels().add_from_file(_LABEL_FILE), + writer = ( + object_detector.MetadataWriter.create_for_models_with_nms( + model_buffer, + [_NORM_MEAN], + [_NORM_STD], + labels=metadata_writer.Labels().add_from_file(_LABEL_FILE), + ) ) _, metadata_json = writer.populate() expected_json_path = test_utils.get_test_data_path( os.path.join(_TEST_DATA_DIR, model_name + ".json") ) with open(expected_json_path, "r") as f: - expected_json = f.read() + expected_json = f.read().strip() self.assertEqual(metadata_json, expected_json) def test_create_with_score_calibration_should_succeed(self): with open(_MODEL_COCO, "rb") as f: model_buffer = f.read() - writer = object_detector.MetadataWriter.create( - model_buffer, - [_NORM_MEAN], - [_NORM_STD], - labels=metadata_writer.Labels().add_from_file(_LABEL_FILE), - score_calibration=metadata_writer.ScoreCalibration.create_from_file( - metadata_fb.ScoreTransformationType.INVERSE_LOGISTIC, - _SCORE_CALIBRATION_FILE, - _SCORE_CALIBRATION_DEFAULT_SCORE, - ), + writer = ( + object_detector.MetadataWriter.create_for_models_with_nms( + model_buffer, + [_NORM_MEAN], + [_NORM_STD], + labels=metadata_writer.Labels().add_from_file(_LABEL_FILE), + score_calibration=metadata_writer.ScoreCalibration.create_from_file( + metadata_fb.ScoreTransformationType.INVERSE_LOGISTIC, + _SCORE_CALIBRATION_FILE, + _SCORE_CALIBRATION_DEFAULT_SCORE, + ), + ) ) tflite_content, metadata_json = writer.populate() with open(_JSON_FOR_SCORE_CALIBRATION, "r") as f: - expected_json = f.read() + expected_json = f.read().strip() self.assertEqual(metadata_json, expected_json) displayer = metadata.MetadataDisplayer.with_model_buffer(tflite_content) diff --git a/mediapipe/tasks/testdata/metadata/BUILD b/mediapipe/tasks/testdata/metadata/BUILD index e335831aa..710e9d8cf 100644 --- a/mediapipe/tasks/testdata/metadata/BUILD +++ b/mediapipe/tasks/testdata/metadata/BUILD @@ -32,7 +32,7 @@ mediapipe_files(srcs = [ "deeplabv3_with_activation.json", "deeplabv3_without_labels.json", "deeplabv3_without_metadata.tflite", - "efficientdet_lite0_v1.json", + "efficientdet_lite0_fp16_no_nms.tflite", "efficientdet_lite0_v1.tflite", "labelmap.txt", "mobile_ica_8bit-with-custom-metadata.tflite", @@ -64,6 +64,8 @@ exports_files([ "classification_tensor_float_meta.json", "classification_tensor_uint8_meta.json", "classification_tensor_unsupported_meta.json", + "efficientdet_lite0_fp16_no_nms_anchors.csv", + "efficientdet_lite0_fp16_no_nms.json", "feature_tensor_meta.json", "image_tensor_meta.json", "input_image_tensor_float_meta.json", @@ -94,6 +96,7 @@ filegroup( "bert_text_classifier_no_metadata.tflite", "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29_no_metadata.tflite", "deeplabv3_without_metadata.tflite", + "efficientdet_lite0_fp16_no_nms.tflite", "efficientdet_lite0_v1.tflite", "mobile_ica_8bit-with-custom-metadata.tflite", "mobile_ica_8bit-with-large-min-parser-version.tflite", @@ -126,6 +129,7 @@ filegroup( "deeplabv3.json", "deeplabv3_with_activation.json", "deeplabv3_without_labels.json", + "efficientdet_lite0_fp16_no_nms_anchors.csv", "efficientdet_lite0_v1.json", "external_file", "feature_tensor_meta.json", diff --git a/mediapipe/tasks/testdata/metadata/coco_ssd_mobilenet_v1_score_calibration.json b/mediapipe/tasks/testdata/metadata/coco_ssd_mobilenet_v1_score_calibration.json index e24aa2e6b..8459fdf17 100644 --- a/mediapipe/tasks/testdata/metadata/coco_ssd_mobilenet_v1_score_calibration.json +++ b/mediapipe/tasks/testdata/metadata/coco_ssd_mobilenet_v1_score_calibration.json @@ -56,23 +56,20 @@ "max": 2 } }, - "stats": { - } + "stats": {} }, { "name": "category", "description": "The categories of the detected boxes.", "content": { "content_properties_type": "FeatureProperties", - "content_properties": { - }, + "content_properties": {}, "range": { "min": 2, "max": 2 } }, - "stats": { - }, + "stats": {}, "associated_files": [ { "name": "labels.txt", @@ -86,8 +83,7 @@ "description": "The scores of the detected boxes.", "content": { "content_properties_type": "FeatureProperties", - "content_properties": { - }, + "content_properties": {}, "range": { "min": 2, "max": 2 @@ -102,8 +98,7 @@ } } ], - "stats": { - }, + "stats": {}, "associated_files": [ { "name": "score_calibration.txt", @@ -117,11 +112,9 @@ "description": "The number of the detected boxes.", "content": { "content_properties_type": "FeatureProperties", - "content_properties": { - } + "content_properties": {} }, - "stats": { - } + "stats": {} } ], "output_tensor_groups": [ diff --git a/mediapipe/tasks/testdata/metadata/efficientdet_lite0_fp16_no_nms_anchors.csv b/mediapipe/tasks/testdata/metadata/efficientdet_lite0_fp16_no_nms_anchors.csv new file mode 100644 index 000000000..e8abc1f38 --- /dev/null +++ b/mediapipe/tasks/testdata/metadata/efficientdet_lite0_fp16_no_nms_anchors.csv @@ -0,0 +1,19206 @@ +0.0125,0.0125,0.075,0.075 +0.012499999,0.012499997,0.05303301,0.10606602 +0.012499997,0.012499999,0.10606602,0.05303301 +0.012499999,0.012499999,0.09449408,0.09449408 +0.012499999,0.012500001,0.0668174,0.1336348 +0.012500001,0.012499999,0.1336348,0.0668174 +0.012500001,0.012500001,0.11905508,0.11905508 +0.012500002,0.012499999,0.084184654,0.1683693 +0.012499999,0.012500002,0.1683693,0.084184654 +0.0125,0.0375,0.075,0.075 +0.012499999,0.037499998,0.05303301,0.10606601 +0.012499997,0.0375,0.10606602,0.05303301 +0.012499999,0.0375,0.09449408,0.094494075 +0.012499999,0.0375,0.0668174,0.1336348 +0.012500001,0.0375,0.1336348,0.0668174 +0.012500001,0.0375,0.11905508,0.11905508 +0.012500002,0.0375,0.084184654,0.16836931 +0.012499999,0.0375,0.1683693,0.08418466 +0.0125,0.0625,0.075,0.075 +0.012499999,0.0625,0.05303301,0.10606602 +0.012499997,0.0625,0.10606602,0.05303301 +0.012499999,0.0625,0.09449408,0.094494075 +0.012499999,0.0625,0.0668174,0.1336348 +0.012500001,0.0625,0.1336348,0.0668174 +0.012500001,0.0625,0.11905508,0.11905508 +0.012500002,0.0625,0.084184654,0.16836932 +0.012499999,0.0625,0.1683693,0.08418465 +0.0125,0.0875,0.075,0.075 +0.012499999,0.08749999,0.05303301,0.10606601 +0.012499997,0.087500006,0.10606602,0.053033013 +0.012499999,0.087500006,0.09449408,0.09449408 +0.012499999,0.087500006,0.0668174,0.1336348 +0.012500001,0.0875,0.1336348,0.0668174 +0.012500001,0.0875,0.11905508,0.11905508 +0.012500002,0.0875,0.084184654,0.16836931 +0.012499999,0.087500006,0.1683693,0.084184654 +0.0125,0.112500004,0.075,0.075 +0.012499999,0.1125,0.05303301,0.10606601 +0.012499997,0.112500004,0.10606602,0.05303301 +0.012499999,0.1125,0.09449408,0.094494075 +0.012499999,0.1125,0.0668174,0.1336348 +0.012500001,0.1125,0.1336348,0.0668174 +0.012500001,0.1125,0.11905508,0.119055085 +0.012500002,0.112500004,0.084184654,0.16836931 +0.012499999,0.1125,0.1683693,0.08418465 +0.0125,0.1375,0.075,0.074999996 +0.012499999,0.1375,0.05303301,0.10606602 +0.012499997,0.1375,0.10606602,0.053033024 +0.012499999,0.1375,0.09449408,0.09449408 +0.012499999,0.1375,0.0668174,0.1336348 +0.012500001,0.1375,0.1336348,0.0668174 +0.012500001,0.13749999,0.11905508,0.11905508 +0.012500002,0.1375,0.084184654,0.1683693 +0.012499999,0.1375,0.1683693,0.084184654 +0.0125,0.1625,0.075,0.075 +0.012499999,0.16250001,0.05303301,0.106066026 +0.012499997,0.1625,0.10606602,0.05303301 +0.012499999,0.1625,0.09449408,0.094494075 +0.012499999,0.1625,0.0668174,0.1336348 +0.012500001,0.1625,0.1336348,0.0668174 +0.012500001,0.1625,0.11905508,0.11905508 +0.012500002,0.1625,0.084184654,0.1683693 +0.012499999,0.1625,0.1683693,0.08418464 +0.0125,0.1875,0.075,0.07499999 +0.012499999,0.1875,0.05303301,0.10606603 +0.012499997,0.1875,0.10606602,0.053033024 +0.012499999,0.1875,0.09449408,0.09449406 +0.012499999,0.1875,0.0668174,0.1336348 +0.012500001,0.1875,0.1336348,0.06681742 +0.012500001,0.1875,0.11905508,0.11905509 +0.012500002,0.1875,0.084184654,0.16836931 +0.012499999,0.1875,0.1683693,0.08418465 +0.0125,0.2125,0.075,0.075 +0.012499999,0.2125,0.05303301,0.10606603 +0.012499997,0.2125,0.10606602,0.05303301 +0.012499999,0.21249999,0.09449408,0.094494075 +0.012499999,0.2125,0.0668174,0.1336348 +0.012500001,0.2125,0.1336348,0.0668174 +0.012500001,0.2125,0.11905508,0.11905509 +0.012500002,0.2125,0.084184654,0.16836931 +0.012499999,0.2125,0.1683693,0.08418465 +0.0125,0.23750001,0.075,0.075 +0.012499999,0.2375,0.05303301,0.10606602 +0.012499997,0.2375,0.10606602,0.053033024 +0.012499999,0.2375,0.09449408,0.094494075 +0.012499999,0.23750001,0.0668174,0.13363482 +0.012500001,0.2375,0.1336348,0.06681743 +0.012500001,0.2375,0.11905508,0.11905506 +0.012500002,0.2375,0.084184654,0.16836932 +0.012499999,0.23750001,0.1683693,0.08418466 +0.0125,0.2625,0.075,0.07500002 +0.012499999,0.2625,0.05303301,0.10606603 +0.012499997,0.2625,0.10606602,0.053033024 +0.012499999,0.2625,0.09449408,0.094494075 +0.012499999,0.2625,0.0668174,0.13363479 +0.012500001,0.2625,0.1336348,0.06681743 +0.012500001,0.2625,0.11905508,0.11905508 +0.012500002,0.2625,0.084184654,0.1683693 +0.012499999,0.2625,0.1683693,0.08418463 +0.0125,0.2875,0.075,0.07499999 +0.012499999,0.2875,0.05303301,0.10606603 +0.012499997,0.28750002,0.10606602,0.053033024 +0.012499999,0.2875,0.09449408,0.094494045 +0.012499999,0.2875,0.0668174,0.1336348 +0.012500001,0.28750002,0.1336348,0.06681743 +0.012500001,0.2875,0.11905508,0.11905508 +0.012500002,0.2875,0.084184654,0.1683693 +0.012499999,0.2875,0.1683693,0.08418465 +0.0125,0.3125,0.075,0.07499999 +0.012499999,0.3125,0.05303301,0.10606605 +0.012499997,0.3125,0.10606602,0.053032994 +0.012499999,0.3125,0.09449408,0.094494045 +0.012499999,0.3125,0.0668174,0.1336348 +0.012500001,0.3125,0.1336348,0.0668174 +0.012500001,0.3125,0.11905508,0.11905509 +0.012500002,0.3125,0.084184654,0.1683693 +0.012499999,0.3125,0.1683693,0.08418465 +0.0125,0.3375,0.075,0.07499999 +0.012499999,0.3375,0.05303301,0.10606605 +0.012499997,0.33749998,0.10606602,0.053033024 +0.012499999,0.3375,0.09449408,0.094494045 +0.012499999,0.33750004,0.0668174,0.13363484 +0.012500001,0.33749998,0.1336348,0.06681743 +0.012500001,0.3375,0.11905508,0.11905509 +0.012500002,0.3375,0.084184654,0.1683693 +0.012499999,0.3375,0.1683693,0.08418465 +0.0125,0.3625,0.075,0.07500002 +0.012499999,0.3625,0.05303301,0.10606602 +0.012499997,0.3625,0.10606602,0.053033024 +0.012499999,0.3625,0.09449408,0.094494075 +0.012499999,0.3625,0.0668174,0.1336348 +0.012500001,0.3625,0.1336348,0.06681743 +0.012500001,0.3625,0.11905508,0.11905506 +0.012500002,0.3625,0.084184654,0.1683693 +0.012499999,0.3625,0.1683693,0.08418465 +0.0125,0.3875,0.075,0.07500002 +0.012499999,0.3875,0.05303301,0.10606602 +0.012499997,0.3875,0.10606602,0.053032994 +0.012499999,0.3875,0.09449408,0.094494075 +0.012499999,0.3875,0.0668174,0.13363484 +0.012500001,0.3875,0.1336348,0.0668174 +0.012500001,0.3875,0.11905508,0.11905506 +0.012500002,0.3875,0.084184654,0.1683693 +0.012499999,0.3875,0.1683693,0.08418465 +0.0125,0.4125,0.075,0.07499999 +0.012499999,0.4125,0.05303301,0.10606605 +0.012499997,0.4125,0.10606602,0.053032994 +0.012499999,0.4125,0.09449408,0.094494045 +0.012499999,0.41250002,0.0668174,0.13363484 +0.012500001,0.4125,0.1336348,0.0668174 +0.012500001,0.4125,0.11905508,0.11905509 +0.012500002,0.4125,0.084184654,0.1683693 +0.012499999,0.4125,0.1683693,0.08418465 +0.0125,0.4375,0.075,0.07499999 +0.012499999,0.4375,0.05303301,0.10606605 +0.012499997,0.4375,0.10606602,0.053032994 +0.012499999,0.4375,0.09449408,0.094494045 +0.012499999,0.4375,0.0668174,0.1336348 +0.012500001,0.4375,0.1336348,0.0668174 +0.012500001,0.4375,0.11905508,0.11905509 +0.012500002,0.4375,0.084184654,0.1683693 +0.012499999,0.4375,0.1683693,0.08418465 +0.0125,0.4625,0.075,0.07499999 +0.012499999,0.4625,0.05303301,0.10606605 +0.012499997,0.46249998,0.10606602,0.053032964 +0.012499999,0.4625,0.09449408,0.094494045 +0.012499999,0.46250004,0.0668174,0.13363484 +0.012500001,0.46249998,0.1336348,0.06681737 +0.012500001,0.4625,0.11905508,0.11905509 +0.012500002,0.46249998,0.084184654,0.16836926 +0.012499999,0.46249998,0.1683693,0.08418462 +0.0125,0.48749998,0.075,0.07499999 +0.012499999,0.4875,0.05303301,0.10606602 +0.012499997,0.4875,0.10606602,0.053032994 +0.012499999,0.48749998,0.09449408,0.094494045 +0.012499999,0.4875,0.0668174,0.13363484 +0.012500001,0.4875,0.1336348,0.0668174 +0.012500001,0.4875,0.11905508,0.11905506 +0.012500002,0.4875,0.084184654,0.1683693 +0.012499999,0.4875,0.1683693,0.08418465 +0.0125,0.5125,0.075,0.07500002 +0.012499999,0.51250005,0.05303301,0.10606605 +0.012499997,0.5125,0.10606602,0.053032964 +0.012499999,0.5125,0.09449408,0.094494075 +0.012499999,0.51250005,0.0668174,0.13363487 +0.012500001,0.5125,0.1336348,0.06681737 +0.012500001,0.51250005,0.11905508,0.11905509 +0.012500002,0.5125,0.084184654,0.1683693 +0.012499999,0.5125,0.1683693,0.08418465 +0.0125,0.5375,0.075,0.07499999 +0.012499999,0.5375,0.05303301,0.10606605 +0.012499997,0.5375,0.10606602,0.053032935 +0.012499999,0.5375,0.09449408,0.094494045 +0.012499999,0.5375,0.0668174,0.13363487 +0.012500001,0.5375,0.1336348,0.06681734 +0.012500001,0.5375,0.11905508,0.11905509 +0.012500002,0.5375,0.084184654,0.16836932 +0.012499999,0.5375,0.1683693,0.08418468 +0.0125,0.5625,0.075,0.07500005 +0.012499999,0.5625,0.05303301,0.10606599 +0.012499997,0.5625,0.10606602,0.053032994 +0.012499999,0.5625,0.09449408,0.094494104 +0.012499999,0.5625,0.0668174,0.13363484 +0.012500001,0.5625,0.1336348,0.0668174 +0.012500001,0.5625,0.11905508,0.11905503 +0.012500002,0.5625,0.084184654,0.1683693 +0.012499999,0.5625,0.1683693,0.08418465 +0.0125,0.5875,0.075,0.07499999 +0.012499999,0.5875,0.05303301,0.10606605 +0.012499997,0.5875,0.10606602,0.053032935 +0.012499999,0.5875,0.09449408,0.094494045 +0.012499999,0.5875,0.0668174,0.13363487 +0.012500001,0.5875,0.1336348,0.06681734 +0.012500001,0.5875,0.11905508,0.11905509 +0.012500002,0.5875,0.084184654,0.1683693 +0.012499999,0.5875,0.1683693,0.08418465 +0.0125,0.61249995,0.075,0.07499999 +0.012499999,0.61249995,0.05303301,0.10606605 +0.012499997,0.6125,0.10606602,0.053032994 +0.012499999,0.61249995,0.09449408,0.094494045 +0.012499999,0.61249995,0.0668174,0.13363487 +0.012500001,0.6125,0.1336348,0.0668174 +0.012500001,0.61249995,0.11905508,0.11905509 +0.012500002,0.6125,0.084184654,0.1683693 +0.012499999,0.6125,0.1683693,0.08418465 +0.0125,0.63750005,0.075,0.07499999 +0.012499999,0.63750005,0.05303301,0.10606605 +0.012499997,0.6375,0.10606602,0.053032994 +0.012499999,0.63750005,0.09449408,0.094494045 +0.012499999,0.63750005,0.0668174,0.13363487 +0.012500001,0.6375,0.1336348,0.0668174 +0.012500001,0.63750005,0.11905508,0.11905509 +0.012500002,0.6375,0.084184654,0.1683693 +0.012499999,0.6375,0.1683693,0.08418465 +0.0125,0.6625,0.075,0.07499999 +0.012499999,0.6625,0.05303301,0.10606605 +0.012499997,0.6625,0.10606602,0.053032935 +0.012499999,0.6625,0.09449408,0.094494045 +0.012499999,0.6625,0.0668174,0.13363487 +0.012500001,0.6625,0.1336348,0.06681734 +0.012500001,0.6625,0.11905508,0.11905509 +0.012500002,0.6625,0.084184654,0.1683693 +0.012499999,0.6625,0.1683693,0.08418465 +0.0125,0.6875,0.075,0.07500005 +0.012499999,0.6875,0.05303301,0.10606599 +0.012499997,0.6875,0.10606602,0.053032994 +0.012499999,0.6875,0.09449408,0.094494104 +0.012499999,0.6875,0.0668174,0.1336348 +0.012500001,0.6875,0.1336348,0.0668174 +0.012500001,0.6875,0.11905508,0.11905503 +0.012500002,0.6875,0.084184654,0.1683693 +0.012499999,0.6875,0.1683693,0.08418465 +0.0125,0.7125,0.075,0.07499999 +0.012499999,0.7125,0.05303301,0.10606605 +0.012499997,0.7125,0.10606602,0.053032935 +0.012499999,0.7125,0.09449408,0.094494045 +0.012499999,0.7125,0.0668174,0.13363487 +0.012500001,0.7125,0.1336348,0.06681734 +0.012500001,0.7125,0.11905508,0.11905509 +0.012500002,0.7125,0.084184654,0.1683693 +0.012499999,0.7125,0.1683693,0.08418465 +0.0125,0.73749995,0.075,0.07499999 +0.012499999,0.73749995,0.05303301,0.10606605 +0.012499997,0.7375,0.10606602,0.053032994 +0.012499999,0.73749995,0.09449408,0.094494045 +0.012499999,0.73749995,0.0668174,0.1336348 +0.012500001,0.7375,0.1336348,0.0668174 +0.012500001,0.73749995,0.11905508,0.11905509 +0.012500002,0.7375,0.084184654,0.1683693 +0.012499999,0.7375,0.1683693,0.08418465 +0.0125,0.76250005,0.075,0.07499999 +0.012499999,0.7625,0.05303301,0.10606599 +0.012499997,0.7625,0.10606602,0.053032994 +0.012499999,0.76250005,0.09449408,0.094494045 +0.012499999,0.7625,0.0668174,0.1336348 +0.012500001,0.7625,0.1336348,0.0668174 +0.012500001,0.7625,0.11905508,0.11905503 +0.012500002,0.7625,0.084184654,0.1683693 +0.012499999,0.7625,0.1683693,0.08418465 +0.0125,0.7875,0.075,0.07499999 +0.012499999,0.78749996,0.05303301,0.10606599 +0.012499997,0.7875,0.10606602,0.053032994 +0.012499999,0.7875,0.09449408,0.094494045 +0.012499999,0.78749996,0.0668174,0.1336348 +0.012500001,0.7875,0.1336348,0.0668174 +0.012500001,0.78749996,0.11905508,0.11905503 +0.012500002,0.7875,0.084184654,0.1683693 +0.012499999,0.7875,0.1683693,0.08418465 +0.0125,0.8125,0.075,0.07500005 +0.012499999,0.8125,0.05303301,0.10606599 +0.012499997,0.8125,0.10606602,0.053033054 +0.012499999,0.8125,0.09449408,0.094494104 +0.012499999,0.8125,0.0668174,0.1336348 +0.012500001,0.8125,0.1336348,0.06681746 +0.012500001,0.8125,0.11905508,0.11905503 +0.012500002,0.8125,0.084184654,0.1683693 +0.012499999,0.8125,0.1683693,0.08418465 +0.0125,0.8375,0.075,0.07499999 +0.012499999,0.8375,0.05303301,0.10606599 +0.012499997,0.8375,0.10606602,0.053033054 +0.012499999,0.8375,0.09449408,0.094494045 +0.012499999,0.8375,0.0668174,0.1336348 +0.012500001,0.8375,0.1336348,0.06681746 +0.012500001,0.8375,0.11905508,0.11905503 +0.012500002,0.8375,0.084184654,0.1683693 +0.012499999,0.8375,0.1683693,0.08418465 +0.0125,0.86249995,0.075,0.07499999 +0.012499999,0.86249995,0.05303301,0.10606593 +0.012499997,0.86249995,0.10606602,0.053033054 +0.012499999,0.86249995,0.09449408,0.094494045 +0.012499999,0.86249995,0.0668174,0.1336348 +0.012500001,0.86249995,0.1336348,0.06681746 +0.012500001,0.86249995,0.11905508,0.11905497 +0.012500002,0.8625,0.084184654,0.1683693 +0.012499999,0.8625,0.1683693,0.08418465 +0.0125,0.88750005,0.075,0.07499999 +0.012499999,0.88750005,0.05303301,0.10606593 +0.012499997,0.88750005,0.10606602,0.053033054 +0.012499999,0.88750005,0.09449408,0.094494045 +0.012499999,0.88750005,0.0668174,0.13363475 +0.012500001,0.88750005,0.1336348,0.06681746 +0.012500001,0.88750005,0.11905508,0.11905497 +0.012500002,0.8875,0.084184654,0.1683693 +0.012499999,0.8875,0.1683693,0.08418465 +0.0125,0.9125,0.075,0.07499999 +0.012499999,0.9125,0.05303301,0.10606593 +0.012499997,0.9125,0.10606602,0.053033054 +0.012499999,0.9125,0.09449408,0.094494045 +0.012499999,0.9125,0.0668174,0.13363475 +0.012500001,0.9125,0.1336348,0.06681746 +0.012500001,0.9125,0.11905508,0.11905497 +0.012500002,0.9125,0.084184654,0.1683693 +0.012499999,0.9125,0.1683693,0.08418465 +0.0125,0.9375,0.075,0.07500005 +0.012499999,0.9375,0.05303301,0.10606599 +0.012499997,0.9375,0.10606602,0.053033113 +0.012499999,0.9375,0.09449408,0.094494104 +0.012499999,0.9375,0.0668174,0.1336348 +0.012500001,0.9375,0.1336348,0.06681752 +0.012500001,0.9375,0.11905508,0.11905503 +0.012500002,0.9375,0.084184654,0.1683693 +0.012499999,0.9375,0.1683693,0.08418465 +0.0125,0.9625,0.075,0.07499999 +0.012499999,0.9625,0.05303301,0.10606593 +0.012499997,0.9625,0.10606602,0.053033054 +0.012499999,0.9625,0.09449408,0.094494045 +0.012499999,0.9625,0.0668174,0.13363475 +0.012500001,0.9625,0.1336348,0.06681746 +0.012500001,0.9625,0.11905508,0.11905497 +0.012500002,0.9625,0.084184654,0.1683693 +0.012499999,0.9625,0.1683693,0.08418465 +0.0125,0.98749995,0.075,0.07499999 +0.012499999,0.98749995,0.05303301,0.10606593 +0.012499997,0.98749995,0.10606602,0.053033054 +0.012499999,0.98749995,0.09449408,0.094494045 +0.012499999,0.98749995,0.0668174,0.13363475 +0.012500001,0.98749995,0.1336348,0.06681746 +0.012500001,0.98749995,0.11905508,0.11905497 +0.012500002,0.98749995,0.084184654,0.16836923 +0.012499999,0.98749995,0.1683693,0.08418459 +0.0375,0.0125,0.075,0.075 +0.0375,0.012499997,0.05303301,0.10606602 +0.037499998,0.012499999,0.10606601,0.05303301 +0.0375,0.012499999,0.094494075,0.09449408 +0.0375,0.012500001,0.0668174,0.1336348 +0.0375,0.012499999,0.1336348,0.0668174 +0.0375,0.012500001,0.11905508,0.11905508 +0.0375,0.012499999,0.08418466,0.1683693 +0.0375,0.012500002,0.16836931,0.084184654 +0.0375,0.0375,0.075,0.075 +0.0375,0.037499998,0.05303301,0.10606601 +0.037499998,0.0375,0.10606601,0.05303301 +0.0375,0.0375,0.094494075,0.094494075 +0.0375,0.0375,0.0668174,0.1336348 +0.0375,0.0375,0.1336348,0.0668174 +0.0375,0.0375,0.11905508,0.11905508 +0.0375,0.0375,0.08418466,0.16836931 +0.0375,0.0375,0.16836931,0.08418466 +0.0375,0.0625,0.075,0.075 +0.0375,0.0625,0.05303301,0.10606602 +0.037499998,0.0625,0.10606601,0.05303301 +0.0375,0.0625,0.094494075,0.094494075 +0.0375,0.0625,0.0668174,0.1336348 +0.0375,0.0625,0.1336348,0.0668174 +0.0375,0.0625,0.11905508,0.11905508 +0.0375,0.0625,0.08418466,0.16836932 +0.0375,0.0625,0.16836931,0.08418465 +0.0375,0.0875,0.075,0.075 +0.0375,0.08749999,0.05303301,0.10606601 +0.037499998,0.087500006,0.10606601,0.053033013 +0.0375,0.087500006,0.094494075,0.09449408 +0.0375,0.087500006,0.0668174,0.1336348 +0.0375,0.0875,0.1336348,0.0668174 +0.0375,0.0875,0.11905508,0.11905508 +0.0375,0.0875,0.08418466,0.16836931 +0.0375,0.087500006,0.16836931,0.084184654 +0.0375,0.112500004,0.075,0.075 +0.0375,0.1125,0.05303301,0.10606601 +0.037499998,0.112500004,0.10606601,0.05303301 +0.0375,0.1125,0.094494075,0.094494075 +0.0375,0.1125,0.0668174,0.1336348 +0.0375,0.1125,0.1336348,0.0668174 +0.0375,0.1125,0.11905508,0.119055085 +0.0375,0.112500004,0.08418466,0.16836931 +0.0375,0.1125,0.16836931,0.08418465 +0.0375,0.1375,0.075,0.074999996 +0.0375,0.1375,0.05303301,0.10606602 +0.037499998,0.1375,0.10606601,0.053033024 +0.0375,0.1375,0.094494075,0.09449408 +0.0375,0.1375,0.0668174,0.1336348 +0.0375,0.1375,0.1336348,0.0668174 +0.0375,0.13749999,0.11905508,0.11905508 +0.0375,0.1375,0.08418466,0.1683693 +0.0375,0.1375,0.16836931,0.084184654 +0.0375,0.1625,0.075,0.075 +0.0375,0.16250001,0.05303301,0.106066026 +0.037499998,0.1625,0.10606601,0.05303301 +0.0375,0.1625,0.094494075,0.094494075 +0.0375,0.1625,0.0668174,0.1336348 +0.0375,0.1625,0.1336348,0.0668174 +0.0375,0.1625,0.11905508,0.11905508 +0.0375,0.1625,0.08418466,0.1683693 +0.0375,0.1625,0.16836931,0.08418464 +0.0375,0.1875,0.075,0.07499999 +0.0375,0.1875,0.05303301,0.10606603 +0.037499998,0.1875,0.10606601,0.053033024 +0.0375,0.1875,0.094494075,0.09449406 +0.0375,0.1875,0.0668174,0.1336348 +0.0375,0.1875,0.1336348,0.06681742 +0.0375,0.1875,0.11905508,0.11905509 +0.0375,0.1875,0.08418466,0.16836931 +0.0375,0.1875,0.16836931,0.08418465 +0.0375,0.2125,0.075,0.075 +0.0375,0.2125,0.05303301,0.10606603 +0.037499998,0.2125,0.10606601,0.05303301 +0.0375,0.21249999,0.094494075,0.094494075 +0.0375,0.2125,0.0668174,0.1336348 +0.0375,0.2125,0.1336348,0.0668174 +0.0375,0.2125,0.11905508,0.11905509 +0.0375,0.2125,0.08418466,0.16836931 +0.0375,0.2125,0.16836931,0.08418465 +0.0375,0.23750001,0.075,0.075 +0.0375,0.2375,0.05303301,0.10606602 +0.037499998,0.2375,0.10606601,0.053033024 +0.0375,0.2375,0.094494075,0.094494075 +0.0375,0.23750001,0.0668174,0.13363482 +0.0375,0.2375,0.1336348,0.06681743 +0.0375,0.2375,0.11905508,0.11905506 +0.0375,0.2375,0.08418466,0.16836932 +0.0375,0.23750001,0.16836931,0.08418466 +0.0375,0.2625,0.075,0.07500002 +0.0375,0.2625,0.05303301,0.10606603 +0.037499998,0.2625,0.10606601,0.053033024 +0.0375,0.2625,0.094494075,0.094494075 +0.0375,0.2625,0.0668174,0.13363479 +0.0375,0.2625,0.1336348,0.06681743 +0.0375,0.2625,0.11905508,0.11905508 +0.0375,0.2625,0.08418466,0.1683693 +0.0375,0.2625,0.16836931,0.08418463 +0.0375,0.2875,0.075,0.07499999 +0.0375,0.2875,0.05303301,0.10606603 +0.037499998,0.28750002,0.10606601,0.053033024 +0.0375,0.2875,0.094494075,0.094494045 +0.0375,0.2875,0.0668174,0.1336348 +0.0375,0.28750002,0.1336348,0.06681743 +0.0375,0.2875,0.11905508,0.11905508 +0.0375,0.2875,0.08418466,0.1683693 +0.0375,0.2875,0.16836931,0.08418465 +0.0375,0.3125,0.075,0.07499999 +0.0375,0.3125,0.05303301,0.10606605 +0.037499998,0.3125,0.10606601,0.053032994 +0.0375,0.3125,0.094494075,0.094494045 +0.0375,0.3125,0.0668174,0.1336348 +0.0375,0.3125,0.1336348,0.0668174 +0.0375,0.3125,0.11905508,0.11905509 +0.0375,0.3125,0.08418466,0.1683693 +0.0375,0.3125,0.16836931,0.08418465 +0.0375,0.3375,0.075,0.07499999 +0.0375,0.3375,0.05303301,0.10606605 +0.037499998,0.33749998,0.10606601,0.053033024 +0.0375,0.3375,0.094494075,0.094494045 +0.0375,0.33750004,0.0668174,0.13363484 +0.0375,0.33749998,0.1336348,0.06681743 +0.0375,0.3375,0.11905508,0.11905509 +0.0375,0.3375,0.08418466,0.1683693 +0.0375,0.3375,0.16836931,0.08418465 +0.0375,0.3625,0.075,0.07500002 +0.0375,0.3625,0.05303301,0.10606602 +0.037499998,0.3625,0.10606601,0.053033024 +0.0375,0.3625,0.094494075,0.094494075 +0.0375,0.3625,0.0668174,0.1336348 +0.0375,0.3625,0.1336348,0.06681743 +0.0375,0.3625,0.11905508,0.11905506 +0.0375,0.3625,0.08418466,0.1683693 +0.0375,0.3625,0.16836931,0.08418465 +0.0375,0.3875,0.075,0.07500002 +0.0375,0.3875,0.05303301,0.10606602 +0.037499998,0.3875,0.10606601,0.053032994 +0.0375,0.3875,0.094494075,0.094494075 +0.0375,0.3875,0.0668174,0.13363484 +0.0375,0.3875,0.1336348,0.0668174 +0.0375,0.3875,0.11905508,0.11905506 +0.0375,0.3875,0.08418466,0.1683693 +0.0375,0.3875,0.16836931,0.08418465 +0.0375,0.4125,0.075,0.07499999 +0.0375,0.4125,0.05303301,0.10606605 +0.037499998,0.4125,0.10606601,0.053032994 +0.0375,0.4125,0.094494075,0.094494045 +0.0375,0.41250002,0.0668174,0.13363484 +0.0375,0.4125,0.1336348,0.0668174 +0.0375,0.4125,0.11905508,0.11905509 +0.0375,0.4125,0.08418466,0.1683693 +0.0375,0.4125,0.16836931,0.08418465 +0.0375,0.4375,0.075,0.07499999 +0.0375,0.4375,0.05303301,0.10606605 +0.037499998,0.4375,0.10606601,0.053032994 +0.0375,0.4375,0.094494075,0.094494045 +0.0375,0.4375,0.0668174,0.1336348 +0.0375,0.4375,0.1336348,0.0668174 +0.0375,0.4375,0.11905508,0.11905509 +0.0375,0.4375,0.08418466,0.1683693 +0.0375,0.4375,0.16836931,0.08418465 +0.0375,0.4625,0.075,0.07499999 +0.0375,0.4625,0.05303301,0.10606605 +0.037499998,0.46249998,0.10606601,0.053032964 +0.0375,0.4625,0.094494075,0.094494045 +0.0375,0.46250004,0.0668174,0.13363484 +0.0375,0.46249998,0.1336348,0.06681737 +0.0375,0.4625,0.11905508,0.11905509 +0.0375,0.46249998,0.08418466,0.16836926 +0.0375,0.46249998,0.16836931,0.08418462 +0.0375,0.48749998,0.075,0.07499999 +0.0375,0.4875,0.05303301,0.10606602 +0.037499998,0.4875,0.10606601,0.053032994 +0.0375,0.48749998,0.094494075,0.094494045 +0.0375,0.4875,0.0668174,0.13363484 +0.0375,0.4875,0.1336348,0.0668174 +0.0375,0.4875,0.11905508,0.11905506 +0.0375,0.4875,0.08418466,0.1683693 +0.0375,0.4875,0.16836931,0.08418465 +0.0375,0.5125,0.075,0.07500002 +0.0375,0.51250005,0.05303301,0.10606605 +0.037499998,0.5125,0.10606601,0.053032964 +0.0375,0.5125,0.094494075,0.094494075 +0.0375,0.51250005,0.0668174,0.13363487 +0.0375,0.5125,0.1336348,0.06681737 +0.0375,0.51250005,0.11905508,0.11905509 +0.0375,0.5125,0.08418466,0.1683693 +0.0375,0.5125,0.16836931,0.08418465 +0.0375,0.5375,0.075,0.07499999 +0.0375,0.5375,0.05303301,0.10606605 +0.037499998,0.5375,0.10606601,0.053032935 +0.0375,0.5375,0.094494075,0.094494045 +0.0375,0.5375,0.0668174,0.13363487 +0.0375,0.5375,0.1336348,0.06681734 +0.0375,0.5375,0.11905508,0.11905509 +0.0375,0.5375,0.08418466,0.16836932 +0.0375,0.5375,0.16836931,0.08418468 +0.0375,0.5625,0.075,0.07500005 +0.0375,0.5625,0.05303301,0.10606599 +0.037499998,0.5625,0.10606601,0.053032994 +0.0375,0.5625,0.094494075,0.094494104 +0.0375,0.5625,0.0668174,0.13363484 +0.0375,0.5625,0.1336348,0.0668174 +0.0375,0.5625,0.11905508,0.11905503 +0.0375,0.5625,0.08418466,0.1683693 +0.0375,0.5625,0.16836931,0.08418465 +0.0375,0.5875,0.075,0.07499999 +0.0375,0.5875,0.05303301,0.10606605 +0.037499998,0.5875,0.10606601,0.053032935 +0.0375,0.5875,0.094494075,0.094494045 +0.0375,0.5875,0.0668174,0.13363487 +0.0375,0.5875,0.1336348,0.06681734 +0.0375,0.5875,0.11905508,0.11905509 +0.0375,0.5875,0.08418466,0.1683693 +0.0375,0.5875,0.16836931,0.08418465 +0.0375,0.61249995,0.075,0.07499999 +0.0375,0.61249995,0.05303301,0.10606605 +0.037499998,0.6125,0.10606601,0.053032994 +0.0375,0.61249995,0.094494075,0.094494045 +0.0375,0.61249995,0.0668174,0.13363487 +0.0375,0.6125,0.1336348,0.0668174 +0.0375,0.61249995,0.11905508,0.11905509 +0.0375,0.6125,0.08418466,0.1683693 +0.0375,0.6125,0.16836931,0.08418465 +0.0375,0.63750005,0.075,0.07499999 +0.0375,0.63750005,0.05303301,0.10606605 +0.037499998,0.6375,0.10606601,0.053032994 +0.0375,0.63750005,0.094494075,0.094494045 +0.0375,0.63750005,0.0668174,0.13363487 +0.0375,0.6375,0.1336348,0.0668174 +0.0375,0.63750005,0.11905508,0.11905509 +0.0375,0.6375,0.08418466,0.1683693 +0.0375,0.6375,0.16836931,0.08418465 +0.0375,0.6625,0.075,0.07499999 +0.0375,0.6625,0.05303301,0.10606605 +0.037499998,0.6625,0.10606601,0.053032935 +0.0375,0.6625,0.094494075,0.094494045 +0.0375,0.6625,0.0668174,0.13363487 +0.0375,0.6625,0.1336348,0.06681734 +0.0375,0.6625,0.11905508,0.11905509 +0.0375,0.6625,0.08418466,0.1683693 +0.0375,0.6625,0.16836931,0.08418465 +0.0375,0.6875,0.075,0.07500005 +0.0375,0.6875,0.05303301,0.10606599 +0.037499998,0.6875,0.10606601,0.053032994 +0.0375,0.6875,0.094494075,0.094494104 +0.0375,0.6875,0.0668174,0.1336348 +0.0375,0.6875,0.1336348,0.0668174 +0.0375,0.6875,0.11905508,0.11905503 +0.0375,0.6875,0.08418466,0.1683693 +0.0375,0.6875,0.16836931,0.08418465 +0.0375,0.7125,0.075,0.07499999 +0.0375,0.7125,0.05303301,0.10606605 +0.037499998,0.7125,0.10606601,0.053032935 +0.0375,0.7125,0.094494075,0.094494045 +0.0375,0.7125,0.0668174,0.13363487 +0.0375,0.7125,0.1336348,0.06681734 +0.0375,0.7125,0.11905508,0.11905509 +0.0375,0.7125,0.08418466,0.1683693 +0.0375,0.7125,0.16836931,0.08418465 +0.0375,0.73749995,0.075,0.07499999 +0.0375,0.73749995,0.05303301,0.10606605 +0.037499998,0.7375,0.10606601,0.053032994 +0.0375,0.73749995,0.094494075,0.094494045 +0.0375,0.73749995,0.0668174,0.1336348 +0.0375,0.7375,0.1336348,0.0668174 +0.0375,0.73749995,0.11905508,0.11905509 +0.0375,0.7375,0.08418466,0.1683693 +0.0375,0.7375,0.16836931,0.08418465 +0.0375,0.76250005,0.075,0.07499999 +0.0375,0.7625,0.05303301,0.10606599 +0.037499998,0.7625,0.10606601,0.053032994 +0.0375,0.76250005,0.094494075,0.094494045 +0.0375,0.7625,0.0668174,0.1336348 +0.0375,0.7625,0.1336348,0.0668174 +0.0375,0.7625,0.11905508,0.11905503 +0.0375,0.7625,0.08418466,0.1683693 +0.0375,0.7625,0.16836931,0.08418465 +0.0375,0.7875,0.075,0.07499999 +0.0375,0.78749996,0.05303301,0.10606599 +0.037499998,0.7875,0.10606601,0.053032994 +0.0375,0.7875,0.094494075,0.094494045 +0.0375,0.78749996,0.0668174,0.1336348 +0.0375,0.7875,0.1336348,0.0668174 +0.0375,0.78749996,0.11905508,0.11905503 +0.0375,0.7875,0.08418466,0.1683693 +0.0375,0.7875,0.16836931,0.08418465 +0.0375,0.8125,0.075,0.07500005 +0.0375,0.8125,0.05303301,0.10606599 +0.037499998,0.8125,0.10606601,0.053033054 +0.0375,0.8125,0.094494075,0.094494104 +0.0375,0.8125,0.0668174,0.1336348 +0.0375,0.8125,0.1336348,0.06681746 +0.0375,0.8125,0.11905508,0.11905503 +0.0375,0.8125,0.08418466,0.1683693 +0.0375,0.8125,0.16836931,0.08418465 +0.0375,0.8375,0.075,0.07499999 +0.0375,0.8375,0.05303301,0.10606599 +0.037499998,0.8375,0.10606601,0.053033054 +0.0375,0.8375,0.094494075,0.094494045 +0.0375,0.8375,0.0668174,0.1336348 +0.0375,0.8375,0.1336348,0.06681746 +0.0375,0.8375,0.11905508,0.11905503 +0.0375,0.8375,0.08418466,0.1683693 +0.0375,0.8375,0.16836931,0.08418465 +0.0375,0.86249995,0.075,0.07499999 +0.0375,0.86249995,0.05303301,0.10606593 +0.037499998,0.86249995,0.10606601,0.053033054 +0.0375,0.86249995,0.094494075,0.094494045 +0.0375,0.86249995,0.0668174,0.1336348 +0.0375,0.86249995,0.1336348,0.06681746 +0.0375,0.86249995,0.11905508,0.11905497 +0.0375,0.8625,0.08418466,0.1683693 +0.0375,0.8625,0.16836931,0.08418465 +0.0375,0.88750005,0.075,0.07499999 +0.0375,0.88750005,0.05303301,0.10606593 +0.037499998,0.88750005,0.10606601,0.053033054 +0.0375,0.88750005,0.094494075,0.094494045 +0.0375,0.88750005,0.0668174,0.13363475 +0.0375,0.88750005,0.1336348,0.06681746 +0.0375,0.88750005,0.11905508,0.11905497 +0.0375,0.8875,0.08418466,0.1683693 +0.0375,0.8875,0.16836931,0.08418465 +0.0375,0.9125,0.075,0.07499999 +0.0375,0.9125,0.05303301,0.10606593 +0.037499998,0.9125,0.10606601,0.053033054 +0.0375,0.9125,0.094494075,0.094494045 +0.0375,0.9125,0.0668174,0.13363475 +0.0375,0.9125,0.1336348,0.06681746 +0.0375,0.9125,0.11905508,0.11905497 +0.0375,0.9125,0.08418466,0.1683693 +0.0375,0.9125,0.16836931,0.08418465 +0.0375,0.9375,0.075,0.07500005 +0.0375,0.9375,0.05303301,0.10606599 +0.037499998,0.9375,0.10606601,0.053033113 +0.0375,0.9375,0.094494075,0.094494104 +0.0375,0.9375,0.0668174,0.1336348 +0.0375,0.9375,0.1336348,0.06681752 +0.0375,0.9375,0.11905508,0.11905503 +0.0375,0.9375,0.08418466,0.1683693 +0.0375,0.9375,0.16836931,0.08418465 +0.0375,0.9625,0.075,0.07499999 +0.0375,0.9625,0.05303301,0.10606593 +0.037499998,0.9625,0.10606601,0.053033054 +0.0375,0.9625,0.094494075,0.094494045 +0.0375,0.9625,0.0668174,0.13363475 +0.0375,0.9625,0.1336348,0.06681746 +0.0375,0.9625,0.11905508,0.11905497 +0.0375,0.9625,0.08418466,0.1683693 +0.0375,0.9625,0.16836931,0.08418465 +0.0375,0.98749995,0.075,0.07499999 +0.0375,0.98749995,0.05303301,0.10606593 +0.037499998,0.98749995,0.10606601,0.053033054 +0.0375,0.98749995,0.094494075,0.094494045 +0.0375,0.98749995,0.0668174,0.13363475 +0.0375,0.98749995,0.1336348,0.06681746 +0.0375,0.98749995,0.11905508,0.11905497 +0.0375,0.98749995,0.08418466,0.16836923 +0.0375,0.98749995,0.16836931,0.08418459 +0.0625,0.0125,0.075,0.075 +0.0625,0.012499997,0.05303301,0.10606602 +0.0625,0.012499999,0.10606602,0.05303301 +0.0625,0.012499999,0.094494075,0.09449408 +0.0625,0.012500001,0.0668174,0.1336348 +0.0625,0.012499999,0.1336348,0.0668174 +0.0625,0.012500001,0.11905508,0.11905508 +0.0625,0.012499999,0.08418465,0.1683693 +0.0625,0.012500002,0.16836932,0.084184654 +0.0625,0.0375,0.075,0.075 +0.0625,0.037499998,0.05303301,0.10606601 +0.0625,0.0375,0.10606602,0.05303301 +0.0625,0.0375,0.094494075,0.094494075 +0.0625,0.0375,0.0668174,0.1336348 +0.0625,0.0375,0.1336348,0.0668174 +0.0625,0.0375,0.11905508,0.11905508 +0.0625,0.0375,0.08418465,0.16836931 +0.0625,0.0375,0.16836932,0.08418466 +0.0625,0.0625,0.075,0.075 +0.0625,0.0625,0.05303301,0.10606602 +0.0625,0.0625,0.10606602,0.05303301 +0.0625,0.0625,0.094494075,0.094494075 +0.0625,0.0625,0.0668174,0.1336348 +0.0625,0.0625,0.1336348,0.0668174 +0.0625,0.0625,0.11905508,0.11905508 +0.0625,0.0625,0.08418465,0.16836932 +0.0625,0.0625,0.16836932,0.08418465 +0.0625,0.0875,0.075,0.075 +0.0625,0.08749999,0.05303301,0.10606601 +0.0625,0.087500006,0.10606602,0.053033013 +0.0625,0.087500006,0.094494075,0.09449408 +0.0625,0.087500006,0.0668174,0.1336348 +0.0625,0.0875,0.1336348,0.0668174 +0.0625,0.0875,0.11905508,0.11905508 +0.0625,0.0875,0.08418465,0.16836931 +0.0625,0.087500006,0.16836932,0.084184654 +0.0625,0.112500004,0.075,0.075 +0.0625,0.1125,0.05303301,0.10606601 +0.0625,0.112500004,0.10606602,0.05303301 +0.0625,0.1125,0.094494075,0.094494075 +0.0625,0.1125,0.0668174,0.1336348 +0.0625,0.1125,0.1336348,0.0668174 +0.0625,0.1125,0.11905508,0.119055085 +0.0625,0.112500004,0.08418465,0.16836931 +0.0625,0.1125,0.16836932,0.08418465 +0.0625,0.1375,0.075,0.074999996 +0.0625,0.1375,0.05303301,0.10606602 +0.0625,0.1375,0.10606602,0.053033024 +0.0625,0.1375,0.094494075,0.09449408 +0.0625,0.1375,0.0668174,0.1336348 +0.0625,0.1375,0.1336348,0.0668174 +0.0625,0.13749999,0.11905508,0.11905508 +0.0625,0.1375,0.08418465,0.1683693 +0.0625,0.1375,0.16836932,0.084184654 +0.0625,0.1625,0.075,0.075 +0.0625,0.16250001,0.05303301,0.106066026 +0.0625,0.1625,0.10606602,0.05303301 +0.0625,0.1625,0.094494075,0.094494075 +0.0625,0.1625,0.0668174,0.1336348 +0.0625,0.1625,0.1336348,0.0668174 +0.0625,0.1625,0.11905508,0.11905508 +0.0625,0.1625,0.08418465,0.1683693 +0.0625,0.1625,0.16836932,0.08418464 +0.0625,0.1875,0.075,0.07499999 +0.0625,0.1875,0.05303301,0.10606603 +0.0625,0.1875,0.10606602,0.053033024 +0.0625,0.1875,0.094494075,0.09449406 +0.0625,0.1875,0.0668174,0.1336348 +0.0625,0.1875,0.1336348,0.06681742 +0.0625,0.1875,0.11905508,0.11905509 +0.0625,0.1875,0.08418465,0.16836931 +0.0625,0.1875,0.16836932,0.08418465 +0.0625,0.2125,0.075,0.075 +0.0625,0.2125,0.05303301,0.10606603 +0.0625,0.2125,0.10606602,0.05303301 +0.0625,0.21249999,0.094494075,0.094494075 +0.0625,0.2125,0.0668174,0.1336348 +0.0625,0.2125,0.1336348,0.0668174 +0.0625,0.2125,0.11905508,0.11905509 +0.0625,0.2125,0.08418465,0.16836931 +0.0625,0.2125,0.16836932,0.08418465 +0.0625,0.23750001,0.075,0.075 +0.0625,0.2375,0.05303301,0.10606602 +0.0625,0.2375,0.10606602,0.053033024 +0.0625,0.2375,0.094494075,0.094494075 +0.0625,0.23750001,0.0668174,0.13363482 +0.0625,0.2375,0.1336348,0.06681743 +0.0625,0.2375,0.11905508,0.11905506 +0.0625,0.2375,0.08418465,0.16836932 +0.0625,0.23750001,0.16836932,0.08418466 +0.0625,0.2625,0.075,0.07500002 +0.0625,0.2625,0.05303301,0.10606603 +0.0625,0.2625,0.10606602,0.053033024 +0.0625,0.2625,0.094494075,0.094494075 +0.0625,0.2625,0.0668174,0.13363479 +0.0625,0.2625,0.1336348,0.06681743 +0.0625,0.2625,0.11905508,0.11905508 +0.0625,0.2625,0.08418465,0.1683693 +0.0625,0.2625,0.16836932,0.08418463 +0.0625,0.2875,0.075,0.07499999 +0.0625,0.2875,0.05303301,0.10606603 +0.0625,0.28750002,0.10606602,0.053033024 +0.0625,0.2875,0.094494075,0.094494045 +0.0625,0.2875,0.0668174,0.1336348 +0.0625,0.28750002,0.1336348,0.06681743 +0.0625,0.2875,0.11905508,0.11905508 +0.0625,0.2875,0.08418465,0.1683693 +0.0625,0.2875,0.16836932,0.08418465 +0.0625,0.3125,0.075,0.07499999 +0.0625,0.3125,0.05303301,0.10606605 +0.0625,0.3125,0.10606602,0.053032994 +0.0625,0.3125,0.094494075,0.094494045 +0.0625,0.3125,0.0668174,0.1336348 +0.0625,0.3125,0.1336348,0.0668174 +0.0625,0.3125,0.11905508,0.11905509 +0.0625,0.3125,0.08418465,0.1683693 +0.0625,0.3125,0.16836932,0.08418465 +0.0625,0.3375,0.075,0.07499999 +0.0625,0.3375,0.05303301,0.10606605 +0.0625,0.33749998,0.10606602,0.053033024 +0.0625,0.3375,0.094494075,0.094494045 +0.0625,0.33750004,0.0668174,0.13363484 +0.0625,0.33749998,0.1336348,0.06681743 +0.0625,0.3375,0.11905508,0.11905509 +0.0625,0.3375,0.08418465,0.1683693 +0.0625,0.3375,0.16836932,0.08418465 +0.0625,0.3625,0.075,0.07500002 +0.0625,0.3625,0.05303301,0.10606602 +0.0625,0.3625,0.10606602,0.053033024 +0.0625,0.3625,0.094494075,0.094494075 +0.0625,0.3625,0.0668174,0.1336348 +0.0625,0.3625,0.1336348,0.06681743 +0.0625,0.3625,0.11905508,0.11905506 +0.0625,0.3625,0.08418465,0.1683693 +0.0625,0.3625,0.16836932,0.08418465 +0.0625,0.3875,0.075,0.07500002 +0.0625,0.3875,0.05303301,0.10606602 +0.0625,0.3875,0.10606602,0.053032994 +0.0625,0.3875,0.094494075,0.094494075 +0.0625,0.3875,0.0668174,0.13363484 +0.0625,0.3875,0.1336348,0.0668174 +0.0625,0.3875,0.11905508,0.11905506 +0.0625,0.3875,0.08418465,0.1683693 +0.0625,0.3875,0.16836932,0.08418465 +0.0625,0.4125,0.075,0.07499999 +0.0625,0.4125,0.05303301,0.10606605 +0.0625,0.4125,0.10606602,0.053032994 +0.0625,0.4125,0.094494075,0.094494045 +0.0625,0.41250002,0.0668174,0.13363484 +0.0625,0.4125,0.1336348,0.0668174 +0.0625,0.4125,0.11905508,0.11905509 +0.0625,0.4125,0.08418465,0.1683693 +0.0625,0.4125,0.16836932,0.08418465 +0.0625,0.4375,0.075,0.07499999 +0.0625,0.4375,0.05303301,0.10606605 +0.0625,0.4375,0.10606602,0.053032994 +0.0625,0.4375,0.094494075,0.094494045 +0.0625,0.4375,0.0668174,0.1336348 +0.0625,0.4375,0.1336348,0.0668174 +0.0625,0.4375,0.11905508,0.11905509 +0.0625,0.4375,0.08418465,0.1683693 +0.0625,0.4375,0.16836932,0.08418465 +0.0625,0.4625,0.075,0.07499999 +0.0625,0.4625,0.05303301,0.10606605 +0.0625,0.46249998,0.10606602,0.053032964 +0.0625,0.4625,0.094494075,0.094494045 +0.0625,0.46250004,0.0668174,0.13363484 +0.0625,0.46249998,0.1336348,0.06681737 +0.0625,0.4625,0.11905508,0.11905509 +0.0625,0.46249998,0.08418465,0.16836926 +0.0625,0.46249998,0.16836932,0.08418462 +0.0625,0.48749998,0.075,0.07499999 +0.0625,0.4875,0.05303301,0.10606602 +0.0625,0.4875,0.10606602,0.053032994 +0.0625,0.48749998,0.094494075,0.094494045 +0.0625,0.4875,0.0668174,0.13363484 +0.0625,0.4875,0.1336348,0.0668174 +0.0625,0.4875,0.11905508,0.11905506 +0.0625,0.4875,0.08418465,0.1683693 +0.0625,0.4875,0.16836932,0.08418465 +0.0625,0.5125,0.075,0.07500002 +0.0625,0.51250005,0.05303301,0.10606605 +0.0625,0.5125,0.10606602,0.053032964 +0.0625,0.5125,0.094494075,0.094494075 +0.0625,0.51250005,0.0668174,0.13363487 +0.0625,0.5125,0.1336348,0.06681737 +0.0625,0.51250005,0.11905508,0.11905509 +0.0625,0.5125,0.08418465,0.1683693 +0.0625,0.5125,0.16836932,0.08418465 +0.0625,0.5375,0.075,0.07499999 +0.0625,0.5375,0.05303301,0.10606605 +0.0625,0.5375,0.10606602,0.053032935 +0.0625,0.5375,0.094494075,0.094494045 +0.0625,0.5375,0.0668174,0.13363487 +0.0625,0.5375,0.1336348,0.06681734 +0.0625,0.5375,0.11905508,0.11905509 +0.0625,0.5375,0.08418465,0.16836932 +0.0625,0.5375,0.16836932,0.08418468 +0.0625,0.5625,0.075,0.07500005 +0.0625,0.5625,0.05303301,0.10606599 +0.0625,0.5625,0.10606602,0.053032994 +0.0625,0.5625,0.094494075,0.094494104 +0.0625,0.5625,0.0668174,0.13363484 +0.0625,0.5625,0.1336348,0.0668174 +0.0625,0.5625,0.11905508,0.11905503 +0.0625,0.5625,0.08418465,0.1683693 +0.0625,0.5625,0.16836932,0.08418465 +0.0625,0.5875,0.075,0.07499999 +0.0625,0.5875,0.05303301,0.10606605 +0.0625,0.5875,0.10606602,0.053032935 +0.0625,0.5875,0.094494075,0.094494045 +0.0625,0.5875,0.0668174,0.13363487 +0.0625,0.5875,0.1336348,0.06681734 +0.0625,0.5875,0.11905508,0.11905509 +0.0625,0.5875,0.08418465,0.1683693 +0.0625,0.5875,0.16836932,0.08418465 +0.0625,0.61249995,0.075,0.07499999 +0.0625,0.61249995,0.05303301,0.10606605 +0.0625,0.6125,0.10606602,0.053032994 +0.0625,0.61249995,0.094494075,0.094494045 +0.0625,0.61249995,0.0668174,0.13363487 +0.0625,0.6125,0.1336348,0.0668174 +0.0625,0.61249995,0.11905508,0.11905509 +0.0625,0.6125,0.08418465,0.1683693 +0.0625,0.6125,0.16836932,0.08418465 +0.0625,0.63750005,0.075,0.07499999 +0.0625,0.63750005,0.05303301,0.10606605 +0.0625,0.6375,0.10606602,0.053032994 +0.0625,0.63750005,0.094494075,0.094494045 +0.0625,0.63750005,0.0668174,0.13363487 +0.0625,0.6375,0.1336348,0.0668174 +0.0625,0.63750005,0.11905508,0.11905509 +0.0625,0.6375,0.08418465,0.1683693 +0.0625,0.6375,0.16836932,0.08418465 +0.0625,0.6625,0.075,0.07499999 +0.0625,0.6625,0.05303301,0.10606605 +0.0625,0.6625,0.10606602,0.053032935 +0.0625,0.6625,0.094494075,0.094494045 +0.0625,0.6625,0.0668174,0.13363487 +0.0625,0.6625,0.1336348,0.06681734 +0.0625,0.6625,0.11905508,0.11905509 +0.0625,0.6625,0.08418465,0.1683693 +0.0625,0.6625,0.16836932,0.08418465 +0.0625,0.6875,0.075,0.07500005 +0.0625,0.6875,0.05303301,0.10606599 +0.0625,0.6875,0.10606602,0.053032994 +0.0625,0.6875,0.094494075,0.094494104 +0.0625,0.6875,0.0668174,0.1336348 +0.0625,0.6875,0.1336348,0.0668174 +0.0625,0.6875,0.11905508,0.11905503 +0.0625,0.6875,0.08418465,0.1683693 +0.0625,0.6875,0.16836932,0.08418465 +0.0625,0.7125,0.075,0.07499999 +0.0625,0.7125,0.05303301,0.10606605 +0.0625,0.7125,0.10606602,0.053032935 +0.0625,0.7125,0.094494075,0.094494045 +0.0625,0.7125,0.0668174,0.13363487 +0.0625,0.7125,0.1336348,0.06681734 +0.0625,0.7125,0.11905508,0.11905509 +0.0625,0.7125,0.08418465,0.1683693 +0.0625,0.7125,0.16836932,0.08418465 +0.0625,0.73749995,0.075,0.07499999 +0.0625,0.73749995,0.05303301,0.10606605 +0.0625,0.7375,0.10606602,0.053032994 +0.0625,0.73749995,0.094494075,0.094494045 +0.0625,0.73749995,0.0668174,0.1336348 +0.0625,0.7375,0.1336348,0.0668174 +0.0625,0.73749995,0.11905508,0.11905509 +0.0625,0.7375,0.08418465,0.1683693 +0.0625,0.7375,0.16836932,0.08418465 +0.0625,0.76250005,0.075,0.07499999 +0.0625,0.7625,0.05303301,0.10606599 +0.0625,0.7625,0.10606602,0.053032994 +0.0625,0.76250005,0.094494075,0.094494045 +0.0625,0.7625,0.0668174,0.1336348 +0.0625,0.7625,0.1336348,0.0668174 +0.0625,0.7625,0.11905508,0.11905503 +0.0625,0.7625,0.08418465,0.1683693 +0.0625,0.7625,0.16836932,0.08418465 +0.0625,0.7875,0.075,0.07499999 +0.0625,0.78749996,0.05303301,0.10606599 +0.0625,0.7875,0.10606602,0.053032994 +0.0625,0.7875,0.094494075,0.094494045 +0.0625,0.78749996,0.0668174,0.1336348 +0.0625,0.7875,0.1336348,0.0668174 +0.0625,0.78749996,0.11905508,0.11905503 +0.0625,0.7875,0.08418465,0.1683693 +0.0625,0.7875,0.16836932,0.08418465 +0.0625,0.8125,0.075,0.07500005 +0.0625,0.8125,0.05303301,0.10606599 +0.0625,0.8125,0.10606602,0.053033054 +0.0625,0.8125,0.094494075,0.094494104 +0.0625,0.8125,0.0668174,0.1336348 +0.0625,0.8125,0.1336348,0.06681746 +0.0625,0.8125,0.11905508,0.11905503 +0.0625,0.8125,0.08418465,0.1683693 +0.0625,0.8125,0.16836932,0.08418465 +0.0625,0.8375,0.075,0.07499999 +0.0625,0.8375,0.05303301,0.10606599 +0.0625,0.8375,0.10606602,0.053033054 +0.0625,0.8375,0.094494075,0.094494045 +0.0625,0.8375,0.0668174,0.1336348 +0.0625,0.8375,0.1336348,0.06681746 +0.0625,0.8375,0.11905508,0.11905503 +0.0625,0.8375,0.08418465,0.1683693 +0.0625,0.8375,0.16836932,0.08418465 +0.0625,0.86249995,0.075,0.07499999 +0.0625,0.86249995,0.05303301,0.10606593 +0.0625,0.86249995,0.10606602,0.053033054 +0.0625,0.86249995,0.094494075,0.094494045 +0.0625,0.86249995,0.0668174,0.1336348 +0.0625,0.86249995,0.1336348,0.06681746 +0.0625,0.86249995,0.11905508,0.11905497 +0.0625,0.8625,0.08418465,0.1683693 +0.0625,0.8625,0.16836932,0.08418465 +0.0625,0.88750005,0.075,0.07499999 +0.0625,0.88750005,0.05303301,0.10606593 +0.0625,0.88750005,0.10606602,0.053033054 +0.0625,0.88750005,0.094494075,0.094494045 +0.0625,0.88750005,0.0668174,0.13363475 +0.0625,0.88750005,0.1336348,0.06681746 +0.0625,0.88750005,0.11905508,0.11905497 +0.0625,0.8875,0.08418465,0.1683693 +0.0625,0.8875,0.16836932,0.08418465 +0.0625,0.9125,0.075,0.07499999 +0.0625,0.9125,0.05303301,0.10606593 +0.0625,0.9125,0.10606602,0.053033054 +0.0625,0.9125,0.094494075,0.094494045 +0.0625,0.9125,0.0668174,0.13363475 +0.0625,0.9125,0.1336348,0.06681746 +0.0625,0.9125,0.11905508,0.11905497 +0.0625,0.9125,0.08418465,0.1683693 +0.0625,0.9125,0.16836932,0.08418465 +0.0625,0.9375,0.075,0.07500005 +0.0625,0.9375,0.05303301,0.10606599 +0.0625,0.9375,0.10606602,0.053033113 +0.0625,0.9375,0.094494075,0.094494104 +0.0625,0.9375,0.0668174,0.1336348 +0.0625,0.9375,0.1336348,0.06681752 +0.0625,0.9375,0.11905508,0.11905503 +0.0625,0.9375,0.08418465,0.1683693 +0.0625,0.9375,0.16836932,0.08418465 +0.0625,0.9625,0.075,0.07499999 +0.0625,0.9625,0.05303301,0.10606593 +0.0625,0.9625,0.10606602,0.053033054 +0.0625,0.9625,0.094494075,0.094494045 +0.0625,0.9625,0.0668174,0.13363475 +0.0625,0.9625,0.1336348,0.06681746 +0.0625,0.9625,0.11905508,0.11905497 +0.0625,0.9625,0.08418465,0.1683693 +0.0625,0.9625,0.16836932,0.08418465 +0.0625,0.98749995,0.075,0.07499999 +0.0625,0.98749995,0.05303301,0.10606593 +0.0625,0.98749995,0.10606602,0.053033054 +0.0625,0.98749995,0.094494075,0.094494045 +0.0625,0.98749995,0.0668174,0.13363475 +0.0625,0.98749995,0.1336348,0.06681746 +0.0625,0.98749995,0.11905508,0.11905497 +0.0625,0.98749995,0.08418465,0.16836923 +0.0625,0.98749995,0.16836932,0.08418459 +0.0875,0.0125,0.075,0.075 +0.087500006,0.012499997,0.053033013,0.10606602 +0.08749999,0.012499999,0.10606601,0.05303301 +0.087500006,0.012499999,0.09449408,0.09449408 +0.0875,0.012500001,0.0668174,0.1336348 +0.087500006,0.012499999,0.1336348,0.0668174 +0.0875,0.012500001,0.11905508,0.11905508 +0.087500006,0.012499999,0.084184654,0.1683693 +0.0875,0.012500002,0.16836931,0.084184654 +0.0875,0.0375,0.075,0.075 +0.087500006,0.037499998,0.053033013,0.10606601 +0.08749999,0.0375,0.10606601,0.05303301 +0.087500006,0.0375,0.09449408,0.094494075 +0.0875,0.0375,0.0668174,0.1336348 +0.087500006,0.0375,0.1336348,0.0668174 +0.0875,0.0375,0.11905508,0.11905508 +0.087500006,0.0375,0.084184654,0.16836931 +0.0875,0.0375,0.16836931,0.08418466 +0.0875,0.0625,0.075,0.075 +0.087500006,0.0625,0.053033013,0.10606602 +0.08749999,0.0625,0.10606601,0.05303301 +0.087500006,0.0625,0.09449408,0.094494075 +0.0875,0.0625,0.0668174,0.1336348 +0.087500006,0.0625,0.1336348,0.0668174 +0.0875,0.0625,0.11905508,0.11905508 +0.087500006,0.0625,0.084184654,0.16836932 +0.0875,0.0625,0.16836931,0.08418465 +0.0875,0.0875,0.075,0.075 +0.087500006,0.08749999,0.053033013,0.10606601 +0.08749999,0.087500006,0.10606601,0.053033013 +0.087500006,0.087500006,0.09449408,0.09449408 +0.0875,0.087500006,0.0668174,0.1336348 +0.087500006,0.0875,0.1336348,0.0668174 +0.0875,0.0875,0.11905508,0.11905508 +0.087500006,0.0875,0.084184654,0.16836931 +0.0875,0.087500006,0.16836931,0.084184654 +0.0875,0.112500004,0.075,0.075 +0.087500006,0.1125,0.053033013,0.10606601 +0.08749999,0.112500004,0.10606601,0.05303301 +0.087500006,0.1125,0.09449408,0.094494075 +0.0875,0.1125,0.0668174,0.1336348 +0.087500006,0.1125,0.1336348,0.0668174 +0.0875,0.1125,0.11905508,0.119055085 +0.087500006,0.112500004,0.084184654,0.16836931 +0.0875,0.1125,0.16836931,0.08418465 +0.0875,0.1375,0.075,0.074999996 +0.087500006,0.1375,0.053033013,0.10606602 +0.08749999,0.1375,0.10606601,0.053033024 +0.087500006,0.1375,0.09449408,0.09449408 +0.0875,0.1375,0.0668174,0.1336348 +0.087500006,0.1375,0.1336348,0.0668174 +0.0875,0.13749999,0.11905508,0.11905508 +0.087500006,0.1375,0.084184654,0.1683693 +0.0875,0.1375,0.16836931,0.084184654 +0.0875,0.1625,0.075,0.075 +0.087500006,0.16250001,0.053033013,0.106066026 +0.08749999,0.1625,0.10606601,0.05303301 +0.087500006,0.1625,0.09449408,0.094494075 +0.0875,0.1625,0.0668174,0.1336348 +0.087500006,0.1625,0.1336348,0.0668174 +0.0875,0.1625,0.11905508,0.11905508 +0.087500006,0.1625,0.084184654,0.1683693 +0.0875,0.1625,0.16836931,0.08418464 +0.0875,0.1875,0.075,0.07499999 +0.087500006,0.1875,0.053033013,0.10606603 +0.08749999,0.1875,0.10606601,0.053033024 +0.087500006,0.1875,0.09449408,0.09449406 +0.0875,0.1875,0.0668174,0.1336348 +0.087500006,0.1875,0.1336348,0.06681742 +0.0875,0.1875,0.11905508,0.11905509 +0.087500006,0.1875,0.084184654,0.16836931 +0.0875,0.1875,0.16836931,0.08418465 +0.0875,0.2125,0.075,0.075 +0.087500006,0.2125,0.053033013,0.10606603 +0.08749999,0.2125,0.10606601,0.05303301 +0.087500006,0.21249999,0.09449408,0.094494075 +0.0875,0.2125,0.0668174,0.1336348 +0.087500006,0.2125,0.1336348,0.0668174 +0.0875,0.2125,0.11905508,0.11905509 +0.087500006,0.2125,0.084184654,0.16836931 +0.0875,0.2125,0.16836931,0.08418465 +0.0875,0.23750001,0.075,0.075 +0.087500006,0.2375,0.053033013,0.10606602 +0.08749999,0.2375,0.10606601,0.053033024 +0.087500006,0.2375,0.09449408,0.094494075 +0.0875,0.23750001,0.0668174,0.13363482 +0.087500006,0.2375,0.1336348,0.06681743 +0.0875,0.2375,0.11905508,0.11905506 +0.087500006,0.2375,0.084184654,0.16836932 +0.0875,0.23750001,0.16836931,0.08418466 +0.0875,0.2625,0.075,0.07500002 +0.087500006,0.2625,0.053033013,0.10606603 +0.08749999,0.2625,0.10606601,0.053033024 +0.087500006,0.2625,0.09449408,0.094494075 +0.0875,0.2625,0.0668174,0.13363479 +0.087500006,0.2625,0.1336348,0.06681743 +0.0875,0.2625,0.11905508,0.11905508 +0.087500006,0.2625,0.084184654,0.1683693 +0.0875,0.2625,0.16836931,0.08418463 +0.0875,0.2875,0.075,0.07499999 +0.087500006,0.2875,0.053033013,0.10606603 +0.08749999,0.28750002,0.10606601,0.053033024 +0.087500006,0.2875,0.09449408,0.094494045 +0.0875,0.2875,0.0668174,0.1336348 +0.087500006,0.28750002,0.1336348,0.06681743 +0.0875,0.2875,0.11905508,0.11905508 +0.087500006,0.2875,0.084184654,0.1683693 +0.0875,0.2875,0.16836931,0.08418465 +0.0875,0.3125,0.075,0.07499999 +0.087500006,0.3125,0.053033013,0.10606605 +0.08749999,0.3125,0.10606601,0.053032994 +0.087500006,0.3125,0.09449408,0.094494045 +0.0875,0.3125,0.0668174,0.1336348 +0.087500006,0.3125,0.1336348,0.0668174 +0.0875,0.3125,0.11905508,0.11905509 +0.087500006,0.3125,0.084184654,0.1683693 +0.0875,0.3125,0.16836931,0.08418465 +0.0875,0.3375,0.075,0.07499999 +0.087500006,0.3375,0.053033013,0.10606605 +0.08749999,0.33749998,0.10606601,0.053033024 +0.087500006,0.3375,0.09449408,0.094494045 +0.0875,0.33750004,0.0668174,0.13363484 +0.087500006,0.33749998,0.1336348,0.06681743 +0.0875,0.3375,0.11905508,0.11905509 +0.087500006,0.3375,0.084184654,0.1683693 +0.0875,0.3375,0.16836931,0.08418465 +0.0875,0.3625,0.075,0.07500002 +0.087500006,0.3625,0.053033013,0.10606602 +0.08749999,0.3625,0.10606601,0.053033024 +0.087500006,0.3625,0.09449408,0.094494075 +0.0875,0.3625,0.0668174,0.1336348 +0.087500006,0.3625,0.1336348,0.06681743 +0.0875,0.3625,0.11905508,0.11905506 +0.087500006,0.3625,0.084184654,0.1683693 +0.0875,0.3625,0.16836931,0.08418465 +0.0875,0.3875,0.075,0.07500002 +0.087500006,0.3875,0.053033013,0.10606602 +0.08749999,0.3875,0.10606601,0.053032994 +0.087500006,0.3875,0.09449408,0.094494075 +0.0875,0.3875,0.0668174,0.13363484 +0.087500006,0.3875,0.1336348,0.0668174 +0.0875,0.3875,0.11905508,0.11905506 +0.087500006,0.3875,0.084184654,0.1683693 +0.0875,0.3875,0.16836931,0.08418465 +0.0875,0.4125,0.075,0.07499999 +0.087500006,0.4125,0.053033013,0.10606605 +0.08749999,0.4125,0.10606601,0.053032994 +0.087500006,0.4125,0.09449408,0.094494045 +0.0875,0.41250002,0.0668174,0.13363484 +0.087500006,0.4125,0.1336348,0.0668174 +0.0875,0.4125,0.11905508,0.11905509 +0.087500006,0.4125,0.084184654,0.1683693 +0.0875,0.4125,0.16836931,0.08418465 +0.0875,0.4375,0.075,0.07499999 +0.087500006,0.4375,0.053033013,0.10606605 +0.08749999,0.4375,0.10606601,0.053032994 +0.087500006,0.4375,0.09449408,0.094494045 +0.0875,0.4375,0.0668174,0.1336348 +0.087500006,0.4375,0.1336348,0.0668174 +0.0875,0.4375,0.11905508,0.11905509 +0.087500006,0.4375,0.084184654,0.1683693 +0.0875,0.4375,0.16836931,0.08418465 +0.0875,0.4625,0.075,0.07499999 +0.087500006,0.4625,0.053033013,0.10606605 +0.08749999,0.46249998,0.10606601,0.053032964 +0.087500006,0.4625,0.09449408,0.094494045 +0.0875,0.46250004,0.0668174,0.13363484 +0.087500006,0.46249998,0.1336348,0.06681737 +0.0875,0.4625,0.11905508,0.11905509 +0.087500006,0.46249998,0.084184654,0.16836926 +0.0875,0.46249998,0.16836931,0.08418462 +0.0875,0.48749998,0.075,0.07499999 +0.087500006,0.4875,0.053033013,0.10606602 +0.08749999,0.4875,0.10606601,0.053032994 +0.087500006,0.48749998,0.09449408,0.094494045 +0.0875,0.4875,0.0668174,0.13363484 +0.087500006,0.4875,0.1336348,0.0668174 +0.0875,0.4875,0.11905508,0.11905506 +0.087500006,0.4875,0.084184654,0.1683693 +0.0875,0.4875,0.16836931,0.08418465 +0.0875,0.5125,0.075,0.07500002 +0.087500006,0.51250005,0.053033013,0.10606605 +0.08749999,0.5125,0.10606601,0.053032964 +0.087500006,0.5125,0.09449408,0.094494075 +0.0875,0.51250005,0.0668174,0.13363487 +0.087500006,0.5125,0.1336348,0.06681737 +0.0875,0.51250005,0.11905508,0.11905509 +0.087500006,0.5125,0.084184654,0.1683693 +0.0875,0.5125,0.16836931,0.08418465 +0.0875,0.5375,0.075,0.07499999 +0.087500006,0.5375,0.053033013,0.10606605 +0.08749999,0.5375,0.10606601,0.053032935 +0.087500006,0.5375,0.09449408,0.094494045 +0.0875,0.5375,0.0668174,0.13363487 +0.087500006,0.5375,0.1336348,0.06681734 +0.0875,0.5375,0.11905508,0.11905509 +0.087500006,0.5375,0.084184654,0.16836932 +0.0875,0.5375,0.16836931,0.08418468 +0.0875,0.5625,0.075,0.07500005 +0.087500006,0.5625,0.053033013,0.10606599 +0.08749999,0.5625,0.10606601,0.053032994 +0.087500006,0.5625,0.09449408,0.094494104 +0.0875,0.5625,0.0668174,0.13363484 +0.087500006,0.5625,0.1336348,0.0668174 +0.0875,0.5625,0.11905508,0.11905503 +0.087500006,0.5625,0.084184654,0.1683693 +0.0875,0.5625,0.16836931,0.08418465 +0.0875,0.5875,0.075,0.07499999 +0.087500006,0.5875,0.053033013,0.10606605 +0.08749999,0.5875,0.10606601,0.053032935 +0.087500006,0.5875,0.09449408,0.094494045 +0.0875,0.5875,0.0668174,0.13363487 +0.087500006,0.5875,0.1336348,0.06681734 +0.0875,0.5875,0.11905508,0.11905509 +0.087500006,0.5875,0.084184654,0.1683693 +0.0875,0.5875,0.16836931,0.08418465 +0.0875,0.61249995,0.075,0.07499999 +0.087500006,0.61249995,0.053033013,0.10606605 +0.08749999,0.6125,0.10606601,0.053032994 +0.087500006,0.61249995,0.09449408,0.094494045 +0.0875,0.61249995,0.0668174,0.13363487 +0.087500006,0.6125,0.1336348,0.0668174 +0.0875,0.61249995,0.11905508,0.11905509 +0.087500006,0.6125,0.084184654,0.1683693 +0.0875,0.6125,0.16836931,0.08418465 +0.0875,0.63750005,0.075,0.07499999 +0.087500006,0.63750005,0.053033013,0.10606605 +0.08749999,0.6375,0.10606601,0.053032994 +0.087500006,0.63750005,0.09449408,0.094494045 +0.0875,0.63750005,0.0668174,0.13363487 +0.087500006,0.6375,0.1336348,0.0668174 +0.0875,0.63750005,0.11905508,0.11905509 +0.087500006,0.6375,0.084184654,0.1683693 +0.0875,0.6375,0.16836931,0.08418465 +0.0875,0.6625,0.075,0.07499999 +0.087500006,0.6625,0.053033013,0.10606605 +0.08749999,0.6625,0.10606601,0.053032935 +0.087500006,0.6625,0.09449408,0.094494045 +0.0875,0.6625,0.0668174,0.13363487 +0.087500006,0.6625,0.1336348,0.06681734 +0.0875,0.6625,0.11905508,0.11905509 +0.087500006,0.6625,0.084184654,0.1683693 +0.0875,0.6625,0.16836931,0.08418465 +0.0875,0.6875,0.075,0.07500005 +0.087500006,0.6875,0.053033013,0.10606599 +0.08749999,0.6875,0.10606601,0.053032994 +0.087500006,0.6875,0.09449408,0.094494104 +0.0875,0.6875,0.0668174,0.1336348 +0.087500006,0.6875,0.1336348,0.0668174 +0.0875,0.6875,0.11905508,0.11905503 +0.087500006,0.6875,0.084184654,0.1683693 +0.0875,0.6875,0.16836931,0.08418465 +0.0875,0.7125,0.075,0.07499999 +0.087500006,0.7125,0.053033013,0.10606605 +0.08749999,0.7125,0.10606601,0.053032935 +0.087500006,0.7125,0.09449408,0.094494045 +0.0875,0.7125,0.0668174,0.13363487 +0.087500006,0.7125,0.1336348,0.06681734 +0.0875,0.7125,0.11905508,0.11905509 +0.087500006,0.7125,0.084184654,0.1683693 +0.0875,0.7125,0.16836931,0.08418465 +0.0875,0.73749995,0.075,0.07499999 +0.087500006,0.73749995,0.053033013,0.10606605 +0.08749999,0.7375,0.10606601,0.053032994 +0.087500006,0.73749995,0.09449408,0.094494045 +0.0875,0.73749995,0.0668174,0.1336348 +0.087500006,0.7375,0.1336348,0.0668174 +0.0875,0.73749995,0.11905508,0.11905509 +0.087500006,0.7375,0.084184654,0.1683693 +0.0875,0.7375,0.16836931,0.08418465 +0.0875,0.76250005,0.075,0.07499999 +0.087500006,0.7625,0.053033013,0.10606599 +0.08749999,0.7625,0.10606601,0.053032994 +0.087500006,0.76250005,0.09449408,0.094494045 +0.0875,0.7625,0.0668174,0.1336348 +0.087500006,0.7625,0.1336348,0.0668174 +0.0875,0.7625,0.11905508,0.11905503 +0.087500006,0.7625,0.084184654,0.1683693 +0.0875,0.7625,0.16836931,0.08418465 +0.0875,0.7875,0.075,0.07499999 +0.087500006,0.78749996,0.053033013,0.10606599 +0.08749999,0.7875,0.10606601,0.053032994 +0.087500006,0.7875,0.09449408,0.094494045 +0.0875,0.78749996,0.0668174,0.1336348 +0.087500006,0.7875,0.1336348,0.0668174 +0.0875,0.78749996,0.11905508,0.11905503 +0.087500006,0.7875,0.084184654,0.1683693 +0.0875,0.7875,0.16836931,0.08418465 +0.0875,0.8125,0.075,0.07500005 +0.087500006,0.8125,0.053033013,0.10606599 +0.08749999,0.8125,0.10606601,0.053033054 +0.087500006,0.8125,0.09449408,0.094494104 +0.0875,0.8125,0.0668174,0.1336348 +0.087500006,0.8125,0.1336348,0.06681746 +0.0875,0.8125,0.11905508,0.11905503 +0.087500006,0.8125,0.084184654,0.1683693 +0.0875,0.8125,0.16836931,0.08418465 +0.0875,0.8375,0.075,0.07499999 +0.087500006,0.8375,0.053033013,0.10606599 +0.08749999,0.8375,0.10606601,0.053033054 +0.087500006,0.8375,0.09449408,0.094494045 +0.0875,0.8375,0.0668174,0.1336348 +0.087500006,0.8375,0.1336348,0.06681746 +0.0875,0.8375,0.11905508,0.11905503 +0.087500006,0.8375,0.084184654,0.1683693 +0.0875,0.8375,0.16836931,0.08418465 +0.0875,0.86249995,0.075,0.07499999 +0.087500006,0.86249995,0.053033013,0.10606593 +0.08749999,0.86249995,0.10606601,0.053033054 +0.087500006,0.86249995,0.09449408,0.094494045 +0.0875,0.86249995,0.0668174,0.1336348 +0.087500006,0.86249995,0.1336348,0.06681746 +0.0875,0.86249995,0.11905508,0.11905497 +0.087500006,0.8625,0.084184654,0.1683693 +0.0875,0.8625,0.16836931,0.08418465 +0.0875,0.88750005,0.075,0.07499999 +0.087500006,0.88750005,0.053033013,0.10606593 +0.08749999,0.88750005,0.10606601,0.053033054 +0.087500006,0.88750005,0.09449408,0.094494045 +0.0875,0.88750005,0.0668174,0.13363475 +0.087500006,0.88750005,0.1336348,0.06681746 +0.0875,0.88750005,0.11905508,0.11905497 +0.087500006,0.8875,0.084184654,0.1683693 +0.0875,0.8875,0.16836931,0.08418465 +0.0875,0.9125,0.075,0.07499999 +0.087500006,0.9125,0.053033013,0.10606593 +0.08749999,0.9125,0.10606601,0.053033054 +0.087500006,0.9125,0.09449408,0.094494045 +0.0875,0.9125,0.0668174,0.13363475 +0.087500006,0.9125,0.1336348,0.06681746 +0.0875,0.9125,0.11905508,0.11905497 +0.087500006,0.9125,0.084184654,0.1683693 +0.0875,0.9125,0.16836931,0.08418465 +0.0875,0.9375,0.075,0.07500005 +0.087500006,0.9375,0.053033013,0.10606599 +0.08749999,0.9375,0.10606601,0.053033113 +0.087500006,0.9375,0.09449408,0.094494104 +0.0875,0.9375,0.0668174,0.1336348 +0.087500006,0.9375,0.1336348,0.06681752 +0.0875,0.9375,0.11905508,0.11905503 +0.087500006,0.9375,0.084184654,0.1683693 +0.0875,0.9375,0.16836931,0.08418465 +0.0875,0.9625,0.075,0.07499999 +0.087500006,0.9625,0.053033013,0.10606593 +0.08749999,0.9625,0.10606601,0.053033054 +0.087500006,0.9625,0.09449408,0.094494045 +0.0875,0.9625,0.0668174,0.13363475 +0.087500006,0.9625,0.1336348,0.06681746 +0.0875,0.9625,0.11905508,0.11905497 +0.087500006,0.9625,0.084184654,0.1683693 +0.0875,0.9625,0.16836931,0.08418465 +0.0875,0.98749995,0.075,0.07499999 +0.087500006,0.98749995,0.053033013,0.10606593 +0.08749999,0.98749995,0.10606601,0.053033054 +0.087500006,0.98749995,0.09449408,0.094494045 +0.0875,0.98749995,0.0668174,0.13363475 +0.087500006,0.98749995,0.1336348,0.06681746 +0.0875,0.98749995,0.11905508,0.11905497 +0.087500006,0.98749995,0.084184654,0.16836923 +0.0875,0.98749995,0.16836931,0.08418459 +0.112500004,0.0125,0.075,0.075 +0.112500004,0.012499997,0.05303301,0.10606602 +0.1125,0.012499999,0.10606601,0.05303301 +0.1125,0.012499999,0.094494075,0.09449408 +0.1125,0.012500001,0.0668174,0.1336348 +0.1125,0.012499999,0.1336348,0.0668174 +0.1125,0.012500001,0.119055085,0.11905508 +0.1125,0.012499999,0.08418465,0.1683693 +0.112500004,0.012500002,0.16836931,0.084184654 +0.112500004,0.0375,0.075,0.075 +0.112500004,0.037499998,0.05303301,0.10606601 +0.1125,0.0375,0.10606601,0.05303301 +0.1125,0.0375,0.094494075,0.094494075 +0.1125,0.0375,0.0668174,0.1336348 +0.1125,0.0375,0.1336348,0.0668174 +0.1125,0.0375,0.119055085,0.11905508 +0.1125,0.0375,0.08418465,0.16836931 +0.112500004,0.0375,0.16836931,0.08418466 +0.112500004,0.0625,0.075,0.075 +0.112500004,0.0625,0.05303301,0.10606602 +0.1125,0.0625,0.10606601,0.05303301 +0.1125,0.0625,0.094494075,0.094494075 +0.1125,0.0625,0.0668174,0.1336348 +0.1125,0.0625,0.1336348,0.0668174 +0.1125,0.0625,0.119055085,0.11905508 +0.1125,0.0625,0.08418465,0.16836932 +0.112500004,0.0625,0.16836931,0.08418465 +0.112500004,0.0875,0.075,0.075 +0.112500004,0.08749999,0.05303301,0.10606601 +0.1125,0.087500006,0.10606601,0.053033013 +0.1125,0.087500006,0.094494075,0.09449408 +0.1125,0.087500006,0.0668174,0.1336348 +0.1125,0.0875,0.1336348,0.0668174 +0.1125,0.0875,0.119055085,0.11905508 +0.1125,0.0875,0.08418465,0.16836931 +0.112500004,0.087500006,0.16836931,0.084184654 +0.112500004,0.112500004,0.075,0.075 +0.112500004,0.1125,0.05303301,0.10606601 +0.1125,0.112500004,0.10606601,0.05303301 +0.1125,0.1125,0.094494075,0.094494075 +0.1125,0.1125,0.0668174,0.1336348 +0.1125,0.1125,0.1336348,0.0668174 +0.1125,0.1125,0.119055085,0.119055085 +0.1125,0.112500004,0.08418465,0.16836931 +0.112500004,0.1125,0.16836931,0.08418465 +0.112500004,0.1375,0.075,0.074999996 +0.112500004,0.1375,0.05303301,0.10606602 +0.1125,0.1375,0.10606601,0.053033024 +0.1125,0.1375,0.094494075,0.09449408 +0.1125,0.1375,0.0668174,0.1336348 +0.1125,0.1375,0.1336348,0.0668174 +0.1125,0.13749999,0.119055085,0.11905508 +0.1125,0.1375,0.08418465,0.1683693 +0.112500004,0.1375,0.16836931,0.084184654 +0.112500004,0.1625,0.075,0.075 +0.112500004,0.16250001,0.05303301,0.106066026 +0.1125,0.1625,0.10606601,0.05303301 +0.1125,0.1625,0.094494075,0.094494075 +0.1125,0.1625,0.0668174,0.1336348 +0.1125,0.1625,0.1336348,0.0668174 +0.1125,0.1625,0.119055085,0.11905508 +0.1125,0.1625,0.08418465,0.1683693 +0.112500004,0.1625,0.16836931,0.08418464 +0.112500004,0.1875,0.075,0.07499999 +0.112500004,0.1875,0.05303301,0.10606603 +0.1125,0.1875,0.10606601,0.053033024 +0.1125,0.1875,0.094494075,0.09449406 +0.1125,0.1875,0.0668174,0.1336348 +0.1125,0.1875,0.1336348,0.06681742 +0.1125,0.1875,0.119055085,0.11905509 +0.1125,0.1875,0.08418465,0.16836931 +0.112500004,0.1875,0.16836931,0.08418465 +0.112500004,0.2125,0.075,0.075 +0.112500004,0.2125,0.05303301,0.10606603 +0.1125,0.2125,0.10606601,0.05303301 +0.1125,0.21249999,0.094494075,0.094494075 +0.1125,0.2125,0.0668174,0.1336348 +0.1125,0.2125,0.1336348,0.0668174 +0.1125,0.2125,0.119055085,0.11905509 +0.1125,0.2125,0.08418465,0.16836931 +0.112500004,0.2125,0.16836931,0.08418465 +0.112500004,0.23750001,0.075,0.075 +0.112500004,0.2375,0.05303301,0.10606602 +0.1125,0.2375,0.10606601,0.053033024 +0.1125,0.2375,0.094494075,0.094494075 +0.1125,0.23750001,0.0668174,0.13363482 +0.1125,0.2375,0.1336348,0.06681743 +0.1125,0.2375,0.119055085,0.11905506 +0.1125,0.2375,0.08418465,0.16836932 +0.112500004,0.23750001,0.16836931,0.08418466 +0.112500004,0.2625,0.075,0.07500002 +0.112500004,0.2625,0.05303301,0.10606603 +0.1125,0.2625,0.10606601,0.053033024 +0.1125,0.2625,0.094494075,0.094494075 +0.1125,0.2625,0.0668174,0.13363479 +0.1125,0.2625,0.1336348,0.06681743 +0.1125,0.2625,0.119055085,0.11905508 +0.1125,0.2625,0.08418465,0.1683693 +0.112500004,0.2625,0.16836931,0.08418463 +0.112500004,0.2875,0.075,0.07499999 +0.112500004,0.2875,0.05303301,0.10606603 +0.1125,0.28750002,0.10606601,0.053033024 +0.1125,0.2875,0.094494075,0.094494045 +0.1125,0.2875,0.0668174,0.1336348 +0.1125,0.28750002,0.1336348,0.06681743 +0.1125,0.2875,0.119055085,0.11905508 +0.1125,0.2875,0.08418465,0.1683693 +0.112500004,0.2875,0.16836931,0.08418465 +0.112500004,0.3125,0.075,0.07499999 +0.112500004,0.3125,0.05303301,0.10606605 +0.1125,0.3125,0.10606601,0.053032994 +0.1125,0.3125,0.094494075,0.094494045 +0.1125,0.3125,0.0668174,0.1336348 +0.1125,0.3125,0.1336348,0.0668174 +0.1125,0.3125,0.119055085,0.11905509 +0.1125,0.3125,0.08418465,0.1683693 +0.112500004,0.3125,0.16836931,0.08418465 +0.112500004,0.3375,0.075,0.07499999 +0.112500004,0.3375,0.05303301,0.10606605 +0.1125,0.33749998,0.10606601,0.053033024 +0.1125,0.3375,0.094494075,0.094494045 +0.1125,0.33750004,0.0668174,0.13363484 +0.1125,0.33749998,0.1336348,0.06681743 +0.1125,0.3375,0.119055085,0.11905509 +0.1125,0.3375,0.08418465,0.1683693 +0.112500004,0.3375,0.16836931,0.08418465 +0.112500004,0.3625,0.075,0.07500002 +0.112500004,0.3625,0.05303301,0.10606602 +0.1125,0.3625,0.10606601,0.053033024 +0.1125,0.3625,0.094494075,0.094494075 +0.1125,0.3625,0.0668174,0.1336348 +0.1125,0.3625,0.1336348,0.06681743 +0.1125,0.3625,0.119055085,0.11905506 +0.1125,0.3625,0.08418465,0.1683693 +0.112500004,0.3625,0.16836931,0.08418465 +0.112500004,0.3875,0.075,0.07500002 +0.112500004,0.3875,0.05303301,0.10606602 +0.1125,0.3875,0.10606601,0.053032994 +0.1125,0.3875,0.094494075,0.094494075 +0.1125,0.3875,0.0668174,0.13363484 +0.1125,0.3875,0.1336348,0.0668174 +0.1125,0.3875,0.119055085,0.11905506 +0.1125,0.3875,0.08418465,0.1683693 +0.112500004,0.3875,0.16836931,0.08418465 +0.112500004,0.4125,0.075,0.07499999 +0.112500004,0.4125,0.05303301,0.10606605 +0.1125,0.4125,0.10606601,0.053032994 +0.1125,0.4125,0.094494075,0.094494045 +0.1125,0.41250002,0.0668174,0.13363484 +0.1125,0.4125,0.1336348,0.0668174 +0.1125,0.4125,0.119055085,0.11905509 +0.1125,0.4125,0.08418465,0.1683693 +0.112500004,0.4125,0.16836931,0.08418465 +0.112500004,0.4375,0.075,0.07499999 +0.112500004,0.4375,0.05303301,0.10606605 +0.1125,0.4375,0.10606601,0.053032994 +0.1125,0.4375,0.094494075,0.094494045 +0.1125,0.4375,0.0668174,0.1336348 +0.1125,0.4375,0.1336348,0.0668174 +0.1125,0.4375,0.119055085,0.11905509 +0.1125,0.4375,0.08418465,0.1683693 +0.112500004,0.4375,0.16836931,0.08418465 +0.112500004,0.4625,0.075,0.07499999 +0.112500004,0.4625,0.05303301,0.10606605 +0.1125,0.46249998,0.10606601,0.053032964 +0.1125,0.4625,0.094494075,0.094494045 +0.1125,0.46250004,0.0668174,0.13363484 +0.1125,0.46249998,0.1336348,0.06681737 +0.1125,0.4625,0.119055085,0.11905509 +0.1125,0.46249998,0.08418465,0.16836926 +0.112500004,0.46249998,0.16836931,0.08418462 +0.112500004,0.48749998,0.075,0.07499999 +0.112500004,0.4875,0.05303301,0.10606602 +0.1125,0.4875,0.10606601,0.053032994 +0.1125,0.48749998,0.094494075,0.094494045 +0.1125,0.4875,0.0668174,0.13363484 +0.1125,0.4875,0.1336348,0.0668174 +0.1125,0.4875,0.119055085,0.11905506 +0.1125,0.4875,0.08418465,0.1683693 +0.112500004,0.4875,0.16836931,0.08418465 +0.112500004,0.5125,0.075,0.07500002 +0.112500004,0.51250005,0.05303301,0.10606605 +0.1125,0.5125,0.10606601,0.053032964 +0.1125,0.5125,0.094494075,0.094494075 +0.1125,0.51250005,0.0668174,0.13363487 +0.1125,0.5125,0.1336348,0.06681737 +0.1125,0.51250005,0.119055085,0.11905509 +0.1125,0.5125,0.08418465,0.1683693 +0.112500004,0.5125,0.16836931,0.08418465 +0.112500004,0.5375,0.075,0.07499999 +0.112500004,0.5375,0.05303301,0.10606605 +0.1125,0.5375,0.10606601,0.053032935 +0.1125,0.5375,0.094494075,0.094494045 +0.1125,0.5375,0.0668174,0.13363487 +0.1125,0.5375,0.1336348,0.06681734 +0.1125,0.5375,0.119055085,0.11905509 +0.1125,0.5375,0.08418465,0.16836932 +0.112500004,0.5375,0.16836931,0.08418468 +0.112500004,0.5625,0.075,0.07500005 +0.112500004,0.5625,0.05303301,0.10606599 +0.1125,0.5625,0.10606601,0.053032994 +0.1125,0.5625,0.094494075,0.094494104 +0.1125,0.5625,0.0668174,0.13363484 +0.1125,0.5625,0.1336348,0.0668174 +0.1125,0.5625,0.119055085,0.11905503 +0.1125,0.5625,0.08418465,0.1683693 +0.112500004,0.5625,0.16836931,0.08418465 +0.112500004,0.5875,0.075,0.07499999 +0.112500004,0.5875,0.05303301,0.10606605 +0.1125,0.5875,0.10606601,0.053032935 +0.1125,0.5875,0.094494075,0.094494045 +0.1125,0.5875,0.0668174,0.13363487 +0.1125,0.5875,0.1336348,0.06681734 +0.1125,0.5875,0.119055085,0.11905509 +0.1125,0.5875,0.08418465,0.1683693 +0.112500004,0.5875,0.16836931,0.08418465 +0.112500004,0.61249995,0.075,0.07499999 +0.112500004,0.61249995,0.05303301,0.10606605 +0.1125,0.6125,0.10606601,0.053032994 +0.1125,0.61249995,0.094494075,0.094494045 +0.1125,0.61249995,0.0668174,0.13363487 +0.1125,0.6125,0.1336348,0.0668174 +0.1125,0.61249995,0.119055085,0.11905509 +0.1125,0.6125,0.08418465,0.1683693 +0.112500004,0.6125,0.16836931,0.08418465 +0.112500004,0.63750005,0.075,0.07499999 +0.112500004,0.63750005,0.05303301,0.10606605 +0.1125,0.6375,0.10606601,0.053032994 +0.1125,0.63750005,0.094494075,0.094494045 +0.1125,0.63750005,0.0668174,0.13363487 +0.1125,0.6375,0.1336348,0.0668174 +0.1125,0.63750005,0.119055085,0.11905509 +0.1125,0.6375,0.08418465,0.1683693 +0.112500004,0.6375,0.16836931,0.08418465 +0.112500004,0.6625,0.075,0.07499999 +0.112500004,0.6625,0.05303301,0.10606605 +0.1125,0.6625,0.10606601,0.053032935 +0.1125,0.6625,0.094494075,0.094494045 +0.1125,0.6625,0.0668174,0.13363487 +0.1125,0.6625,0.1336348,0.06681734 +0.1125,0.6625,0.119055085,0.11905509 +0.1125,0.6625,0.08418465,0.1683693 +0.112500004,0.6625,0.16836931,0.08418465 +0.112500004,0.6875,0.075,0.07500005 +0.112500004,0.6875,0.05303301,0.10606599 +0.1125,0.6875,0.10606601,0.053032994 +0.1125,0.6875,0.094494075,0.094494104 +0.1125,0.6875,0.0668174,0.1336348 +0.1125,0.6875,0.1336348,0.0668174 +0.1125,0.6875,0.119055085,0.11905503 +0.1125,0.6875,0.08418465,0.1683693 +0.112500004,0.6875,0.16836931,0.08418465 +0.112500004,0.7125,0.075,0.07499999 +0.112500004,0.7125,0.05303301,0.10606605 +0.1125,0.7125,0.10606601,0.053032935 +0.1125,0.7125,0.094494075,0.094494045 +0.1125,0.7125,0.0668174,0.13363487 +0.1125,0.7125,0.1336348,0.06681734 +0.1125,0.7125,0.119055085,0.11905509 +0.1125,0.7125,0.08418465,0.1683693 +0.112500004,0.7125,0.16836931,0.08418465 +0.112500004,0.73749995,0.075,0.07499999 +0.112500004,0.73749995,0.05303301,0.10606605 +0.1125,0.7375,0.10606601,0.053032994 +0.1125,0.73749995,0.094494075,0.094494045 +0.1125,0.73749995,0.0668174,0.1336348 +0.1125,0.7375,0.1336348,0.0668174 +0.1125,0.73749995,0.119055085,0.11905509 +0.1125,0.7375,0.08418465,0.1683693 +0.112500004,0.7375,0.16836931,0.08418465 +0.112500004,0.76250005,0.075,0.07499999 +0.112500004,0.7625,0.05303301,0.10606599 +0.1125,0.7625,0.10606601,0.053032994 +0.1125,0.76250005,0.094494075,0.094494045 +0.1125,0.7625,0.0668174,0.1336348 +0.1125,0.7625,0.1336348,0.0668174 +0.1125,0.7625,0.119055085,0.11905503 +0.1125,0.7625,0.08418465,0.1683693 +0.112500004,0.7625,0.16836931,0.08418465 +0.112500004,0.7875,0.075,0.07499999 +0.112500004,0.78749996,0.05303301,0.10606599 +0.1125,0.7875,0.10606601,0.053032994 +0.1125,0.7875,0.094494075,0.094494045 +0.1125,0.78749996,0.0668174,0.1336348 +0.1125,0.7875,0.1336348,0.0668174 +0.1125,0.78749996,0.119055085,0.11905503 +0.1125,0.7875,0.08418465,0.1683693 +0.112500004,0.7875,0.16836931,0.08418465 +0.112500004,0.8125,0.075,0.07500005 +0.112500004,0.8125,0.05303301,0.10606599 +0.1125,0.8125,0.10606601,0.053033054 +0.1125,0.8125,0.094494075,0.094494104 +0.1125,0.8125,0.0668174,0.1336348 +0.1125,0.8125,0.1336348,0.06681746 +0.1125,0.8125,0.119055085,0.11905503 +0.1125,0.8125,0.08418465,0.1683693 +0.112500004,0.8125,0.16836931,0.08418465 +0.112500004,0.8375,0.075,0.07499999 +0.112500004,0.8375,0.05303301,0.10606599 +0.1125,0.8375,0.10606601,0.053033054 +0.1125,0.8375,0.094494075,0.094494045 +0.1125,0.8375,0.0668174,0.1336348 +0.1125,0.8375,0.1336348,0.06681746 +0.1125,0.8375,0.119055085,0.11905503 +0.1125,0.8375,0.08418465,0.1683693 +0.112500004,0.8375,0.16836931,0.08418465 +0.112500004,0.86249995,0.075,0.07499999 +0.112500004,0.86249995,0.05303301,0.10606593 +0.1125,0.86249995,0.10606601,0.053033054 +0.1125,0.86249995,0.094494075,0.094494045 +0.1125,0.86249995,0.0668174,0.1336348 +0.1125,0.86249995,0.1336348,0.06681746 +0.1125,0.86249995,0.119055085,0.11905497 +0.1125,0.8625,0.08418465,0.1683693 +0.112500004,0.8625,0.16836931,0.08418465 +0.112500004,0.88750005,0.075,0.07499999 +0.112500004,0.88750005,0.05303301,0.10606593 +0.1125,0.88750005,0.10606601,0.053033054 +0.1125,0.88750005,0.094494075,0.094494045 +0.1125,0.88750005,0.0668174,0.13363475 +0.1125,0.88750005,0.1336348,0.06681746 +0.1125,0.88750005,0.119055085,0.11905497 +0.1125,0.8875,0.08418465,0.1683693 +0.112500004,0.8875,0.16836931,0.08418465 +0.112500004,0.9125,0.075,0.07499999 +0.112500004,0.9125,0.05303301,0.10606593 +0.1125,0.9125,0.10606601,0.053033054 +0.1125,0.9125,0.094494075,0.094494045 +0.1125,0.9125,0.0668174,0.13363475 +0.1125,0.9125,0.1336348,0.06681746 +0.1125,0.9125,0.119055085,0.11905497 +0.1125,0.9125,0.08418465,0.1683693 +0.112500004,0.9125,0.16836931,0.08418465 +0.112500004,0.9375,0.075,0.07500005 +0.112500004,0.9375,0.05303301,0.10606599 +0.1125,0.9375,0.10606601,0.053033113 +0.1125,0.9375,0.094494075,0.094494104 +0.1125,0.9375,0.0668174,0.1336348 +0.1125,0.9375,0.1336348,0.06681752 +0.1125,0.9375,0.119055085,0.11905503 +0.1125,0.9375,0.08418465,0.1683693 +0.112500004,0.9375,0.16836931,0.08418465 +0.112500004,0.9625,0.075,0.07499999 +0.112500004,0.9625,0.05303301,0.10606593 +0.1125,0.9625,0.10606601,0.053033054 +0.1125,0.9625,0.094494075,0.094494045 +0.1125,0.9625,0.0668174,0.13363475 +0.1125,0.9625,0.1336348,0.06681746 +0.1125,0.9625,0.119055085,0.11905497 +0.1125,0.9625,0.08418465,0.1683693 +0.112500004,0.9625,0.16836931,0.08418465 +0.112500004,0.98749995,0.075,0.07499999 +0.112500004,0.98749995,0.05303301,0.10606593 +0.1125,0.98749995,0.10606601,0.053033054 +0.1125,0.98749995,0.094494075,0.094494045 +0.1125,0.98749995,0.0668174,0.13363475 +0.1125,0.98749995,0.1336348,0.06681746 +0.1125,0.98749995,0.119055085,0.11905497 +0.1125,0.98749995,0.08418465,0.16836923 +0.112500004,0.98749995,0.16836931,0.08418459 +0.1375,0.0125,0.074999996,0.075 +0.1375,0.012499997,0.053033024,0.10606602 +0.1375,0.012499999,0.10606602,0.05303301 +0.1375,0.012499999,0.09449408,0.09449408 +0.1375,0.012500001,0.0668174,0.1336348 +0.1375,0.012499999,0.1336348,0.0668174 +0.13749999,0.012500001,0.11905508,0.11905508 +0.1375,0.012499999,0.084184654,0.1683693 +0.1375,0.012500002,0.1683693,0.084184654 +0.1375,0.0375,0.074999996,0.075 +0.1375,0.037499998,0.053033024,0.10606601 +0.1375,0.0375,0.10606602,0.05303301 +0.1375,0.0375,0.09449408,0.094494075 +0.1375,0.0375,0.0668174,0.1336348 +0.1375,0.0375,0.1336348,0.0668174 +0.13749999,0.0375,0.11905508,0.11905508 +0.1375,0.0375,0.084184654,0.16836931 +0.1375,0.0375,0.1683693,0.08418466 +0.1375,0.0625,0.074999996,0.075 +0.1375,0.0625,0.053033024,0.10606602 +0.1375,0.0625,0.10606602,0.05303301 +0.1375,0.0625,0.09449408,0.094494075 +0.1375,0.0625,0.0668174,0.1336348 +0.1375,0.0625,0.1336348,0.0668174 +0.13749999,0.0625,0.11905508,0.11905508 +0.1375,0.0625,0.084184654,0.16836932 +0.1375,0.0625,0.1683693,0.08418465 +0.1375,0.0875,0.074999996,0.075 +0.1375,0.08749999,0.053033024,0.10606601 +0.1375,0.087500006,0.10606602,0.053033013 +0.1375,0.087500006,0.09449408,0.09449408 +0.1375,0.087500006,0.0668174,0.1336348 +0.1375,0.0875,0.1336348,0.0668174 +0.13749999,0.0875,0.11905508,0.11905508 +0.1375,0.0875,0.084184654,0.16836931 +0.1375,0.087500006,0.1683693,0.084184654 +0.1375,0.112500004,0.074999996,0.075 +0.1375,0.1125,0.053033024,0.10606601 +0.1375,0.112500004,0.10606602,0.05303301 +0.1375,0.1125,0.09449408,0.094494075 +0.1375,0.1125,0.0668174,0.1336348 +0.1375,0.1125,0.1336348,0.0668174 +0.13749999,0.1125,0.11905508,0.119055085 +0.1375,0.112500004,0.084184654,0.16836931 +0.1375,0.1125,0.1683693,0.08418465 +0.1375,0.1375,0.074999996,0.074999996 +0.1375,0.1375,0.053033024,0.10606602 +0.1375,0.1375,0.10606602,0.053033024 +0.1375,0.1375,0.09449408,0.09449408 +0.1375,0.1375,0.0668174,0.1336348 +0.1375,0.1375,0.1336348,0.0668174 +0.13749999,0.13749999,0.11905508,0.11905508 +0.1375,0.1375,0.084184654,0.1683693 +0.1375,0.1375,0.1683693,0.084184654 +0.1375,0.1625,0.074999996,0.075 +0.1375,0.16250001,0.053033024,0.106066026 +0.1375,0.1625,0.10606602,0.05303301 +0.1375,0.1625,0.09449408,0.094494075 +0.1375,0.1625,0.0668174,0.1336348 +0.1375,0.1625,0.1336348,0.0668174 +0.13749999,0.1625,0.11905508,0.11905508 +0.1375,0.1625,0.084184654,0.1683693 +0.1375,0.1625,0.1683693,0.08418464 +0.1375,0.1875,0.074999996,0.07499999 +0.1375,0.1875,0.053033024,0.10606603 +0.1375,0.1875,0.10606602,0.053033024 +0.1375,0.1875,0.09449408,0.09449406 +0.1375,0.1875,0.0668174,0.1336348 +0.1375,0.1875,0.1336348,0.06681742 +0.13749999,0.1875,0.11905508,0.11905509 +0.1375,0.1875,0.084184654,0.16836931 +0.1375,0.1875,0.1683693,0.08418465 +0.1375,0.2125,0.074999996,0.075 +0.1375,0.2125,0.053033024,0.10606603 +0.1375,0.2125,0.10606602,0.05303301 +0.1375,0.21249999,0.09449408,0.094494075 +0.1375,0.2125,0.0668174,0.1336348 +0.1375,0.2125,0.1336348,0.0668174 +0.13749999,0.2125,0.11905508,0.11905509 +0.1375,0.2125,0.084184654,0.16836931 +0.1375,0.2125,0.1683693,0.08418465 +0.1375,0.23750001,0.074999996,0.075 +0.1375,0.2375,0.053033024,0.10606602 +0.1375,0.2375,0.10606602,0.053033024 +0.1375,0.2375,0.09449408,0.094494075 +0.1375,0.23750001,0.0668174,0.13363482 +0.1375,0.2375,0.1336348,0.06681743 +0.13749999,0.2375,0.11905508,0.11905506 +0.1375,0.2375,0.084184654,0.16836932 +0.1375,0.23750001,0.1683693,0.08418466 +0.1375,0.2625,0.074999996,0.07500002 +0.1375,0.2625,0.053033024,0.10606603 +0.1375,0.2625,0.10606602,0.053033024 +0.1375,0.2625,0.09449408,0.094494075 +0.1375,0.2625,0.0668174,0.13363479 +0.1375,0.2625,0.1336348,0.06681743 +0.13749999,0.2625,0.11905508,0.11905508 +0.1375,0.2625,0.084184654,0.1683693 +0.1375,0.2625,0.1683693,0.08418463 +0.1375,0.2875,0.074999996,0.07499999 +0.1375,0.2875,0.053033024,0.10606603 +0.1375,0.28750002,0.10606602,0.053033024 +0.1375,0.2875,0.09449408,0.094494045 +0.1375,0.2875,0.0668174,0.1336348 +0.1375,0.28750002,0.1336348,0.06681743 +0.13749999,0.2875,0.11905508,0.11905508 +0.1375,0.2875,0.084184654,0.1683693 +0.1375,0.2875,0.1683693,0.08418465 +0.1375,0.3125,0.074999996,0.07499999 +0.1375,0.3125,0.053033024,0.10606605 +0.1375,0.3125,0.10606602,0.053032994 +0.1375,0.3125,0.09449408,0.094494045 +0.1375,0.3125,0.0668174,0.1336348 +0.1375,0.3125,0.1336348,0.0668174 +0.13749999,0.3125,0.11905508,0.11905509 +0.1375,0.3125,0.084184654,0.1683693 +0.1375,0.3125,0.1683693,0.08418465 +0.1375,0.3375,0.074999996,0.07499999 +0.1375,0.3375,0.053033024,0.10606605 +0.1375,0.33749998,0.10606602,0.053033024 +0.1375,0.3375,0.09449408,0.094494045 +0.1375,0.33750004,0.0668174,0.13363484 +0.1375,0.33749998,0.1336348,0.06681743 +0.13749999,0.3375,0.11905508,0.11905509 +0.1375,0.3375,0.084184654,0.1683693 +0.1375,0.3375,0.1683693,0.08418465 +0.1375,0.3625,0.074999996,0.07500002 +0.1375,0.3625,0.053033024,0.10606602 +0.1375,0.3625,0.10606602,0.053033024 +0.1375,0.3625,0.09449408,0.094494075 +0.1375,0.3625,0.0668174,0.1336348 +0.1375,0.3625,0.1336348,0.06681743 +0.13749999,0.3625,0.11905508,0.11905506 +0.1375,0.3625,0.084184654,0.1683693 +0.1375,0.3625,0.1683693,0.08418465 +0.1375,0.3875,0.074999996,0.07500002 +0.1375,0.3875,0.053033024,0.10606602 +0.1375,0.3875,0.10606602,0.053032994 +0.1375,0.3875,0.09449408,0.094494075 +0.1375,0.3875,0.0668174,0.13363484 +0.1375,0.3875,0.1336348,0.0668174 +0.13749999,0.3875,0.11905508,0.11905506 +0.1375,0.3875,0.084184654,0.1683693 +0.1375,0.3875,0.1683693,0.08418465 +0.1375,0.4125,0.074999996,0.07499999 +0.1375,0.4125,0.053033024,0.10606605 +0.1375,0.4125,0.10606602,0.053032994 +0.1375,0.4125,0.09449408,0.094494045 +0.1375,0.41250002,0.0668174,0.13363484 +0.1375,0.4125,0.1336348,0.0668174 +0.13749999,0.4125,0.11905508,0.11905509 +0.1375,0.4125,0.084184654,0.1683693 +0.1375,0.4125,0.1683693,0.08418465 +0.1375,0.4375,0.074999996,0.07499999 +0.1375,0.4375,0.053033024,0.10606605 +0.1375,0.4375,0.10606602,0.053032994 +0.1375,0.4375,0.09449408,0.094494045 +0.1375,0.4375,0.0668174,0.1336348 +0.1375,0.4375,0.1336348,0.0668174 +0.13749999,0.4375,0.11905508,0.11905509 +0.1375,0.4375,0.084184654,0.1683693 +0.1375,0.4375,0.1683693,0.08418465 +0.1375,0.4625,0.074999996,0.07499999 +0.1375,0.4625,0.053033024,0.10606605 +0.1375,0.46249998,0.10606602,0.053032964 +0.1375,0.4625,0.09449408,0.094494045 +0.1375,0.46250004,0.0668174,0.13363484 +0.1375,0.46249998,0.1336348,0.06681737 +0.13749999,0.4625,0.11905508,0.11905509 +0.1375,0.46249998,0.084184654,0.16836926 +0.1375,0.46249998,0.1683693,0.08418462 +0.1375,0.48749998,0.074999996,0.07499999 +0.1375,0.4875,0.053033024,0.10606602 +0.1375,0.4875,0.10606602,0.053032994 +0.1375,0.48749998,0.09449408,0.094494045 +0.1375,0.4875,0.0668174,0.13363484 +0.1375,0.4875,0.1336348,0.0668174 +0.13749999,0.4875,0.11905508,0.11905506 +0.1375,0.4875,0.084184654,0.1683693 +0.1375,0.4875,0.1683693,0.08418465 +0.1375,0.5125,0.074999996,0.07500002 +0.1375,0.51250005,0.053033024,0.10606605 +0.1375,0.5125,0.10606602,0.053032964 +0.1375,0.5125,0.09449408,0.094494075 +0.1375,0.51250005,0.0668174,0.13363487 +0.1375,0.5125,0.1336348,0.06681737 +0.13749999,0.51250005,0.11905508,0.11905509 +0.1375,0.5125,0.084184654,0.1683693 +0.1375,0.5125,0.1683693,0.08418465 +0.1375,0.5375,0.074999996,0.07499999 +0.1375,0.5375,0.053033024,0.10606605 +0.1375,0.5375,0.10606602,0.053032935 +0.1375,0.5375,0.09449408,0.094494045 +0.1375,0.5375,0.0668174,0.13363487 +0.1375,0.5375,0.1336348,0.06681734 +0.13749999,0.5375,0.11905508,0.11905509 +0.1375,0.5375,0.084184654,0.16836932 +0.1375,0.5375,0.1683693,0.08418468 +0.1375,0.5625,0.074999996,0.07500005 +0.1375,0.5625,0.053033024,0.10606599 +0.1375,0.5625,0.10606602,0.053032994 +0.1375,0.5625,0.09449408,0.094494104 +0.1375,0.5625,0.0668174,0.13363484 +0.1375,0.5625,0.1336348,0.0668174 +0.13749999,0.5625,0.11905508,0.11905503 +0.1375,0.5625,0.084184654,0.1683693 +0.1375,0.5625,0.1683693,0.08418465 +0.1375,0.5875,0.074999996,0.07499999 +0.1375,0.5875,0.053033024,0.10606605 +0.1375,0.5875,0.10606602,0.053032935 +0.1375,0.5875,0.09449408,0.094494045 +0.1375,0.5875,0.0668174,0.13363487 +0.1375,0.5875,0.1336348,0.06681734 +0.13749999,0.5875,0.11905508,0.11905509 +0.1375,0.5875,0.084184654,0.1683693 +0.1375,0.5875,0.1683693,0.08418465 +0.1375,0.61249995,0.074999996,0.07499999 +0.1375,0.61249995,0.053033024,0.10606605 +0.1375,0.6125,0.10606602,0.053032994 +0.1375,0.61249995,0.09449408,0.094494045 +0.1375,0.61249995,0.0668174,0.13363487 +0.1375,0.6125,0.1336348,0.0668174 +0.13749999,0.61249995,0.11905508,0.11905509 +0.1375,0.6125,0.084184654,0.1683693 +0.1375,0.6125,0.1683693,0.08418465 +0.1375,0.63750005,0.074999996,0.07499999 +0.1375,0.63750005,0.053033024,0.10606605 +0.1375,0.6375,0.10606602,0.053032994 +0.1375,0.63750005,0.09449408,0.094494045 +0.1375,0.63750005,0.0668174,0.13363487 +0.1375,0.6375,0.1336348,0.0668174 +0.13749999,0.63750005,0.11905508,0.11905509 +0.1375,0.6375,0.084184654,0.1683693 +0.1375,0.6375,0.1683693,0.08418465 +0.1375,0.6625,0.074999996,0.07499999 +0.1375,0.6625,0.053033024,0.10606605 +0.1375,0.6625,0.10606602,0.053032935 +0.1375,0.6625,0.09449408,0.094494045 +0.1375,0.6625,0.0668174,0.13363487 +0.1375,0.6625,0.1336348,0.06681734 +0.13749999,0.6625,0.11905508,0.11905509 +0.1375,0.6625,0.084184654,0.1683693 +0.1375,0.6625,0.1683693,0.08418465 +0.1375,0.6875,0.074999996,0.07500005 +0.1375,0.6875,0.053033024,0.10606599 +0.1375,0.6875,0.10606602,0.053032994 +0.1375,0.6875,0.09449408,0.094494104 +0.1375,0.6875,0.0668174,0.1336348 +0.1375,0.6875,0.1336348,0.0668174 +0.13749999,0.6875,0.11905508,0.11905503 +0.1375,0.6875,0.084184654,0.1683693 +0.1375,0.6875,0.1683693,0.08418465 +0.1375,0.7125,0.074999996,0.07499999 +0.1375,0.7125,0.053033024,0.10606605 +0.1375,0.7125,0.10606602,0.053032935 +0.1375,0.7125,0.09449408,0.094494045 +0.1375,0.7125,0.0668174,0.13363487 +0.1375,0.7125,0.1336348,0.06681734 +0.13749999,0.7125,0.11905508,0.11905509 +0.1375,0.7125,0.084184654,0.1683693 +0.1375,0.7125,0.1683693,0.08418465 +0.1375,0.73749995,0.074999996,0.07499999 +0.1375,0.73749995,0.053033024,0.10606605 +0.1375,0.7375,0.10606602,0.053032994 +0.1375,0.73749995,0.09449408,0.094494045 +0.1375,0.73749995,0.0668174,0.1336348 +0.1375,0.7375,0.1336348,0.0668174 +0.13749999,0.73749995,0.11905508,0.11905509 +0.1375,0.7375,0.084184654,0.1683693 +0.1375,0.7375,0.1683693,0.08418465 +0.1375,0.76250005,0.074999996,0.07499999 +0.1375,0.7625,0.053033024,0.10606599 +0.1375,0.7625,0.10606602,0.053032994 +0.1375,0.76250005,0.09449408,0.094494045 +0.1375,0.7625,0.0668174,0.1336348 +0.1375,0.7625,0.1336348,0.0668174 +0.13749999,0.7625,0.11905508,0.11905503 +0.1375,0.7625,0.084184654,0.1683693 +0.1375,0.7625,0.1683693,0.08418465 +0.1375,0.7875,0.074999996,0.07499999 +0.1375,0.78749996,0.053033024,0.10606599 +0.1375,0.7875,0.10606602,0.053032994 +0.1375,0.7875,0.09449408,0.094494045 +0.1375,0.78749996,0.0668174,0.1336348 +0.1375,0.7875,0.1336348,0.0668174 +0.13749999,0.78749996,0.11905508,0.11905503 +0.1375,0.7875,0.084184654,0.1683693 +0.1375,0.7875,0.1683693,0.08418465 +0.1375,0.8125,0.074999996,0.07500005 +0.1375,0.8125,0.053033024,0.10606599 +0.1375,0.8125,0.10606602,0.053033054 +0.1375,0.8125,0.09449408,0.094494104 +0.1375,0.8125,0.0668174,0.1336348 +0.1375,0.8125,0.1336348,0.06681746 +0.13749999,0.8125,0.11905508,0.11905503 +0.1375,0.8125,0.084184654,0.1683693 +0.1375,0.8125,0.1683693,0.08418465 +0.1375,0.8375,0.074999996,0.07499999 +0.1375,0.8375,0.053033024,0.10606599 +0.1375,0.8375,0.10606602,0.053033054 +0.1375,0.8375,0.09449408,0.094494045 +0.1375,0.8375,0.0668174,0.1336348 +0.1375,0.8375,0.1336348,0.06681746 +0.13749999,0.8375,0.11905508,0.11905503 +0.1375,0.8375,0.084184654,0.1683693 +0.1375,0.8375,0.1683693,0.08418465 +0.1375,0.86249995,0.074999996,0.07499999 +0.1375,0.86249995,0.053033024,0.10606593 +0.1375,0.86249995,0.10606602,0.053033054 +0.1375,0.86249995,0.09449408,0.094494045 +0.1375,0.86249995,0.0668174,0.1336348 +0.1375,0.86249995,0.1336348,0.06681746 +0.13749999,0.86249995,0.11905508,0.11905497 +0.1375,0.8625,0.084184654,0.1683693 +0.1375,0.8625,0.1683693,0.08418465 +0.1375,0.88750005,0.074999996,0.07499999 +0.1375,0.88750005,0.053033024,0.10606593 +0.1375,0.88750005,0.10606602,0.053033054 +0.1375,0.88750005,0.09449408,0.094494045 +0.1375,0.88750005,0.0668174,0.13363475 +0.1375,0.88750005,0.1336348,0.06681746 +0.13749999,0.88750005,0.11905508,0.11905497 +0.1375,0.8875,0.084184654,0.1683693 +0.1375,0.8875,0.1683693,0.08418465 +0.1375,0.9125,0.074999996,0.07499999 +0.1375,0.9125,0.053033024,0.10606593 +0.1375,0.9125,0.10606602,0.053033054 +0.1375,0.9125,0.09449408,0.094494045 +0.1375,0.9125,0.0668174,0.13363475 +0.1375,0.9125,0.1336348,0.06681746 +0.13749999,0.9125,0.11905508,0.11905497 +0.1375,0.9125,0.084184654,0.1683693 +0.1375,0.9125,0.1683693,0.08418465 +0.1375,0.9375,0.074999996,0.07500005 +0.1375,0.9375,0.053033024,0.10606599 +0.1375,0.9375,0.10606602,0.053033113 +0.1375,0.9375,0.09449408,0.094494104 +0.1375,0.9375,0.0668174,0.1336348 +0.1375,0.9375,0.1336348,0.06681752 +0.13749999,0.9375,0.11905508,0.11905503 +0.1375,0.9375,0.084184654,0.1683693 +0.1375,0.9375,0.1683693,0.08418465 +0.1375,0.9625,0.074999996,0.07499999 +0.1375,0.9625,0.053033024,0.10606593 +0.1375,0.9625,0.10606602,0.053033054 +0.1375,0.9625,0.09449408,0.094494045 +0.1375,0.9625,0.0668174,0.13363475 +0.1375,0.9625,0.1336348,0.06681746 +0.13749999,0.9625,0.11905508,0.11905497 +0.1375,0.9625,0.084184654,0.1683693 +0.1375,0.9625,0.1683693,0.08418465 +0.1375,0.98749995,0.074999996,0.07499999 +0.1375,0.98749995,0.053033024,0.10606593 +0.1375,0.98749995,0.10606602,0.053033054 +0.1375,0.98749995,0.09449408,0.094494045 +0.1375,0.98749995,0.0668174,0.13363475 +0.1375,0.98749995,0.1336348,0.06681746 +0.13749999,0.98749995,0.11905508,0.11905497 +0.1375,0.98749995,0.084184654,0.16836923 +0.1375,0.98749995,0.1683693,0.08418459 +0.1625,0.0125,0.075,0.075 +0.1625,0.012499997,0.05303301,0.10606602 +0.16250001,0.012499999,0.106066026,0.05303301 +0.1625,0.012499999,0.094494075,0.09449408 +0.1625,0.012500001,0.0668174,0.1336348 +0.1625,0.012499999,0.1336348,0.0668174 +0.1625,0.012500001,0.11905508,0.11905508 +0.1625,0.012499999,0.08418464,0.1683693 +0.1625,0.012500002,0.1683693,0.084184654 +0.1625,0.0375,0.075,0.075 +0.1625,0.037499998,0.05303301,0.10606601 +0.16250001,0.0375,0.106066026,0.05303301 +0.1625,0.0375,0.094494075,0.094494075 +0.1625,0.0375,0.0668174,0.1336348 +0.1625,0.0375,0.1336348,0.0668174 +0.1625,0.0375,0.11905508,0.11905508 +0.1625,0.0375,0.08418464,0.16836931 +0.1625,0.0375,0.1683693,0.08418466 +0.1625,0.0625,0.075,0.075 +0.1625,0.0625,0.05303301,0.10606602 +0.16250001,0.0625,0.106066026,0.05303301 +0.1625,0.0625,0.094494075,0.094494075 +0.1625,0.0625,0.0668174,0.1336348 +0.1625,0.0625,0.1336348,0.0668174 +0.1625,0.0625,0.11905508,0.11905508 +0.1625,0.0625,0.08418464,0.16836932 +0.1625,0.0625,0.1683693,0.08418465 +0.1625,0.0875,0.075,0.075 +0.1625,0.08749999,0.05303301,0.10606601 +0.16250001,0.087500006,0.106066026,0.053033013 +0.1625,0.087500006,0.094494075,0.09449408 +0.1625,0.087500006,0.0668174,0.1336348 +0.1625,0.0875,0.1336348,0.0668174 +0.1625,0.0875,0.11905508,0.11905508 +0.1625,0.0875,0.08418464,0.16836931 +0.1625,0.087500006,0.1683693,0.084184654 +0.1625,0.112500004,0.075,0.075 +0.1625,0.1125,0.05303301,0.10606601 +0.16250001,0.112500004,0.106066026,0.05303301 +0.1625,0.1125,0.094494075,0.094494075 +0.1625,0.1125,0.0668174,0.1336348 +0.1625,0.1125,0.1336348,0.0668174 +0.1625,0.1125,0.11905508,0.119055085 +0.1625,0.112500004,0.08418464,0.16836931 +0.1625,0.1125,0.1683693,0.08418465 +0.1625,0.1375,0.075,0.074999996 +0.1625,0.1375,0.05303301,0.10606602 +0.16250001,0.1375,0.106066026,0.053033024 +0.1625,0.1375,0.094494075,0.09449408 +0.1625,0.1375,0.0668174,0.1336348 +0.1625,0.1375,0.1336348,0.0668174 +0.1625,0.13749999,0.11905508,0.11905508 +0.1625,0.1375,0.08418464,0.1683693 +0.1625,0.1375,0.1683693,0.084184654 +0.1625,0.1625,0.075,0.075 +0.1625,0.16250001,0.05303301,0.106066026 +0.16250001,0.1625,0.106066026,0.05303301 +0.1625,0.1625,0.094494075,0.094494075 +0.1625,0.1625,0.0668174,0.1336348 +0.1625,0.1625,0.1336348,0.0668174 +0.1625,0.1625,0.11905508,0.11905508 +0.1625,0.1625,0.08418464,0.1683693 +0.1625,0.1625,0.1683693,0.08418464 +0.1625,0.1875,0.075,0.07499999 +0.1625,0.1875,0.05303301,0.10606603 +0.16250001,0.1875,0.106066026,0.053033024 +0.1625,0.1875,0.094494075,0.09449406 +0.1625,0.1875,0.0668174,0.1336348 +0.1625,0.1875,0.1336348,0.06681742 +0.1625,0.1875,0.11905508,0.11905509 +0.1625,0.1875,0.08418464,0.16836931 +0.1625,0.1875,0.1683693,0.08418465 +0.1625,0.2125,0.075,0.075 +0.1625,0.2125,0.05303301,0.10606603 +0.16250001,0.2125,0.106066026,0.05303301 +0.1625,0.21249999,0.094494075,0.094494075 +0.1625,0.2125,0.0668174,0.1336348 +0.1625,0.2125,0.1336348,0.0668174 +0.1625,0.2125,0.11905508,0.11905509 +0.1625,0.2125,0.08418464,0.16836931 +0.1625,0.2125,0.1683693,0.08418465 +0.1625,0.23750001,0.075,0.075 +0.1625,0.2375,0.05303301,0.10606602 +0.16250001,0.2375,0.106066026,0.053033024 +0.1625,0.2375,0.094494075,0.094494075 +0.1625,0.23750001,0.0668174,0.13363482 +0.1625,0.2375,0.1336348,0.06681743 +0.1625,0.2375,0.11905508,0.11905506 +0.1625,0.2375,0.08418464,0.16836932 +0.1625,0.23750001,0.1683693,0.08418466 +0.1625,0.2625,0.075,0.07500002 +0.1625,0.2625,0.05303301,0.10606603 +0.16250001,0.2625,0.106066026,0.053033024 +0.1625,0.2625,0.094494075,0.094494075 +0.1625,0.2625,0.0668174,0.13363479 +0.1625,0.2625,0.1336348,0.06681743 +0.1625,0.2625,0.11905508,0.11905508 +0.1625,0.2625,0.08418464,0.1683693 +0.1625,0.2625,0.1683693,0.08418463 +0.1625,0.2875,0.075,0.07499999 +0.1625,0.2875,0.05303301,0.10606603 +0.16250001,0.28750002,0.106066026,0.053033024 +0.1625,0.2875,0.094494075,0.094494045 +0.1625,0.2875,0.0668174,0.1336348 +0.1625,0.28750002,0.1336348,0.06681743 +0.1625,0.2875,0.11905508,0.11905508 +0.1625,0.2875,0.08418464,0.1683693 +0.1625,0.2875,0.1683693,0.08418465 +0.1625,0.3125,0.075,0.07499999 +0.1625,0.3125,0.05303301,0.10606605 +0.16250001,0.3125,0.106066026,0.053032994 +0.1625,0.3125,0.094494075,0.094494045 +0.1625,0.3125,0.0668174,0.1336348 +0.1625,0.3125,0.1336348,0.0668174 +0.1625,0.3125,0.11905508,0.11905509 +0.1625,0.3125,0.08418464,0.1683693 +0.1625,0.3125,0.1683693,0.08418465 +0.1625,0.3375,0.075,0.07499999 +0.1625,0.3375,0.05303301,0.10606605 +0.16250001,0.33749998,0.106066026,0.053033024 +0.1625,0.3375,0.094494075,0.094494045 +0.1625,0.33750004,0.0668174,0.13363484 +0.1625,0.33749998,0.1336348,0.06681743 +0.1625,0.3375,0.11905508,0.11905509 +0.1625,0.3375,0.08418464,0.1683693 +0.1625,0.3375,0.1683693,0.08418465 +0.1625,0.3625,0.075,0.07500002 +0.1625,0.3625,0.05303301,0.10606602 +0.16250001,0.3625,0.106066026,0.053033024 +0.1625,0.3625,0.094494075,0.094494075 +0.1625,0.3625,0.0668174,0.1336348 +0.1625,0.3625,0.1336348,0.06681743 +0.1625,0.3625,0.11905508,0.11905506 +0.1625,0.3625,0.08418464,0.1683693 +0.1625,0.3625,0.1683693,0.08418465 +0.1625,0.3875,0.075,0.07500002 +0.1625,0.3875,0.05303301,0.10606602 +0.16250001,0.3875,0.106066026,0.053032994 +0.1625,0.3875,0.094494075,0.094494075 +0.1625,0.3875,0.0668174,0.13363484 +0.1625,0.3875,0.1336348,0.0668174 +0.1625,0.3875,0.11905508,0.11905506 +0.1625,0.3875,0.08418464,0.1683693 +0.1625,0.3875,0.1683693,0.08418465 +0.1625,0.4125,0.075,0.07499999 +0.1625,0.4125,0.05303301,0.10606605 +0.16250001,0.4125,0.106066026,0.053032994 +0.1625,0.4125,0.094494075,0.094494045 +0.1625,0.41250002,0.0668174,0.13363484 +0.1625,0.4125,0.1336348,0.0668174 +0.1625,0.4125,0.11905508,0.11905509 +0.1625,0.4125,0.08418464,0.1683693 +0.1625,0.4125,0.1683693,0.08418465 +0.1625,0.4375,0.075,0.07499999 +0.1625,0.4375,0.05303301,0.10606605 +0.16250001,0.4375,0.106066026,0.053032994 +0.1625,0.4375,0.094494075,0.094494045 +0.1625,0.4375,0.0668174,0.1336348 +0.1625,0.4375,0.1336348,0.0668174 +0.1625,0.4375,0.11905508,0.11905509 +0.1625,0.4375,0.08418464,0.1683693 +0.1625,0.4375,0.1683693,0.08418465 +0.1625,0.4625,0.075,0.07499999 +0.1625,0.4625,0.05303301,0.10606605 +0.16250001,0.46249998,0.106066026,0.053032964 +0.1625,0.4625,0.094494075,0.094494045 +0.1625,0.46250004,0.0668174,0.13363484 +0.1625,0.46249998,0.1336348,0.06681737 +0.1625,0.4625,0.11905508,0.11905509 +0.1625,0.46249998,0.08418464,0.16836926 +0.1625,0.46249998,0.1683693,0.08418462 +0.1625,0.48749998,0.075,0.07499999 +0.1625,0.4875,0.05303301,0.10606602 +0.16250001,0.4875,0.106066026,0.053032994 +0.1625,0.48749998,0.094494075,0.094494045 +0.1625,0.4875,0.0668174,0.13363484 +0.1625,0.4875,0.1336348,0.0668174 +0.1625,0.4875,0.11905508,0.11905506 +0.1625,0.4875,0.08418464,0.1683693 +0.1625,0.4875,0.1683693,0.08418465 +0.1625,0.5125,0.075,0.07500002 +0.1625,0.51250005,0.05303301,0.10606605 +0.16250001,0.5125,0.106066026,0.053032964 +0.1625,0.5125,0.094494075,0.094494075 +0.1625,0.51250005,0.0668174,0.13363487 +0.1625,0.5125,0.1336348,0.06681737 +0.1625,0.51250005,0.11905508,0.11905509 +0.1625,0.5125,0.08418464,0.1683693 +0.1625,0.5125,0.1683693,0.08418465 +0.1625,0.5375,0.075,0.07499999 +0.1625,0.5375,0.05303301,0.10606605 +0.16250001,0.5375,0.106066026,0.053032935 +0.1625,0.5375,0.094494075,0.094494045 +0.1625,0.5375,0.0668174,0.13363487 +0.1625,0.5375,0.1336348,0.06681734 +0.1625,0.5375,0.11905508,0.11905509 +0.1625,0.5375,0.08418464,0.16836932 +0.1625,0.5375,0.1683693,0.08418468 +0.1625,0.5625,0.075,0.07500005 +0.1625,0.5625,0.05303301,0.10606599 +0.16250001,0.5625,0.106066026,0.053032994 +0.1625,0.5625,0.094494075,0.094494104 +0.1625,0.5625,0.0668174,0.13363484 +0.1625,0.5625,0.1336348,0.0668174 +0.1625,0.5625,0.11905508,0.11905503 +0.1625,0.5625,0.08418464,0.1683693 +0.1625,0.5625,0.1683693,0.08418465 +0.1625,0.5875,0.075,0.07499999 +0.1625,0.5875,0.05303301,0.10606605 +0.16250001,0.5875,0.106066026,0.053032935 +0.1625,0.5875,0.094494075,0.094494045 +0.1625,0.5875,0.0668174,0.13363487 +0.1625,0.5875,0.1336348,0.06681734 +0.1625,0.5875,0.11905508,0.11905509 +0.1625,0.5875,0.08418464,0.1683693 +0.1625,0.5875,0.1683693,0.08418465 +0.1625,0.61249995,0.075,0.07499999 +0.1625,0.61249995,0.05303301,0.10606605 +0.16250001,0.6125,0.106066026,0.053032994 +0.1625,0.61249995,0.094494075,0.094494045 +0.1625,0.61249995,0.0668174,0.13363487 +0.1625,0.6125,0.1336348,0.0668174 +0.1625,0.61249995,0.11905508,0.11905509 +0.1625,0.6125,0.08418464,0.1683693 +0.1625,0.6125,0.1683693,0.08418465 +0.1625,0.63750005,0.075,0.07499999 +0.1625,0.63750005,0.05303301,0.10606605 +0.16250001,0.6375,0.106066026,0.053032994 +0.1625,0.63750005,0.094494075,0.094494045 +0.1625,0.63750005,0.0668174,0.13363487 +0.1625,0.6375,0.1336348,0.0668174 +0.1625,0.63750005,0.11905508,0.11905509 +0.1625,0.6375,0.08418464,0.1683693 +0.1625,0.6375,0.1683693,0.08418465 +0.1625,0.6625,0.075,0.07499999 +0.1625,0.6625,0.05303301,0.10606605 +0.16250001,0.6625,0.106066026,0.053032935 +0.1625,0.6625,0.094494075,0.094494045 +0.1625,0.6625,0.0668174,0.13363487 +0.1625,0.6625,0.1336348,0.06681734 +0.1625,0.6625,0.11905508,0.11905509 +0.1625,0.6625,0.08418464,0.1683693 +0.1625,0.6625,0.1683693,0.08418465 +0.1625,0.6875,0.075,0.07500005 +0.1625,0.6875,0.05303301,0.10606599 +0.16250001,0.6875,0.106066026,0.053032994 +0.1625,0.6875,0.094494075,0.094494104 +0.1625,0.6875,0.0668174,0.1336348 +0.1625,0.6875,0.1336348,0.0668174 +0.1625,0.6875,0.11905508,0.11905503 +0.1625,0.6875,0.08418464,0.1683693 +0.1625,0.6875,0.1683693,0.08418465 +0.1625,0.7125,0.075,0.07499999 +0.1625,0.7125,0.05303301,0.10606605 +0.16250001,0.7125,0.106066026,0.053032935 +0.1625,0.7125,0.094494075,0.094494045 +0.1625,0.7125,0.0668174,0.13363487 +0.1625,0.7125,0.1336348,0.06681734 +0.1625,0.7125,0.11905508,0.11905509 +0.1625,0.7125,0.08418464,0.1683693 +0.1625,0.7125,0.1683693,0.08418465 +0.1625,0.73749995,0.075,0.07499999 +0.1625,0.73749995,0.05303301,0.10606605 +0.16250001,0.7375,0.106066026,0.053032994 +0.1625,0.73749995,0.094494075,0.094494045 +0.1625,0.73749995,0.0668174,0.1336348 +0.1625,0.7375,0.1336348,0.0668174 +0.1625,0.73749995,0.11905508,0.11905509 +0.1625,0.7375,0.08418464,0.1683693 +0.1625,0.7375,0.1683693,0.08418465 +0.1625,0.76250005,0.075,0.07499999 +0.1625,0.7625,0.05303301,0.10606599 +0.16250001,0.7625,0.106066026,0.053032994 +0.1625,0.76250005,0.094494075,0.094494045 +0.1625,0.7625,0.0668174,0.1336348 +0.1625,0.7625,0.1336348,0.0668174 +0.1625,0.7625,0.11905508,0.11905503 +0.1625,0.7625,0.08418464,0.1683693 +0.1625,0.7625,0.1683693,0.08418465 +0.1625,0.7875,0.075,0.07499999 +0.1625,0.78749996,0.05303301,0.10606599 +0.16250001,0.7875,0.106066026,0.053032994 +0.1625,0.7875,0.094494075,0.094494045 +0.1625,0.78749996,0.0668174,0.1336348 +0.1625,0.7875,0.1336348,0.0668174 +0.1625,0.78749996,0.11905508,0.11905503 +0.1625,0.7875,0.08418464,0.1683693 +0.1625,0.7875,0.1683693,0.08418465 +0.1625,0.8125,0.075,0.07500005 +0.1625,0.8125,0.05303301,0.10606599 +0.16250001,0.8125,0.106066026,0.053033054 +0.1625,0.8125,0.094494075,0.094494104 +0.1625,0.8125,0.0668174,0.1336348 +0.1625,0.8125,0.1336348,0.06681746 +0.1625,0.8125,0.11905508,0.11905503 +0.1625,0.8125,0.08418464,0.1683693 +0.1625,0.8125,0.1683693,0.08418465 +0.1625,0.8375,0.075,0.07499999 +0.1625,0.8375,0.05303301,0.10606599 +0.16250001,0.8375,0.106066026,0.053033054 +0.1625,0.8375,0.094494075,0.094494045 +0.1625,0.8375,0.0668174,0.1336348 +0.1625,0.8375,0.1336348,0.06681746 +0.1625,0.8375,0.11905508,0.11905503 +0.1625,0.8375,0.08418464,0.1683693 +0.1625,0.8375,0.1683693,0.08418465 +0.1625,0.86249995,0.075,0.07499999 +0.1625,0.86249995,0.05303301,0.10606593 +0.16250001,0.86249995,0.106066026,0.053033054 +0.1625,0.86249995,0.094494075,0.094494045 +0.1625,0.86249995,0.0668174,0.1336348 +0.1625,0.86249995,0.1336348,0.06681746 +0.1625,0.86249995,0.11905508,0.11905497 +0.1625,0.8625,0.08418464,0.1683693 +0.1625,0.8625,0.1683693,0.08418465 +0.1625,0.88750005,0.075,0.07499999 +0.1625,0.88750005,0.05303301,0.10606593 +0.16250001,0.88750005,0.106066026,0.053033054 +0.1625,0.88750005,0.094494075,0.094494045 +0.1625,0.88750005,0.0668174,0.13363475 +0.1625,0.88750005,0.1336348,0.06681746 +0.1625,0.88750005,0.11905508,0.11905497 +0.1625,0.8875,0.08418464,0.1683693 +0.1625,0.8875,0.1683693,0.08418465 +0.1625,0.9125,0.075,0.07499999 +0.1625,0.9125,0.05303301,0.10606593 +0.16250001,0.9125,0.106066026,0.053033054 +0.1625,0.9125,0.094494075,0.094494045 +0.1625,0.9125,0.0668174,0.13363475 +0.1625,0.9125,0.1336348,0.06681746 +0.1625,0.9125,0.11905508,0.11905497 +0.1625,0.9125,0.08418464,0.1683693 +0.1625,0.9125,0.1683693,0.08418465 +0.1625,0.9375,0.075,0.07500005 +0.1625,0.9375,0.05303301,0.10606599 +0.16250001,0.9375,0.106066026,0.053033113 +0.1625,0.9375,0.094494075,0.094494104 +0.1625,0.9375,0.0668174,0.1336348 +0.1625,0.9375,0.1336348,0.06681752 +0.1625,0.9375,0.11905508,0.11905503 +0.1625,0.9375,0.08418464,0.1683693 +0.1625,0.9375,0.1683693,0.08418465 +0.1625,0.9625,0.075,0.07499999 +0.1625,0.9625,0.05303301,0.10606593 +0.16250001,0.9625,0.106066026,0.053033054 +0.1625,0.9625,0.094494075,0.094494045 +0.1625,0.9625,0.0668174,0.13363475 +0.1625,0.9625,0.1336348,0.06681746 +0.1625,0.9625,0.11905508,0.11905497 +0.1625,0.9625,0.08418464,0.1683693 +0.1625,0.9625,0.1683693,0.08418465 +0.1625,0.98749995,0.075,0.07499999 +0.1625,0.98749995,0.05303301,0.10606593 +0.16250001,0.98749995,0.106066026,0.053033054 +0.1625,0.98749995,0.094494075,0.094494045 +0.1625,0.98749995,0.0668174,0.13363475 +0.1625,0.98749995,0.1336348,0.06681746 +0.1625,0.98749995,0.11905508,0.11905497 +0.1625,0.98749995,0.08418464,0.16836923 +0.1625,0.98749995,0.1683693,0.08418459 +0.1875,0.0125,0.07499999,0.075 +0.1875,0.012499997,0.053033024,0.10606602 +0.1875,0.012499999,0.10606603,0.05303301 +0.1875,0.012499999,0.09449406,0.09449408 +0.1875,0.012500001,0.06681742,0.1336348 +0.1875,0.012499999,0.1336348,0.0668174 +0.1875,0.012500001,0.11905509,0.11905508 +0.1875,0.012499999,0.08418465,0.1683693 +0.1875,0.012500002,0.16836931,0.084184654 +0.1875,0.0375,0.07499999,0.075 +0.1875,0.037499998,0.053033024,0.10606601 +0.1875,0.0375,0.10606603,0.05303301 +0.1875,0.0375,0.09449406,0.094494075 +0.1875,0.0375,0.06681742,0.1336348 +0.1875,0.0375,0.1336348,0.0668174 +0.1875,0.0375,0.11905509,0.11905508 +0.1875,0.0375,0.08418465,0.16836931 +0.1875,0.0375,0.16836931,0.08418466 +0.1875,0.0625,0.07499999,0.075 +0.1875,0.0625,0.053033024,0.10606602 +0.1875,0.0625,0.10606603,0.05303301 +0.1875,0.0625,0.09449406,0.094494075 +0.1875,0.0625,0.06681742,0.1336348 +0.1875,0.0625,0.1336348,0.0668174 +0.1875,0.0625,0.11905509,0.11905508 +0.1875,0.0625,0.08418465,0.16836932 +0.1875,0.0625,0.16836931,0.08418465 +0.1875,0.0875,0.07499999,0.075 +0.1875,0.08749999,0.053033024,0.10606601 +0.1875,0.087500006,0.10606603,0.053033013 +0.1875,0.087500006,0.09449406,0.09449408 +0.1875,0.087500006,0.06681742,0.1336348 +0.1875,0.0875,0.1336348,0.0668174 +0.1875,0.0875,0.11905509,0.11905508 +0.1875,0.0875,0.08418465,0.16836931 +0.1875,0.087500006,0.16836931,0.084184654 +0.1875,0.112500004,0.07499999,0.075 +0.1875,0.1125,0.053033024,0.10606601 +0.1875,0.112500004,0.10606603,0.05303301 +0.1875,0.1125,0.09449406,0.094494075 +0.1875,0.1125,0.06681742,0.1336348 +0.1875,0.1125,0.1336348,0.0668174 +0.1875,0.1125,0.11905509,0.119055085 +0.1875,0.112500004,0.08418465,0.16836931 +0.1875,0.1125,0.16836931,0.08418465 +0.1875,0.1375,0.07499999,0.074999996 +0.1875,0.1375,0.053033024,0.10606602 +0.1875,0.1375,0.10606603,0.053033024 +0.1875,0.1375,0.09449406,0.09449408 +0.1875,0.1375,0.06681742,0.1336348 +0.1875,0.1375,0.1336348,0.0668174 +0.1875,0.13749999,0.11905509,0.11905508 +0.1875,0.1375,0.08418465,0.1683693 +0.1875,0.1375,0.16836931,0.084184654 +0.1875,0.1625,0.07499999,0.075 +0.1875,0.16250001,0.053033024,0.106066026 +0.1875,0.1625,0.10606603,0.05303301 +0.1875,0.1625,0.09449406,0.094494075 +0.1875,0.1625,0.06681742,0.1336348 +0.1875,0.1625,0.1336348,0.0668174 +0.1875,0.1625,0.11905509,0.11905508 +0.1875,0.1625,0.08418465,0.1683693 +0.1875,0.1625,0.16836931,0.08418464 +0.1875,0.1875,0.07499999,0.07499999 +0.1875,0.1875,0.053033024,0.10606603 +0.1875,0.1875,0.10606603,0.053033024 +0.1875,0.1875,0.09449406,0.09449406 +0.1875,0.1875,0.06681742,0.1336348 +0.1875,0.1875,0.1336348,0.06681742 +0.1875,0.1875,0.11905509,0.11905509 +0.1875,0.1875,0.08418465,0.16836931 +0.1875,0.1875,0.16836931,0.08418465 +0.1875,0.2125,0.07499999,0.075 +0.1875,0.2125,0.053033024,0.10606603 +0.1875,0.2125,0.10606603,0.05303301 +0.1875,0.21249999,0.09449406,0.094494075 +0.1875,0.2125,0.06681742,0.1336348 +0.1875,0.2125,0.1336348,0.0668174 +0.1875,0.2125,0.11905509,0.11905509 +0.1875,0.2125,0.08418465,0.16836931 +0.1875,0.2125,0.16836931,0.08418465 +0.1875,0.23750001,0.07499999,0.075 +0.1875,0.2375,0.053033024,0.10606602 +0.1875,0.2375,0.10606603,0.053033024 +0.1875,0.2375,0.09449406,0.094494075 +0.1875,0.23750001,0.06681742,0.13363482 +0.1875,0.2375,0.1336348,0.06681743 +0.1875,0.2375,0.11905509,0.11905506 +0.1875,0.2375,0.08418465,0.16836932 +0.1875,0.23750001,0.16836931,0.08418466 +0.1875,0.2625,0.07499999,0.07500002 +0.1875,0.2625,0.053033024,0.10606603 +0.1875,0.2625,0.10606603,0.053033024 +0.1875,0.2625,0.09449406,0.094494075 +0.1875,0.2625,0.06681742,0.13363479 +0.1875,0.2625,0.1336348,0.06681743 +0.1875,0.2625,0.11905509,0.11905508 +0.1875,0.2625,0.08418465,0.1683693 +0.1875,0.2625,0.16836931,0.08418463 +0.1875,0.2875,0.07499999,0.07499999 +0.1875,0.2875,0.053033024,0.10606603 +0.1875,0.28750002,0.10606603,0.053033024 +0.1875,0.2875,0.09449406,0.094494045 +0.1875,0.2875,0.06681742,0.1336348 +0.1875,0.28750002,0.1336348,0.06681743 +0.1875,0.2875,0.11905509,0.11905508 +0.1875,0.2875,0.08418465,0.1683693 +0.1875,0.2875,0.16836931,0.08418465 +0.1875,0.3125,0.07499999,0.07499999 +0.1875,0.3125,0.053033024,0.10606605 +0.1875,0.3125,0.10606603,0.053032994 +0.1875,0.3125,0.09449406,0.094494045 +0.1875,0.3125,0.06681742,0.1336348 +0.1875,0.3125,0.1336348,0.0668174 +0.1875,0.3125,0.11905509,0.11905509 +0.1875,0.3125,0.08418465,0.1683693 +0.1875,0.3125,0.16836931,0.08418465 +0.1875,0.3375,0.07499999,0.07499999 +0.1875,0.3375,0.053033024,0.10606605 +0.1875,0.33749998,0.10606603,0.053033024 +0.1875,0.3375,0.09449406,0.094494045 +0.1875,0.33750004,0.06681742,0.13363484 +0.1875,0.33749998,0.1336348,0.06681743 +0.1875,0.3375,0.11905509,0.11905509 +0.1875,0.3375,0.08418465,0.1683693 +0.1875,0.3375,0.16836931,0.08418465 +0.1875,0.3625,0.07499999,0.07500002 +0.1875,0.3625,0.053033024,0.10606602 +0.1875,0.3625,0.10606603,0.053033024 +0.1875,0.3625,0.09449406,0.094494075 +0.1875,0.3625,0.06681742,0.1336348 +0.1875,0.3625,0.1336348,0.06681743 +0.1875,0.3625,0.11905509,0.11905506 +0.1875,0.3625,0.08418465,0.1683693 +0.1875,0.3625,0.16836931,0.08418465 +0.1875,0.3875,0.07499999,0.07500002 +0.1875,0.3875,0.053033024,0.10606602 +0.1875,0.3875,0.10606603,0.053032994 +0.1875,0.3875,0.09449406,0.094494075 +0.1875,0.3875,0.06681742,0.13363484 +0.1875,0.3875,0.1336348,0.0668174 +0.1875,0.3875,0.11905509,0.11905506 +0.1875,0.3875,0.08418465,0.1683693 +0.1875,0.3875,0.16836931,0.08418465 +0.1875,0.4125,0.07499999,0.07499999 +0.1875,0.4125,0.053033024,0.10606605 +0.1875,0.4125,0.10606603,0.053032994 +0.1875,0.4125,0.09449406,0.094494045 +0.1875,0.41250002,0.06681742,0.13363484 +0.1875,0.4125,0.1336348,0.0668174 +0.1875,0.4125,0.11905509,0.11905509 +0.1875,0.4125,0.08418465,0.1683693 +0.1875,0.4125,0.16836931,0.08418465 +0.1875,0.4375,0.07499999,0.07499999 +0.1875,0.4375,0.053033024,0.10606605 +0.1875,0.4375,0.10606603,0.053032994 +0.1875,0.4375,0.09449406,0.094494045 +0.1875,0.4375,0.06681742,0.1336348 +0.1875,0.4375,0.1336348,0.0668174 +0.1875,0.4375,0.11905509,0.11905509 +0.1875,0.4375,0.08418465,0.1683693 +0.1875,0.4375,0.16836931,0.08418465 +0.1875,0.4625,0.07499999,0.07499999 +0.1875,0.4625,0.053033024,0.10606605 +0.1875,0.46249998,0.10606603,0.053032964 +0.1875,0.4625,0.09449406,0.094494045 +0.1875,0.46250004,0.06681742,0.13363484 +0.1875,0.46249998,0.1336348,0.06681737 +0.1875,0.4625,0.11905509,0.11905509 +0.1875,0.46249998,0.08418465,0.16836926 +0.1875,0.46249998,0.16836931,0.08418462 +0.1875,0.48749998,0.07499999,0.07499999 +0.1875,0.4875,0.053033024,0.10606602 +0.1875,0.4875,0.10606603,0.053032994 +0.1875,0.48749998,0.09449406,0.094494045 +0.1875,0.4875,0.06681742,0.13363484 +0.1875,0.4875,0.1336348,0.0668174 +0.1875,0.4875,0.11905509,0.11905506 +0.1875,0.4875,0.08418465,0.1683693 +0.1875,0.4875,0.16836931,0.08418465 +0.1875,0.5125,0.07499999,0.07500002 +0.1875,0.51250005,0.053033024,0.10606605 +0.1875,0.5125,0.10606603,0.053032964 +0.1875,0.5125,0.09449406,0.094494075 +0.1875,0.51250005,0.06681742,0.13363487 +0.1875,0.5125,0.1336348,0.06681737 +0.1875,0.51250005,0.11905509,0.11905509 +0.1875,0.5125,0.08418465,0.1683693 +0.1875,0.5125,0.16836931,0.08418465 +0.1875,0.5375,0.07499999,0.07499999 +0.1875,0.5375,0.053033024,0.10606605 +0.1875,0.5375,0.10606603,0.053032935 +0.1875,0.5375,0.09449406,0.094494045 +0.1875,0.5375,0.06681742,0.13363487 +0.1875,0.5375,0.1336348,0.06681734 +0.1875,0.5375,0.11905509,0.11905509 +0.1875,0.5375,0.08418465,0.16836932 +0.1875,0.5375,0.16836931,0.08418468 +0.1875,0.5625,0.07499999,0.07500005 +0.1875,0.5625,0.053033024,0.10606599 +0.1875,0.5625,0.10606603,0.053032994 +0.1875,0.5625,0.09449406,0.094494104 +0.1875,0.5625,0.06681742,0.13363484 +0.1875,0.5625,0.1336348,0.0668174 +0.1875,0.5625,0.11905509,0.11905503 +0.1875,0.5625,0.08418465,0.1683693 +0.1875,0.5625,0.16836931,0.08418465 +0.1875,0.5875,0.07499999,0.07499999 +0.1875,0.5875,0.053033024,0.10606605 +0.1875,0.5875,0.10606603,0.053032935 +0.1875,0.5875,0.09449406,0.094494045 +0.1875,0.5875,0.06681742,0.13363487 +0.1875,0.5875,0.1336348,0.06681734 +0.1875,0.5875,0.11905509,0.11905509 +0.1875,0.5875,0.08418465,0.1683693 +0.1875,0.5875,0.16836931,0.08418465 +0.1875,0.61249995,0.07499999,0.07499999 +0.1875,0.61249995,0.053033024,0.10606605 +0.1875,0.6125,0.10606603,0.053032994 +0.1875,0.61249995,0.09449406,0.094494045 +0.1875,0.61249995,0.06681742,0.13363487 +0.1875,0.6125,0.1336348,0.0668174 +0.1875,0.61249995,0.11905509,0.11905509 +0.1875,0.6125,0.08418465,0.1683693 +0.1875,0.6125,0.16836931,0.08418465 +0.1875,0.63750005,0.07499999,0.07499999 +0.1875,0.63750005,0.053033024,0.10606605 +0.1875,0.6375,0.10606603,0.053032994 +0.1875,0.63750005,0.09449406,0.094494045 +0.1875,0.63750005,0.06681742,0.13363487 +0.1875,0.6375,0.1336348,0.0668174 +0.1875,0.63750005,0.11905509,0.11905509 +0.1875,0.6375,0.08418465,0.1683693 +0.1875,0.6375,0.16836931,0.08418465 +0.1875,0.6625,0.07499999,0.07499999 +0.1875,0.6625,0.053033024,0.10606605 +0.1875,0.6625,0.10606603,0.053032935 +0.1875,0.6625,0.09449406,0.094494045 +0.1875,0.6625,0.06681742,0.13363487 +0.1875,0.6625,0.1336348,0.06681734 +0.1875,0.6625,0.11905509,0.11905509 +0.1875,0.6625,0.08418465,0.1683693 +0.1875,0.6625,0.16836931,0.08418465 +0.1875,0.6875,0.07499999,0.07500005 +0.1875,0.6875,0.053033024,0.10606599 +0.1875,0.6875,0.10606603,0.053032994 +0.1875,0.6875,0.09449406,0.094494104 +0.1875,0.6875,0.06681742,0.1336348 +0.1875,0.6875,0.1336348,0.0668174 +0.1875,0.6875,0.11905509,0.11905503 +0.1875,0.6875,0.08418465,0.1683693 +0.1875,0.6875,0.16836931,0.08418465 +0.1875,0.7125,0.07499999,0.07499999 +0.1875,0.7125,0.053033024,0.10606605 +0.1875,0.7125,0.10606603,0.053032935 +0.1875,0.7125,0.09449406,0.094494045 +0.1875,0.7125,0.06681742,0.13363487 +0.1875,0.7125,0.1336348,0.06681734 +0.1875,0.7125,0.11905509,0.11905509 +0.1875,0.7125,0.08418465,0.1683693 +0.1875,0.7125,0.16836931,0.08418465 +0.1875,0.73749995,0.07499999,0.07499999 +0.1875,0.73749995,0.053033024,0.10606605 +0.1875,0.7375,0.10606603,0.053032994 +0.1875,0.73749995,0.09449406,0.094494045 +0.1875,0.73749995,0.06681742,0.1336348 +0.1875,0.7375,0.1336348,0.0668174 +0.1875,0.73749995,0.11905509,0.11905509 +0.1875,0.7375,0.08418465,0.1683693 +0.1875,0.7375,0.16836931,0.08418465 +0.1875,0.76250005,0.07499999,0.07499999 +0.1875,0.7625,0.053033024,0.10606599 +0.1875,0.7625,0.10606603,0.053032994 +0.1875,0.76250005,0.09449406,0.094494045 +0.1875,0.7625,0.06681742,0.1336348 +0.1875,0.7625,0.1336348,0.0668174 +0.1875,0.7625,0.11905509,0.11905503 +0.1875,0.7625,0.08418465,0.1683693 +0.1875,0.7625,0.16836931,0.08418465 +0.1875,0.7875,0.07499999,0.07499999 +0.1875,0.78749996,0.053033024,0.10606599 +0.1875,0.7875,0.10606603,0.053032994 +0.1875,0.7875,0.09449406,0.094494045 +0.1875,0.78749996,0.06681742,0.1336348 +0.1875,0.7875,0.1336348,0.0668174 +0.1875,0.78749996,0.11905509,0.11905503 +0.1875,0.7875,0.08418465,0.1683693 +0.1875,0.7875,0.16836931,0.08418465 +0.1875,0.8125,0.07499999,0.07500005 +0.1875,0.8125,0.053033024,0.10606599 +0.1875,0.8125,0.10606603,0.053033054 +0.1875,0.8125,0.09449406,0.094494104 +0.1875,0.8125,0.06681742,0.1336348 +0.1875,0.8125,0.1336348,0.06681746 +0.1875,0.8125,0.11905509,0.11905503 +0.1875,0.8125,0.08418465,0.1683693 +0.1875,0.8125,0.16836931,0.08418465 +0.1875,0.8375,0.07499999,0.07499999 +0.1875,0.8375,0.053033024,0.10606599 +0.1875,0.8375,0.10606603,0.053033054 +0.1875,0.8375,0.09449406,0.094494045 +0.1875,0.8375,0.06681742,0.1336348 +0.1875,0.8375,0.1336348,0.06681746 +0.1875,0.8375,0.11905509,0.11905503 +0.1875,0.8375,0.08418465,0.1683693 +0.1875,0.8375,0.16836931,0.08418465 +0.1875,0.86249995,0.07499999,0.07499999 +0.1875,0.86249995,0.053033024,0.10606593 +0.1875,0.86249995,0.10606603,0.053033054 +0.1875,0.86249995,0.09449406,0.094494045 +0.1875,0.86249995,0.06681742,0.1336348 +0.1875,0.86249995,0.1336348,0.06681746 +0.1875,0.86249995,0.11905509,0.11905497 +0.1875,0.8625,0.08418465,0.1683693 +0.1875,0.8625,0.16836931,0.08418465 +0.1875,0.88750005,0.07499999,0.07499999 +0.1875,0.88750005,0.053033024,0.10606593 +0.1875,0.88750005,0.10606603,0.053033054 +0.1875,0.88750005,0.09449406,0.094494045 +0.1875,0.88750005,0.06681742,0.13363475 +0.1875,0.88750005,0.1336348,0.06681746 +0.1875,0.88750005,0.11905509,0.11905497 +0.1875,0.8875,0.08418465,0.1683693 +0.1875,0.8875,0.16836931,0.08418465 +0.1875,0.9125,0.07499999,0.07499999 +0.1875,0.9125,0.053033024,0.10606593 +0.1875,0.9125,0.10606603,0.053033054 +0.1875,0.9125,0.09449406,0.094494045 +0.1875,0.9125,0.06681742,0.13363475 +0.1875,0.9125,0.1336348,0.06681746 +0.1875,0.9125,0.11905509,0.11905497 +0.1875,0.9125,0.08418465,0.1683693 +0.1875,0.9125,0.16836931,0.08418465 +0.1875,0.9375,0.07499999,0.07500005 +0.1875,0.9375,0.053033024,0.10606599 +0.1875,0.9375,0.10606603,0.053033113 +0.1875,0.9375,0.09449406,0.094494104 +0.1875,0.9375,0.06681742,0.1336348 +0.1875,0.9375,0.1336348,0.06681752 +0.1875,0.9375,0.11905509,0.11905503 +0.1875,0.9375,0.08418465,0.1683693 +0.1875,0.9375,0.16836931,0.08418465 +0.1875,0.9625,0.07499999,0.07499999 +0.1875,0.9625,0.053033024,0.10606593 +0.1875,0.9625,0.10606603,0.053033054 +0.1875,0.9625,0.09449406,0.094494045 +0.1875,0.9625,0.06681742,0.13363475 +0.1875,0.9625,0.1336348,0.06681746 +0.1875,0.9625,0.11905509,0.11905497 +0.1875,0.9625,0.08418465,0.1683693 +0.1875,0.9625,0.16836931,0.08418465 +0.1875,0.98749995,0.07499999,0.07499999 +0.1875,0.98749995,0.053033024,0.10606593 +0.1875,0.98749995,0.10606603,0.053033054 +0.1875,0.98749995,0.09449406,0.094494045 +0.1875,0.98749995,0.06681742,0.13363475 +0.1875,0.98749995,0.1336348,0.06681746 +0.1875,0.98749995,0.11905509,0.11905497 +0.1875,0.98749995,0.08418465,0.16836923 +0.1875,0.98749995,0.16836931,0.08418459 +0.2125,0.0125,0.075,0.075 +0.2125,0.012499997,0.05303301,0.10606602 +0.2125,0.012499999,0.10606603,0.05303301 +0.21249999,0.012499999,0.094494075,0.09449408 +0.2125,0.012500001,0.0668174,0.1336348 +0.2125,0.012499999,0.1336348,0.0668174 +0.2125,0.012500001,0.11905509,0.11905508 +0.2125,0.012499999,0.08418465,0.1683693 +0.2125,0.012500002,0.16836931,0.084184654 +0.2125,0.0375,0.075,0.075 +0.2125,0.037499998,0.05303301,0.10606601 +0.2125,0.0375,0.10606603,0.05303301 +0.21249999,0.0375,0.094494075,0.094494075 +0.2125,0.0375,0.0668174,0.1336348 +0.2125,0.0375,0.1336348,0.0668174 +0.2125,0.0375,0.11905509,0.11905508 +0.2125,0.0375,0.08418465,0.16836931 +0.2125,0.0375,0.16836931,0.08418466 +0.2125,0.0625,0.075,0.075 +0.2125,0.0625,0.05303301,0.10606602 +0.2125,0.0625,0.10606603,0.05303301 +0.21249999,0.0625,0.094494075,0.094494075 +0.2125,0.0625,0.0668174,0.1336348 +0.2125,0.0625,0.1336348,0.0668174 +0.2125,0.0625,0.11905509,0.11905508 +0.2125,0.0625,0.08418465,0.16836932 +0.2125,0.0625,0.16836931,0.08418465 +0.2125,0.0875,0.075,0.075 +0.2125,0.08749999,0.05303301,0.10606601 +0.2125,0.087500006,0.10606603,0.053033013 +0.21249999,0.087500006,0.094494075,0.09449408 +0.2125,0.087500006,0.0668174,0.1336348 +0.2125,0.0875,0.1336348,0.0668174 +0.2125,0.0875,0.11905509,0.11905508 +0.2125,0.0875,0.08418465,0.16836931 +0.2125,0.087500006,0.16836931,0.084184654 +0.2125,0.112500004,0.075,0.075 +0.2125,0.1125,0.05303301,0.10606601 +0.2125,0.112500004,0.10606603,0.05303301 +0.21249999,0.1125,0.094494075,0.094494075 +0.2125,0.1125,0.0668174,0.1336348 +0.2125,0.1125,0.1336348,0.0668174 +0.2125,0.1125,0.11905509,0.119055085 +0.2125,0.112500004,0.08418465,0.16836931 +0.2125,0.1125,0.16836931,0.08418465 +0.2125,0.1375,0.075,0.074999996 +0.2125,0.1375,0.05303301,0.10606602 +0.2125,0.1375,0.10606603,0.053033024 +0.21249999,0.1375,0.094494075,0.09449408 +0.2125,0.1375,0.0668174,0.1336348 +0.2125,0.1375,0.1336348,0.0668174 +0.2125,0.13749999,0.11905509,0.11905508 +0.2125,0.1375,0.08418465,0.1683693 +0.2125,0.1375,0.16836931,0.084184654 +0.2125,0.1625,0.075,0.075 +0.2125,0.16250001,0.05303301,0.106066026 +0.2125,0.1625,0.10606603,0.05303301 +0.21249999,0.1625,0.094494075,0.094494075 +0.2125,0.1625,0.0668174,0.1336348 +0.2125,0.1625,0.1336348,0.0668174 +0.2125,0.1625,0.11905509,0.11905508 +0.2125,0.1625,0.08418465,0.1683693 +0.2125,0.1625,0.16836931,0.08418464 +0.2125,0.1875,0.075,0.07499999 +0.2125,0.1875,0.05303301,0.10606603 +0.2125,0.1875,0.10606603,0.053033024 +0.21249999,0.1875,0.094494075,0.09449406 +0.2125,0.1875,0.0668174,0.1336348 +0.2125,0.1875,0.1336348,0.06681742 +0.2125,0.1875,0.11905509,0.11905509 +0.2125,0.1875,0.08418465,0.16836931 +0.2125,0.1875,0.16836931,0.08418465 +0.2125,0.2125,0.075,0.075 +0.2125,0.2125,0.05303301,0.10606603 +0.2125,0.2125,0.10606603,0.05303301 +0.21249999,0.21249999,0.094494075,0.094494075 +0.2125,0.2125,0.0668174,0.1336348 +0.2125,0.2125,0.1336348,0.0668174 +0.2125,0.2125,0.11905509,0.11905509 +0.2125,0.2125,0.08418465,0.16836931 +0.2125,0.2125,0.16836931,0.08418465 +0.2125,0.23750001,0.075,0.075 +0.2125,0.2375,0.05303301,0.10606602 +0.2125,0.2375,0.10606603,0.053033024 +0.21249999,0.2375,0.094494075,0.094494075 +0.2125,0.23750001,0.0668174,0.13363482 +0.2125,0.2375,0.1336348,0.06681743 +0.2125,0.2375,0.11905509,0.11905506 +0.2125,0.2375,0.08418465,0.16836932 +0.2125,0.23750001,0.16836931,0.08418466 +0.2125,0.2625,0.075,0.07500002 +0.2125,0.2625,0.05303301,0.10606603 +0.2125,0.2625,0.10606603,0.053033024 +0.21249999,0.2625,0.094494075,0.094494075 +0.2125,0.2625,0.0668174,0.13363479 +0.2125,0.2625,0.1336348,0.06681743 +0.2125,0.2625,0.11905509,0.11905508 +0.2125,0.2625,0.08418465,0.1683693 +0.2125,0.2625,0.16836931,0.08418463 +0.2125,0.2875,0.075,0.07499999 +0.2125,0.2875,0.05303301,0.10606603 +0.2125,0.28750002,0.10606603,0.053033024 +0.21249999,0.2875,0.094494075,0.094494045 +0.2125,0.2875,0.0668174,0.1336348 +0.2125,0.28750002,0.1336348,0.06681743 +0.2125,0.2875,0.11905509,0.11905508 +0.2125,0.2875,0.08418465,0.1683693 +0.2125,0.2875,0.16836931,0.08418465 +0.2125,0.3125,0.075,0.07499999 +0.2125,0.3125,0.05303301,0.10606605 +0.2125,0.3125,0.10606603,0.053032994 +0.21249999,0.3125,0.094494075,0.094494045 +0.2125,0.3125,0.0668174,0.1336348 +0.2125,0.3125,0.1336348,0.0668174 +0.2125,0.3125,0.11905509,0.11905509 +0.2125,0.3125,0.08418465,0.1683693 +0.2125,0.3125,0.16836931,0.08418465 +0.2125,0.3375,0.075,0.07499999 +0.2125,0.3375,0.05303301,0.10606605 +0.2125,0.33749998,0.10606603,0.053033024 +0.21249999,0.3375,0.094494075,0.094494045 +0.2125,0.33750004,0.0668174,0.13363484 +0.2125,0.33749998,0.1336348,0.06681743 +0.2125,0.3375,0.11905509,0.11905509 +0.2125,0.3375,0.08418465,0.1683693 +0.2125,0.3375,0.16836931,0.08418465 +0.2125,0.3625,0.075,0.07500002 +0.2125,0.3625,0.05303301,0.10606602 +0.2125,0.3625,0.10606603,0.053033024 +0.21249999,0.3625,0.094494075,0.094494075 +0.2125,0.3625,0.0668174,0.1336348 +0.2125,0.3625,0.1336348,0.06681743 +0.2125,0.3625,0.11905509,0.11905506 +0.2125,0.3625,0.08418465,0.1683693 +0.2125,0.3625,0.16836931,0.08418465 +0.2125,0.3875,0.075,0.07500002 +0.2125,0.3875,0.05303301,0.10606602 +0.2125,0.3875,0.10606603,0.053032994 +0.21249999,0.3875,0.094494075,0.094494075 +0.2125,0.3875,0.0668174,0.13363484 +0.2125,0.3875,0.1336348,0.0668174 +0.2125,0.3875,0.11905509,0.11905506 +0.2125,0.3875,0.08418465,0.1683693 +0.2125,0.3875,0.16836931,0.08418465 +0.2125,0.4125,0.075,0.07499999 +0.2125,0.4125,0.05303301,0.10606605 +0.2125,0.4125,0.10606603,0.053032994 +0.21249999,0.4125,0.094494075,0.094494045 +0.2125,0.41250002,0.0668174,0.13363484 +0.2125,0.4125,0.1336348,0.0668174 +0.2125,0.4125,0.11905509,0.11905509 +0.2125,0.4125,0.08418465,0.1683693 +0.2125,0.4125,0.16836931,0.08418465 +0.2125,0.4375,0.075,0.07499999 +0.2125,0.4375,0.05303301,0.10606605 +0.2125,0.4375,0.10606603,0.053032994 +0.21249999,0.4375,0.094494075,0.094494045 +0.2125,0.4375,0.0668174,0.1336348 +0.2125,0.4375,0.1336348,0.0668174 +0.2125,0.4375,0.11905509,0.11905509 +0.2125,0.4375,0.08418465,0.1683693 +0.2125,0.4375,0.16836931,0.08418465 +0.2125,0.4625,0.075,0.07499999 +0.2125,0.4625,0.05303301,0.10606605 +0.2125,0.46249998,0.10606603,0.053032964 +0.21249999,0.4625,0.094494075,0.094494045 +0.2125,0.46250004,0.0668174,0.13363484 +0.2125,0.46249998,0.1336348,0.06681737 +0.2125,0.4625,0.11905509,0.11905509 +0.2125,0.46249998,0.08418465,0.16836926 +0.2125,0.46249998,0.16836931,0.08418462 +0.2125,0.48749998,0.075,0.07499999 +0.2125,0.4875,0.05303301,0.10606602 +0.2125,0.4875,0.10606603,0.053032994 +0.21249999,0.48749998,0.094494075,0.094494045 +0.2125,0.4875,0.0668174,0.13363484 +0.2125,0.4875,0.1336348,0.0668174 +0.2125,0.4875,0.11905509,0.11905506 +0.2125,0.4875,0.08418465,0.1683693 +0.2125,0.4875,0.16836931,0.08418465 +0.2125,0.5125,0.075,0.07500002 +0.2125,0.51250005,0.05303301,0.10606605 +0.2125,0.5125,0.10606603,0.053032964 +0.21249999,0.5125,0.094494075,0.094494075 +0.2125,0.51250005,0.0668174,0.13363487 +0.2125,0.5125,0.1336348,0.06681737 +0.2125,0.51250005,0.11905509,0.11905509 +0.2125,0.5125,0.08418465,0.1683693 +0.2125,0.5125,0.16836931,0.08418465 +0.2125,0.5375,0.075,0.07499999 +0.2125,0.5375,0.05303301,0.10606605 +0.2125,0.5375,0.10606603,0.053032935 +0.21249999,0.5375,0.094494075,0.094494045 +0.2125,0.5375,0.0668174,0.13363487 +0.2125,0.5375,0.1336348,0.06681734 +0.2125,0.5375,0.11905509,0.11905509 +0.2125,0.5375,0.08418465,0.16836932 +0.2125,0.5375,0.16836931,0.08418468 +0.2125,0.5625,0.075,0.07500005 +0.2125,0.5625,0.05303301,0.10606599 +0.2125,0.5625,0.10606603,0.053032994 +0.21249999,0.5625,0.094494075,0.094494104 +0.2125,0.5625,0.0668174,0.13363484 +0.2125,0.5625,0.1336348,0.0668174 +0.2125,0.5625,0.11905509,0.11905503 +0.2125,0.5625,0.08418465,0.1683693 +0.2125,0.5625,0.16836931,0.08418465 +0.2125,0.5875,0.075,0.07499999 +0.2125,0.5875,0.05303301,0.10606605 +0.2125,0.5875,0.10606603,0.053032935 +0.21249999,0.5875,0.094494075,0.094494045 +0.2125,0.5875,0.0668174,0.13363487 +0.2125,0.5875,0.1336348,0.06681734 +0.2125,0.5875,0.11905509,0.11905509 +0.2125,0.5875,0.08418465,0.1683693 +0.2125,0.5875,0.16836931,0.08418465 +0.2125,0.61249995,0.075,0.07499999 +0.2125,0.61249995,0.05303301,0.10606605 +0.2125,0.6125,0.10606603,0.053032994 +0.21249999,0.61249995,0.094494075,0.094494045 +0.2125,0.61249995,0.0668174,0.13363487 +0.2125,0.6125,0.1336348,0.0668174 +0.2125,0.61249995,0.11905509,0.11905509 +0.2125,0.6125,0.08418465,0.1683693 +0.2125,0.6125,0.16836931,0.08418465 +0.2125,0.63750005,0.075,0.07499999 +0.2125,0.63750005,0.05303301,0.10606605 +0.2125,0.6375,0.10606603,0.053032994 +0.21249999,0.63750005,0.094494075,0.094494045 +0.2125,0.63750005,0.0668174,0.13363487 +0.2125,0.6375,0.1336348,0.0668174 +0.2125,0.63750005,0.11905509,0.11905509 +0.2125,0.6375,0.08418465,0.1683693 +0.2125,0.6375,0.16836931,0.08418465 +0.2125,0.6625,0.075,0.07499999 +0.2125,0.6625,0.05303301,0.10606605 +0.2125,0.6625,0.10606603,0.053032935 +0.21249999,0.6625,0.094494075,0.094494045 +0.2125,0.6625,0.0668174,0.13363487 +0.2125,0.6625,0.1336348,0.06681734 +0.2125,0.6625,0.11905509,0.11905509 +0.2125,0.6625,0.08418465,0.1683693 +0.2125,0.6625,0.16836931,0.08418465 +0.2125,0.6875,0.075,0.07500005 +0.2125,0.6875,0.05303301,0.10606599 +0.2125,0.6875,0.10606603,0.053032994 +0.21249999,0.6875,0.094494075,0.094494104 +0.2125,0.6875,0.0668174,0.1336348 +0.2125,0.6875,0.1336348,0.0668174 +0.2125,0.6875,0.11905509,0.11905503 +0.2125,0.6875,0.08418465,0.1683693 +0.2125,0.6875,0.16836931,0.08418465 +0.2125,0.7125,0.075,0.07499999 +0.2125,0.7125,0.05303301,0.10606605 +0.2125,0.7125,0.10606603,0.053032935 +0.21249999,0.7125,0.094494075,0.094494045 +0.2125,0.7125,0.0668174,0.13363487 +0.2125,0.7125,0.1336348,0.06681734 +0.2125,0.7125,0.11905509,0.11905509 +0.2125,0.7125,0.08418465,0.1683693 +0.2125,0.7125,0.16836931,0.08418465 +0.2125,0.73749995,0.075,0.07499999 +0.2125,0.73749995,0.05303301,0.10606605 +0.2125,0.7375,0.10606603,0.053032994 +0.21249999,0.73749995,0.094494075,0.094494045 +0.2125,0.73749995,0.0668174,0.1336348 +0.2125,0.7375,0.1336348,0.0668174 +0.2125,0.73749995,0.11905509,0.11905509 +0.2125,0.7375,0.08418465,0.1683693 +0.2125,0.7375,0.16836931,0.08418465 +0.2125,0.76250005,0.075,0.07499999 +0.2125,0.7625,0.05303301,0.10606599 +0.2125,0.7625,0.10606603,0.053032994 +0.21249999,0.76250005,0.094494075,0.094494045 +0.2125,0.7625,0.0668174,0.1336348 +0.2125,0.7625,0.1336348,0.0668174 +0.2125,0.7625,0.11905509,0.11905503 +0.2125,0.7625,0.08418465,0.1683693 +0.2125,0.7625,0.16836931,0.08418465 +0.2125,0.7875,0.075,0.07499999 +0.2125,0.78749996,0.05303301,0.10606599 +0.2125,0.7875,0.10606603,0.053032994 +0.21249999,0.7875,0.094494075,0.094494045 +0.2125,0.78749996,0.0668174,0.1336348 +0.2125,0.7875,0.1336348,0.0668174 +0.2125,0.78749996,0.11905509,0.11905503 +0.2125,0.7875,0.08418465,0.1683693 +0.2125,0.7875,0.16836931,0.08418465 +0.2125,0.8125,0.075,0.07500005 +0.2125,0.8125,0.05303301,0.10606599 +0.2125,0.8125,0.10606603,0.053033054 +0.21249999,0.8125,0.094494075,0.094494104 +0.2125,0.8125,0.0668174,0.1336348 +0.2125,0.8125,0.1336348,0.06681746 +0.2125,0.8125,0.11905509,0.11905503 +0.2125,0.8125,0.08418465,0.1683693 +0.2125,0.8125,0.16836931,0.08418465 +0.2125,0.8375,0.075,0.07499999 +0.2125,0.8375,0.05303301,0.10606599 +0.2125,0.8375,0.10606603,0.053033054 +0.21249999,0.8375,0.094494075,0.094494045 +0.2125,0.8375,0.0668174,0.1336348 +0.2125,0.8375,0.1336348,0.06681746 +0.2125,0.8375,0.11905509,0.11905503 +0.2125,0.8375,0.08418465,0.1683693 +0.2125,0.8375,0.16836931,0.08418465 +0.2125,0.86249995,0.075,0.07499999 +0.2125,0.86249995,0.05303301,0.10606593 +0.2125,0.86249995,0.10606603,0.053033054 +0.21249999,0.86249995,0.094494075,0.094494045 +0.2125,0.86249995,0.0668174,0.1336348 +0.2125,0.86249995,0.1336348,0.06681746 +0.2125,0.86249995,0.11905509,0.11905497 +0.2125,0.8625,0.08418465,0.1683693 +0.2125,0.8625,0.16836931,0.08418465 +0.2125,0.88750005,0.075,0.07499999 +0.2125,0.88750005,0.05303301,0.10606593 +0.2125,0.88750005,0.10606603,0.053033054 +0.21249999,0.88750005,0.094494075,0.094494045 +0.2125,0.88750005,0.0668174,0.13363475 +0.2125,0.88750005,0.1336348,0.06681746 +0.2125,0.88750005,0.11905509,0.11905497 +0.2125,0.8875,0.08418465,0.1683693 +0.2125,0.8875,0.16836931,0.08418465 +0.2125,0.9125,0.075,0.07499999 +0.2125,0.9125,0.05303301,0.10606593 +0.2125,0.9125,0.10606603,0.053033054 +0.21249999,0.9125,0.094494075,0.094494045 +0.2125,0.9125,0.0668174,0.13363475 +0.2125,0.9125,0.1336348,0.06681746 +0.2125,0.9125,0.11905509,0.11905497 +0.2125,0.9125,0.08418465,0.1683693 +0.2125,0.9125,0.16836931,0.08418465 +0.2125,0.9375,0.075,0.07500005 +0.2125,0.9375,0.05303301,0.10606599 +0.2125,0.9375,0.10606603,0.053033113 +0.21249999,0.9375,0.094494075,0.094494104 +0.2125,0.9375,0.0668174,0.1336348 +0.2125,0.9375,0.1336348,0.06681752 +0.2125,0.9375,0.11905509,0.11905503 +0.2125,0.9375,0.08418465,0.1683693 +0.2125,0.9375,0.16836931,0.08418465 +0.2125,0.9625,0.075,0.07499999 +0.2125,0.9625,0.05303301,0.10606593 +0.2125,0.9625,0.10606603,0.053033054 +0.21249999,0.9625,0.094494075,0.094494045 +0.2125,0.9625,0.0668174,0.13363475 +0.2125,0.9625,0.1336348,0.06681746 +0.2125,0.9625,0.11905509,0.11905497 +0.2125,0.9625,0.08418465,0.1683693 +0.2125,0.9625,0.16836931,0.08418465 +0.2125,0.98749995,0.075,0.07499999 +0.2125,0.98749995,0.05303301,0.10606593 +0.2125,0.98749995,0.10606603,0.053033054 +0.21249999,0.98749995,0.094494075,0.094494045 +0.2125,0.98749995,0.0668174,0.13363475 +0.2125,0.98749995,0.1336348,0.06681746 +0.2125,0.98749995,0.11905509,0.11905497 +0.2125,0.98749995,0.08418465,0.16836923 +0.2125,0.98749995,0.16836931,0.08418459 +0.23750001,0.0125,0.075,0.075 +0.2375,0.012499997,0.053033024,0.10606602 +0.2375,0.012499999,0.10606602,0.05303301 +0.2375,0.012499999,0.094494075,0.09449408 +0.2375,0.012500001,0.06681743,0.1336348 +0.23750001,0.012499999,0.13363482,0.0668174 +0.2375,0.012500001,0.11905506,0.11905508 +0.23750001,0.012499999,0.08418466,0.1683693 +0.2375,0.012500002,0.16836932,0.084184654 +0.23750001,0.0375,0.075,0.075 +0.2375,0.037499998,0.053033024,0.10606601 +0.2375,0.0375,0.10606602,0.05303301 +0.2375,0.0375,0.094494075,0.094494075 +0.2375,0.0375,0.06681743,0.1336348 +0.23750001,0.0375,0.13363482,0.0668174 +0.2375,0.0375,0.11905506,0.11905508 +0.23750001,0.0375,0.08418466,0.16836931 +0.2375,0.0375,0.16836932,0.08418466 +0.23750001,0.0625,0.075,0.075 +0.2375,0.0625,0.053033024,0.10606602 +0.2375,0.0625,0.10606602,0.05303301 +0.2375,0.0625,0.094494075,0.094494075 +0.2375,0.0625,0.06681743,0.1336348 +0.23750001,0.0625,0.13363482,0.0668174 +0.2375,0.0625,0.11905506,0.11905508 +0.23750001,0.0625,0.08418466,0.16836932 +0.2375,0.0625,0.16836932,0.08418465 +0.23750001,0.0875,0.075,0.075 +0.2375,0.08749999,0.053033024,0.10606601 +0.2375,0.087500006,0.10606602,0.053033013 +0.2375,0.087500006,0.094494075,0.09449408 +0.2375,0.087500006,0.06681743,0.1336348 +0.23750001,0.0875,0.13363482,0.0668174 +0.2375,0.0875,0.11905506,0.11905508 +0.23750001,0.0875,0.08418466,0.16836931 +0.2375,0.087500006,0.16836932,0.084184654 +0.23750001,0.112500004,0.075,0.075 +0.2375,0.1125,0.053033024,0.10606601 +0.2375,0.112500004,0.10606602,0.05303301 +0.2375,0.1125,0.094494075,0.094494075 +0.2375,0.1125,0.06681743,0.1336348 +0.23750001,0.1125,0.13363482,0.0668174 +0.2375,0.1125,0.11905506,0.119055085 +0.23750001,0.112500004,0.08418466,0.16836931 +0.2375,0.1125,0.16836932,0.08418465 +0.23750001,0.1375,0.075,0.074999996 +0.2375,0.1375,0.053033024,0.10606602 +0.2375,0.1375,0.10606602,0.053033024 +0.2375,0.1375,0.094494075,0.09449408 +0.2375,0.1375,0.06681743,0.1336348 +0.23750001,0.1375,0.13363482,0.0668174 +0.2375,0.13749999,0.11905506,0.11905508 +0.23750001,0.1375,0.08418466,0.1683693 +0.2375,0.1375,0.16836932,0.084184654 +0.23750001,0.1625,0.075,0.075 +0.2375,0.16250001,0.053033024,0.106066026 +0.2375,0.1625,0.10606602,0.05303301 +0.2375,0.1625,0.094494075,0.094494075 +0.2375,0.1625,0.06681743,0.1336348 +0.23750001,0.1625,0.13363482,0.0668174 +0.2375,0.1625,0.11905506,0.11905508 +0.23750001,0.1625,0.08418466,0.1683693 +0.2375,0.1625,0.16836932,0.08418464 +0.23750001,0.1875,0.075,0.07499999 +0.2375,0.1875,0.053033024,0.10606603 +0.2375,0.1875,0.10606602,0.053033024 +0.2375,0.1875,0.094494075,0.09449406 +0.2375,0.1875,0.06681743,0.1336348 +0.23750001,0.1875,0.13363482,0.06681742 +0.2375,0.1875,0.11905506,0.11905509 +0.23750001,0.1875,0.08418466,0.16836931 +0.2375,0.1875,0.16836932,0.08418465 +0.23750001,0.2125,0.075,0.075 +0.2375,0.2125,0.053033024,0.10606603 +0.2375,0.2125,0.10606602,0.05303301 +0.2375,0.21249999,0.094494075,0.094494075 +0.2375,0.2125,0.06681743,0.1336348 +0.23750001,0.2125,0.13363482,0.0668174 +0.2375,0.2125,0.11905506,0.11905509 +0.23750001,0.2125,0.08418466,0.16836931 +0.2375,0.2125,0.16836932,0.08418465 +0.23750001,0.23750001,0.075,0.075 +0.2375,0.2375,0.053033024,0.10606602 +0.2375,0.2375,0.10606602,0.053033024 +0.2375,0.2375,0.094494075,0.094494075 +0.2375,0.23750001,0.06681743,0.13363482 +0.23750001,0.2375,0.13363482,0.06681743 +0.2375,0.2375,0.11905506,0.11905506 +0.23750001,0.2375,0.08418466,0.16836932 +0.2375,0.23750001,0.16836932,0.08418466 +0.23750001,0.2625,0.075,0.07500002 +0.2375,0.2625,0.053033024,0.10606603 +0.2375,0.2625,0.10606602,0.053033024 +0.2375,0.2625,0.094494075,0.094494075 +0.2375,0.2625,0.06681743,0.13363479 +0.23750001,0.2625,0.13363482,0.06681743 +0.2375,0.2625,0.11905506,0.11905508 +0.23750001,0.2625,0.08418466,0.1683693 +0.2375,0.2625,0.16836932,0.08418463 +0.23750001,0.2875,0.075,0.07499999 +0.2375,0.2875,0.053033024,0.10606603 +0.2375,0.28750002,0.10606602,0.053033024 +0.2375,0.2875,0.094494075,0.094494045 +0.2375,0.2875,0.06681743,0.1336348 +0.23750001,0.28750002,0.13363482,0.06681743 +0.2375,0.2875,0.11905506,0.11905508 +0.23750001,0.2875,0.08418466,0.1683693 +0.2375,0.2875,0.16836932,0.08418465 +0.23750001,0.3125,0.075,0.07499999 +0.2375,0.3125,0.053033024,0.10606605 +0.2375,0.3125,0.10606602,0.053032994 +0.2375,0.3125,0.094494075,0.094494045 +0.2375,0.3125,0.06681743,0.1336348 +0.23750001,0.3125,0.13363482,0.0668174 +0.2375,0.3125,0.11905506,0.11905509 +0.23750001,0.3125,0.08418466,0.1683693 +0.2375,0.3125,0.16836932,0.08418465 +0.23750001,0.3375,0.075,0.07499999 +0.2375,0.3375,0.053033024,0.10606605 +0.2375,0.33749998,0.10606602,0.053033024 +0.2375,0.3375,0.094494075,0.094494045 +0.2375,0.33750004,0.06681743,0.13363484 +0.23750001,0.33749998,0.13363482,0.06681743 +0.2375,0.3375,0.11905506,0.11905509 +0.23750001,0.3375,0.08418466,0.1683693 +0.2375,0.3375,0.16836932,0.08418465 +0.23750001,0.3625,0.075,0.07500002 +0.2375,0.3625,0.053033024,0.10606602 +0.2375,0.3625,0.10606602,0.053033024 +0.2375,0.3625,0.094494075,0.094494075 +0.2375,0.3625,0.06681743,0.1336348 +0.23750001,0.3625,0.13363482,0.06681743 +0.2375,0.3625,0.11905506,0.11905506 +0.23750001,0.3625,0.08418466,0.1683693 +0.2375,0.3625,0.16836932,0.08418465 +0.23750001,0.3875,0.075,0.07500002 +0.2375,0.3875,0.053033024,0.10606602 +0.2375,0.3875,0.10606602,0.053032994 +0.2375,0.3875,0.094494075,0.094494075 +0.2375,0.3875,0.06681743,0.13363484 +0.23750001,0.3875,0.13363482,0.0668174 +0.2375,0.3875,0.11905506,0.11905506 +0.23750001,0.3875,0.08418466,0.1683693 +0.2375,0.3875,0.16836932,0.08418465 +0.23750001,0.4125,0.075,0.07499999 +0.2375,0.4125,0.053033024,0.10606605 +0.2375,0.4125,0.10606602,0.053032994 +0.2375,0.4125,0.094494075,0.094494045 +0.2375,0.41250002,0.06681743,0.13363484 +0.23750001,0.4125,0.13363482,0.0668174 +0.2375,0.4125,0.11905506,0.11905509 +0.23750001,0.4125,0.08418466,0.1683693 +0.2375,0.4125,0.16836932,0.08418465 +0.23750001,0.4375,0.075,0.07499999 +0.2375,0.4375,0.053033024,0.10606605 +0.2375,0.4375,0.10606602,0.053032994 +0.2375,0.4375,0.094494075,0.094494045 +0.2375,0.4375,0.06681743,0.1336348 +0.23750001,0.4375,0.13363482,0.0668174 +0.2375,0.4375,0.11905506,0.11905509 +0.23750001,0.4375,0.08418466,0.1683693 +0.2375,0.4375,0.16836932,0.08418465 +0.23750001,0.4625,0.075,0.07499999 +0.2375,0.4625,0.053033024,0.10606605 +0.2375,0.46249998,0.10606602,0.053032964 +0.2375,0.4625,0.094494075,0.094494045 +0.2375,0.46250004,0.06681743,0.13363484 +0.23750001,0.46249998,0.13363482,0.06681737 +0.2375,0.4625,0.11905506,0.11905509 +0.23750001,0.46249998,0.08418466,0.16836926 +0.2375,0.46249998,0.16836932,0.08418462 +0.23750001,0.48749998,0.075,0.07499999 +0.2375,0.4875,0.053033024,0.10606602 +0.2375,0.4875,0.10606602,0.053032994 +0.2375,0.48749998,0.094494075,0.094494045 +0.2375,0.4875,0.06681743,0.13363484 +0.23750001,0.4875,0.13363482,0.0668174 +0.2375,0.4875,0.11905506,0.11905506 +0.23750001,0.4875,0.08418466,0.1683693 +0.2375,0.4875,0.16836932,0.08418465 +0.23750001,0.5125,0.075,0.07500002 +0.2375,0.51250005,0.053033024,0.10606605 +0.2375,0.5125,0.10606602,0.053032964 +0.2375,0.5125,0.094494075,0.094494075 +0.2375,0.51250005,0.06681743,0.13363487 +0.23750001,0.5125,0.13363482,0.06681737 +0.2375,0.51250005,0.11905506,0.11905509 +0.23750001,0.5125,0.08418466,0.1683693 +0.2375,0.5125,0.16836932,0.08418465 +0.23750001,0.5375,0.075,0.07499999 +0.2375,0.5375,0.053033024,0.10606605 +0.2375,0.5375,0.10606602,0.053032935 +0.2375,0.5375,0.094494075,0.094494045 +0.2375,0.5375,0.06681743,0.13363487 +0.23750001,0.5375,0.13363482,0.06681734 +0.2375,0.5375,0.11905506,0.11905509 +0.23750001,0.5375,0.08418466,0.16836932 +0.2375,0.5375,0.16836932,0.08418468 +0.23750001,0.5625,0.075,0.07500005 +0.2375,0.5625,0.053033024,0.10606599 +0.2375,0.5625,0.10606602,0.053032994 +0.2375,0.5625,0.094494075,0.094494104 +0.2375,0.5625,0.06681743,0.13363484 +0.23750001,0.5625,0.13363482,0.0668174 +0.2375,0.5625,0.11905506,0.11905503 +0.23750001,0.5625,0.08418466,0.1683693 +0.2375,0.5625,0.16836932,0.08418465 +0.23750001,0.5875,0.075,0.07499999 +0.2375,0.5875,0.053033024,0.10606605 +0.2375,0.5875,0.10606602,0.053032935 +0.2375,0.5875,0.094494075,0.094494045 +0.2375,0.5875,0.06681743,0.13363487 +0.23750001,0.5875,0.13363482,0.06681734 +0.2375,0.5875,0.11905506,0.11905509 +0.23750001,0.5875,0.08418466,0.1683693 +0.2375,0.5875,0.16836932,0.08418465 +0.23750001,0.61249995,0.075,0.07499999 +0.2375,0.61249995,0.053033024,0.10606605 +0.2375,0.6125,0.10606602,0.053032994 +0.2375,0.61249995,0.094494075,0.094494045 +0.2375,0.61249995,0.06681743,0.13363487 +0.23750001,0.6125,0.13363482,0.0668174 +0.2375,0.61249995,0.11905506,0.11905509 +0.23750001,0.6125,0.08418466,0.1683693 +0.2375,0.6125,0.16836932,0.08418465 +0.23750001,0.63750005,0.075,0.07499999 +0.2375,0.63750005,0.053033024,0.10606605 +0.2375,0.6375,0.10606602,0.053032994 +0.2375,0.63750005,0.094494075,0.094494045 +0.2375,0.63750005,0.06681743,0.13363487 +0.23750001,0.6375,0.13363482,0.0668174 +0.2375,0.63750005,0.11905506,0.11905509 +0.23750001,0.6375,0.08418466,0.1683693 +0.2375,0.6375,0.16836932,0.08418465 +0.23750001,0.6625,0.075,0.07499999 +0.2375,0.6625,0.053033024,0.10606605 +0.2375,0.6625,0.10606602,0.053032935 +0.2375,0.6625,0.094494075,0.094494045 +0.2375,0.6625,0.06681743,0.13363487 +0.23750001,0.6625,0.13363482,0.06681734 +0.2375,0.6625,0.11905506,0.11905509 +0.23750001,0.6625,0.08418466,0.1683693 +0.2375,0.6625,0.16836932,0.08418465 +0.23750001,0.6875,0.075,0.07500005 +0.2375,0.6875,0.053033024,0.10606599 +0.2375,0.6875,0.10606602,0.053032994 +0.2375,0.6875,0.094494075,0.094494104 +0.2375,0.6875,0.06681743,0.1336348 +0.23750001,0.6875,0.13363482,0.0668174 +0.2375,0.6875,0.11905506,0.11905503 +0.23750001,0.6875,0.08418466,0.1683693 +0.2375,0.6875,0.16836932,0.08418465 +0.23750001,0.7125,0.075,0.07499999 +0.2375,0.7125,0.053033024,0.10606605 +0.2375,0.7125,0.10606602,0.053032935 +0.2375,0.7125,0.094494075,0.094494045 +0.2375,0.7125,0.06681743,0.13363487 +0.23750001,0.7125,0.13363482,0.06681734 +0.2375,0.7125,0.11905506,0.11905509 +0.23750001,0.7125,0.08418466,0.1683693 +0.2375,0.7125,0.16836932,0.08418465 +0.23750001,0.73749995,0.075,0.07499999 +0.2375,0.73749995,0.053033024,0.10606605 +0.2375,0.7375,0.10606602,0.053032994 +0.2375,0.73749995,0.094494075,0.094494045 +0.2375,0.73749995,0.06681743,0.1336348 +0.23750001,0.7375,0.13363482,0.0668174 +0.2375,0.73749995,0.11905506,0.11905509 +0.23750001,0.7375,0.08418466,0.1683693 +0.2375,0.7375,0.16836932,0.08418465 +0.23750001,0.76250005,0.075,0.07499999 +0.2375,0.7625,0.053033024,0.10606599 +0.2375,0.7625,0.10606602,0.053032994 +0.2375,0.76250005,0.094494075,0.094494045 +0.2375,0.7625,0.06681743,0.1336348 +0.23750001,0.7625,0.13363482,0.0668174 +0.2375,0.7625,0.11905506,0.11905503 +0.23750001,0.7625,0.08418466,0.1683693 +0.2375,0.7625,0.16836932,0.08418465 +0.23750001,0.7875,0.075,0.07499999 +0.2375,0.78749996,0.053033024,0.10606599 +0.2375,0.7875,0.10606602,0.053032994 +0.2375,0.7875,0.094494075,0.094494045 +0.2375,0.78749996,0.06681743,0.1336348 +0.23750001,0.7875,0.13363482,0.0668174 +0.2375,0.78749996,0.11905506,0.11905503 +0.23750001,0.7875,0.08418466,0.1683693 +0.2375,0.7875,0.16836932,0.08418465 +0.23750001,0.8125,0.075,0.07500005 +0.2375,0.8125,0.053033024,0.10606599 +0.2375,0.8125,0.10606602,0.053033054 +0.2375,0.8125,0.094494075,0.094494104 +0.2375,0.8125,0.06681743,0.1336348 +0.23750001,0.8125,0.13363482,0.06681746 +0.2375,0.8125,0.11905506,0.11905503 +0.23750001,0.8125,0.08418466,0.1683693 +0.2375,0.8125,0.16836932,0.08418465 +0.23750001,0.8375,0.075,0.07499999 +0.2375,0.8375,0.053033024,0.10606599 +0.2375,0.8375,0.10606602,0.053033054 +0.2375,0.8375,0.094494075,0.094494045 +0.2375,0.8375,0.06681743,0.1336348 +0.23750001,0.8375,0.13363482,0.06681746 +0.2375,0.8375,0.11905506,0.11905503 +0.23750001,0.8375,0.08418466,0.1683693 +0.2375,0.8375,0.16836932,0.08418465 +0.23750001,0.86249995,0.075,0.07499999 +0.2375,0.86249995,0.053033024,0.10606593 +0.2375,0.86249995,0.10606602,0.053033054 +0.2375,0.86249995,0.094494075,0.094494045 +0.2375,0.86249995,0.06681743,0.1336348 +0.23750001,0.86249995,0.13363482,0.06681746 +0.2375,0.86249995,0.11905506,0.11905497 +0.23750001,0.8625,0.08418466,0.1683693 +0.2375,0.8625,0.16836932,0.08418465 +0.23750001,0.88750005,0.075,0.07499999 +0.2375,0.88750005,0.053033024,0.10606593 +0.2375,0.88750005,0.10606602,0.053033054 +0.2375,0.88750005,0.094494075,0.094494045 +0.2375,0.88750005,0.06681743,0.13363475 +0.23750001,0.88750005,0.13363482,0.06681746 +0.2375,0.88750005,0.11905506,0.11905497 +0.23750001,0.8875,0.08418466,0.1683693 +0.2375,0.8875,0.16836932,0.08418465 +0.23750001,0.9125,0.075,0.07499999 +0.2375,0.9125,0.053033024,0.10606593 +0.2375,0.9125,0.10606602,0.053033054 +0.2375,0.9125,0.094494075,0.094494045 +0.2375,0.9125,0.06681743,0.13363475 +0.23750001,0.9125,0.13363482,0.06681746 +0.2375,0.9125,0.11905506,0.11905497 +0.23750001,0.9125,0.08418466,0.1683693 +0.2375,0.9125,0.16836932,0.08418465 +0.23750001,0.9375,0.075,0.07500005 +0.2375,0.9375,0.053033024,0.10606599 +0.2375,0.9375,0.10606602,0.053033113 +0.2375,0.9375,0.094494075,0.094494104 +0.2375,0.9375,0.06681743,0.1336348 +0.23750001,0.9375,0.13363482,0.06681752 +0.2375,0.9375,0.11905506,0.11905503 +0.23750001,0.9375,0.08418466,0.1683693 +0.2375,0.9375,0.16836932,0.08418465 +0.23750001,0.9625,0.075,0.07499999 +0.2375,0.9625,0.053033024,0.10606593 +0.2375,0.9625,0.10606602,0.053033054 +0.2375,0.9625,0.094494075,0.094494045 +0.2375,0.9625,0.06681743,0.13363475 +0.23750001,0.9625,0.13363482,0.06681746 +0.2375,0.9625,0.11905506,0.11905497 +0.23750001,0.9625,0.08418466,0.1683693 +0.2375,0.9625,0.16836932,0.08418465 +0.23750001,0.98749995,0.075,0.07499999 +0.2375,0.98749995,0.053033024,0.10606593 +0.2375,0.98749995,0.10606602,0.053033054 +0.2375,0.98749995,0.094494075,0.094494045 +0.2375,0.98749995,0.06681743,0.13363475 +0.23750001,0.98749995,0.13363482,0.06681746 +0.2375,0.98749995,0.11905506,0.11905497 +0.23750001,0.98749995,0.08418466,0.16836923 +0.2375,0.98749995,0.16836932,0.08418459 +0.2625,0.0125,0.07500002,0.075 +0.2625,0.012499997,0.053033024,0.10606602 +0.2625,0.012499999,0.10606603,0.05303301 +0.2625,0.012499999,0.094494075,0.09449408 +0.2625,0.012500001,0.06681743,0.1336348 +0.2625,0.012499999,0.13363479,0.0668174 +0.2625,0.012500001,0.11905508,0.11905508 +0.2625,0.012499999,0.08418463,0.1683693 +0.2625,0.012500002,0.1683693,0.084184654 +0.2625,0.0375,0.07500002,0.075 +0.2625,0.037499998,0.053033024,0.10606601 +0.2625,0.0375,0.10606603,0.05303301 +0.2625,0.0375,0.094494075,0.094494075 +0.2625,0.0375,0.06681743,0.1336348 +0.2625,0.0375,0.13363479,0.0668174 +0.2625,0.0375,0.11905508,0.11905508 +0.2625,0.0375,0.08418463,0.16836931 +0.2625,0.0375,0.1683693,0.08418466 +0.2625,0.0625,0.07500002,0.075 +0.2625,0.0625,0.053033024,0.10606602 +0.2625,0.0625,0.10606603,0.05303301 +0.2625,0.0625,0.094494075,0.094494075 +0.2625,0.0625,0.06681743,0.1336348 +0.2625,0.0625,0.13363479,0.0668174 +0.2625,0.0625,0.11905508,0.11905508 +0.2625,0.0625,0.08418463,0.16836932 +0.2625,0.0625,0.1683693,0.08418465 +0.2625,0.0875,0.07500002,0.075 +0.2625,0.08749999,0.053033024,0.10606601 +0.2625,0.087500006,0.10606603,0.053033013 +0.2625,0.087500006,0.094494075,0.09449408 +0.2625,0.087500006,0.06681743,0.1336348 +0.2625,0.0875,0.13363479,0.0668174 +0.2625,0.0875,0.11905508,0.11905508 +0.2625,0.0875,0.08418463,0.16836931 +0.2625,0.087500006,0.1683693,0.084184654 +0.2625,0.112500004,0.07500002,0.075 +0.2625,0.1125,0.053033024,0.10606601 +0.2625,0.112500004,0.10606603,0.05303301 +0.2625,0.1125,0.094494075,0.094494075 +0.2625,0.1125,0.06681743,0.1336348 +0.2625,0.1125,0.13363479,0.0668174 +0.2625,0.1125,0.11905508,0.119055085 +0.2625,0.112500004,0.08418463,0.16836931 +0.2625,0.1125,0.1683693,0.08418465 +0.2625,0.1375,0.07500002,0.074999996 +0.2625,0.1375,0.053033024,0.10606602 +0.2625,0.1375,0.10606603,0.053033024 +0.2625,0.1375,0.094494075,0.09449408 +0.2625,0.1375,0.06681743,0.1336348 +0.2625,0.1375,0.13363479,0.0668174 +0.2625,0.13749999,0.11905508,0.11905508 +0.2625,0.1375,0.08418463,0.1683693 +0.2625,0.1375,0.1683693,0.084184654 +0.2625,0.1625,0.07500002,0.075 +0.2625,0.16250001,0.053033024,0.106066026 +0.2625,0.1625,0.10606603,0.05303301 +0.2625,0.1625,0.094494075,0.094494075 +0.2625,0.1625,0.06681743,0.1336348 +0.2625,0.1625,0.13363479,0.0668174 +0.2625,0.1625,0.11905508,0.11905508 +0.2625,0.1625,0.08418463,0.1683693 +0.2625,0.1625,0.1683693,0.08418464 +0.2625,0.1875,0.07500002,0.07499999 +0.2625,0.1875,0.053033024,0.10606603 +0.2625,0.1875,0.10606603,0.053033024 +0.2625,0.1875,0.094494075,0.09449406 +0.2625,0.1875,0.06681743,0.1336348 +0.2625,0.1875,0.13363479,0.06681742 +0.2625,0.1875,0.11905508,0.11905509 +0.2625,0.1875,0.08418463,0.16836931 +0.2625,0.1875,0.1683693,0.08418465 +0.2625,0.2125,0.07500002,0.075 +0.2625,0.2125,0.053033024,0.10606603 +0.2625,0.2125,0.10606603,0.05303301 +0.2625,0.21249999,0.094494075,0.094494075 +0.2625,0.2125,0.06681743,0.1336348 +0.2625,0.2125,0.13363479,0.0668174 +0.2625,0.2125,0.11905508,0.11905509 +0.2625,0.2125,0.08418463,0.16836931 +0.2625,0.2125,0.1683693,0.08418465 +0.2625,0.23750001,0.07500002,0.075 +0.2625,0.2375,0.053033024,0.10606602 +0.2625,0.2375,0.10606603,0.053033024 +0.2625,0.2375,0.094494075,0.094494075 +0.2625,0.23750001,0.06681743,0.13363482 +0.2625,0.2375,0.13363479,0.06681743 +0.2625,0.2375,0.11905508,0.11905506 +0.2625,0.2375,0.08418463,0.16836932 +0.2625,0.23750001,0.1683693,0.08418466 +0.2625,0.2625,0.07500002,0.07500002 +0.2625,0.2625,0.053033024,0.10606603 +0.2625,0.2625,0.10606603,0.053033024 +0.2625,0.2625,0.094494075,0.094494075 +0.2625,0.2625,0.06681743,0.13363479 +0.2625,0.2625,0.13363479,0.06681743 +0.2625,0.2625,0.11905508,0.11905508 +0.2625,0.2625,0.08418463,0.1683693 +0.2625,0.2625,0.1683693,0.08418463 +0.2625,0.2875,0.07500002,0.07499999 +0.2625,0.2875,0.053033024,0.10606603 +0.2625,0.28750002,0.10606603,0.053033024 +0.2625,0.2875,0.094494075,0.094494045 +0.2625,0.2875,0.06681743,0.1336348 +0.2625,0.28750002,0.13363479,0.06681743 +0.2625,0.2875,0.11905508,0.11905508 +0.2625,0.2875,0.08418463,0.1683693 +0.2625,0.2875,0.1683693,0.08418465 +0.2625,0.3125,0.07500002,0.07499999 +0.2625,0.3125,0.053033024,0.10606605 +0.2625,0.3125,0.10606603,0.053032994 +0.2625,0.3125,0.094494075,0.094494045 +0.2625,0.3125,0.06681743,0.1336348 +0.2625,0.3125,0.13363479,0.0668174 +0.2625,0.3125,0.11905508,0.11905509 +0.2625,0.3125,0.08418463,0.1683693 +0.2625,0.3125,0.1683693,0.08418465 +0.2625,0.3375,0.07500002,0.07499999 +0.2625,0.3375,0.053033024,0.10606605 +0.2625,0.33749998,0.10606603,0.053033024 +0.2625,0.3375,0.094494075,0.094494045 +0.2625,0.33750004,0.06681743,0.13363484 +0.2625,0.33749998,0.13363479,0.06681743 +0.2625,0.3375,0.11905508,0.11905509 +0.2625,0.3375,0.08418463,0.1683693 +0.2625,0.3375,0.1683693,0.08418465 +0.2625,0.3625,0.07500002,0.07500002 +0.2625,0.3625,0.053033024,0.10606602 +0.2625,0.3625,0.10606603,0.053033024 +0.2625,0.3625,0.094494075,0.094494075 +0.2625,0.3625,0.06681743,0.1336348 +0.2625,0.3625,0.13363479,0.06681743 +0.2625,0.3625,0.11905508,0.11905506 +0.2625,0.3625,0.08418463,0.1683693 +0.2625,0.3625,0.1683693,0.08418465 +0.2625,0.3875,0.07500002,0.07500002 +0.2625,0.3875,0.053033024,0.10606602 +0.2625,0.3875,0.10606603,0.053032994 +0.2625,0.3875,0.094494075,0.094494075 +0.2625,0.3875,0.06681743,0.13363484 +0.2625,0.3875,0.13363479,0.0668174 +0.2625,0.3875,0.11905508,0.11905506 +0.2625,0.3875,0.08418463,0.1683693 +0.2625,0.3875,0.1683693,0.08418465 +0.2625,0.4125,0.07500002,0.07499999 +0.2625,0.4125,0.053033024,0.10606605 +0.2625,0.4125,0.10606603,0.053032994 +0.2625,0.4125,0.094494075,0.094494045 +0.2625,0.41250002,0.06681743,0.13363484 +0.2625,0.4125,0.13363479,0.0668174 +0.2625,0.4125,0.11905508,0.11905509 +0.2625,0.4125,0.08418463,0.1683693 +0.2625,0.4125,0.1683693,0.08418465 +0.2625,0.4375,0.07500002,0.07499999 +0.2625,0.4375,0.053033024,0.10606605 +0.2625,0.4375,0.10606603,0.053032994 +0.2625,0.4375,0.094494075,0.094494045 +0.2625,0.4375,0.06681743,0.1336348 +0.2625,0.4375,0.13363479,0.0668174 +0.2625,0.4375,0.11905508,0.11905509 +0.2625,0.4375,0.08418463,0.1683693 +0.2625,0.4375,0.1683693,0.08418465 +0.2625,0.4625,0.07500002,0.07499999 +0.2625,0.4625,0.053033024,0.10606605 +0.2625,0.46249998,0.10606603,0.053032964 +0.2625,0.4625,0.094494075,0.094494045 +0.2625,0.46250004,0.06681743,0.13363484 +0.2625,0.46249998,0.13363479,0.06681737 +0.2625,0.4625,0.11905508,0.11905509 +0.2625,0.46249998,0.08418463,0.16836926 +0.2625,0.46249998,0.1683693,0.08418462 +0.2625,0.48749998,0.07500002,0.07499999 +0.2625,0.4875,0.053033024,0.10606602 +0.2625,0.4875,0.10606603,0.053032994 +0.2625,0.48749998,0.094494075,0.094494045 +0.2625,0.4875,0.06681743,0.13363484 +0.2625,0.4875,0.13363479,0.0668174 +0.2625,0.4875,0.11905508,0.11905506 +0.2625,0.4875,0.08418463,0.1683693 +0.2625,0.4875,0.1683693,0.08418465 +0.2625,0.5125,0.07500002,0.07500002 +0.2625,0.51250005,0.053033024,0.10606605 +0.2625,0.5125,0.10606603,0.053032964 +0.2625,0.5125,0.094494075,0.094494075 +0.2625,0.51250005,0.06681743,0.13363487 +0.2625,0.5125,0.13363479,0.06681737 +0.2625,0.51250005,0.11905508,0.11905509 +0.2625,0.5125,0.08418463,0.1683693 +0.2625,0.5125,0.1683693,0.08418465 +0.2625,0.5375,0.07500002,0.07499999 +0.2625,0.5375,0.053033024,0.10606605 +0.2625,0.5375,0.10606603,0.053032935 +0.2625,0.5375,0.094494075,0.094494045 +0.2625,0.5375,0.06681743,0.13363487 +0.2625,0.5375,0.13363479,0.06681734 +0.2625,0.5375,0.11905508,0.11905509 +0.2625,0.5375,0.08418463,0.16836932 +0.2625,0.5375,0.1683693,0.08418468 +0.2625,0.5625,0.07500002,0.07500005 +0.2625,0.5625,0.053033024,0.10606599 +0.2625,0.5625,0.10606603,0.053032994 +0.2625,0.5625,0.094494075,0.094494104 +0.2625,0.5625,0.06681743,0.13363484 +0.2625,0.5625,0.13363479,0.0668174 +0.2625,0.5625,0.11905508,0.11905503 +0.2625,0.5625,0.08418463,0.1683693 +0.2625,0.5625,0.1683693,0.08418465 +0.2625,0.5875,0.07500002,0.07499999 +0.2625,0.5875,0.053033024,0.10606605 +0.2625,0.5875,0.10606603,0.053032935 +0.2625,0.5875,0.094494075,0.094494045 +0.2625,0.5875,0.06681743,0.13363487 +0.2625,0.5875,0.13363479,0.06681734 +0.2625,0.5875,0.11905508,0.11905509 +0.2625,0.5875,0.08418463,0.1683693 +0.2625,0.5875,0.1683693,0.08418465 +0.2625,0.61249995,0.07500002,0.07499999 +0.2625,0.61249995,0.053033024,0.10606605 +0.2625,0.6125,0.10606603,0.053032994 +0.2625,0.61249995,0.094494075,0.094494045 +0.2625,0.61249995,0.06681743,0.13363487 +0.2625,0.6125,0.13363479,0.0668174 +0.2625,0.61249995,0.11905508,0.11905509 +0.2625,0.6125,0.08418463,0.1683693 +0.2625,0.6125,0.1683693,0.08418465 +0.2625,0.63750005,0.07500002,0.07499999 +0.2625,0.63750005,0.053033024,0.10606605 +0.2625,0.6375,0.10606603,0.053032994 +0.2625,0.63750005,0.094494075,0.094494045 +0.2625,0.63750005,0.06681743,0.13363487 +0.2625,0.6375,0.13363479,0.0668174 +0.2625,0.63750005,0.11905508,0.11905509 +0.2625,0.6375,0.08418463,0.1683693 +0.2625,0.6375,0.1683693,0.08418465 +0.2625,0.6625,0.07500002,0.07499999 +0.2625,0.6625,0.053033024,0.10606605 +0.2625,0.6625,0.10606603,0.053032935 +0.2625,0.6625,0.094494075,0.094494045 +0.2625,0.6625,0.06681743,0.13363487 +0.2625,0.6625,0.13363479,0.06681734 +0.2625,0.6625,0.11905508,0.11905509 +0.2625,0.6625,0.08418463,0.1683693 +0.2625,0.6625,0.1683693,0.08418465 +0.2625,0.6875,0.07500002,0.07500005 +0.2625,0.6875,0.053033024,0.10606599 +0.2625,0.6875,0.10606603,0.053032994 +0.2625,0.6875,0.094494075,0.094494104 +0.2625,0.6875,0.06681743,0.1336348 +0.2625,0.6875,0.13363479,0.0668174 +0.2625,0.6875,0.11905508,0.11905503 +0.2625,0.6875,0.08418463,0.1683693 +0.2625,0.6875,0.1683693,0.08418465 +0.2625,0.7125,0.07500002,0.07499999 +0.2625,0.7125,0.053033024,0.10606605 +0.2625,0.7125,0.10606603,0.053032935 +0.2625,0.7125,0.094494075,0.094494045 +0.2625,0.7125,0.06681743,0.13363487 +0.2625,0.7125,0.13363479,0.06681734 +0.2625,0.7125,0.11905508,0.11905509 +0.2625,0.7125,0.08418463,0.1683693 +0.2625,0.7125,0.1683693,0.08418465 +0.2625,0.73749995,0.07500002,0.07499999 +0.2625,0.73749995,0.053033024,0.10606605 +0.2625,0.7375,0.10606603,0.053032994 +0.2625,0.73749995,0.094494075,0.094494045 +0.2625,0.73749995,0.06681743,0.1336348 +0.2625,0.7375,0.13363479,0.0668174 +0.2625,0.73749995,0.11905508,0.11905509 +0.2625,0.7375,0.08418463,0.1683693 +0.2625,0.7375,0.1683693,0.08418465 +0.2625,0.76250005,0.07500002,0.07499999 +0.2625,0.7625,0.053033024,0.10606599 +0.2625,0.7625,0.10606603,0.053032994 +0.2625,0.76250005,0.094494075,0.094494045 +0.2625,0.7625,0.06681743,0.1336348 +0.2625,0.7625,0.13363479,0.0668174 +0.2625,0.7625,0.11905508,0.11905503 +0.2625,0.7625,0.08418463,0.1683693 +0.2625,0.7625,0.1683693,0.08418465 +0.2625,0.7875,0.07500002,0.07499999 +0.2625,0.78749996,0.053033024,0.10606599 +0.2625,0.7875,0.10606603,0.053032994 +0.2625,0.7875,0.094494075,0.094494045 +0.2625,0.78749996,0.06681743,0.1336348 +0.2625,0.7875,0.13363479,0.0668174 +0.2625,0.78749996,0.11905508,0.11905503 +0.2625,0.7875,0.08418463,0.1683693 +0.2625,0.7875,0.1683693,0.08418465 +0.2625,0.8125,0.07500002,0.07500005 +0.2625,0.8125,0.053033024,0.10606599 +0.2625,0.8125,0.10606603,0.053033054 +0.2625,0.8125,0.094494075,0.094494104 +0.2625,0.8125,0.06681743,0.1336348 +0.2625,0.8125,0.13363479,0.06681746 +0.2625,0.8125,0.11905508,0.11905503 +0.2625,0.8125,0.08418463,0.1683693 +0.2625,0.8125,0.1683693,0.08418465 +0.2625,0.8375,0.07500002,0.07499999 +0.2625,0.8375,0.053033024,0.10606599 +0.2625,0.8375,0.10606603,0.053033054 +0.2625,0.8375,0.094494075,0.094494045 +0.2625,0.8375,0.06681743,0.1336348 +0.2625,0.8375,0.13363479,0.06681746 +0.2625,0.8375,0.11905508,0.11905503 +0.2625,0.8375,0.08418463,0.1683693 +0.2625,0.8375,0.1683693,0.08418465 +0.2625,0.86249995,0.07500002,0.07499999 +0.2625,0.86249995,0.053033024,0.10606593 +0.2625,0.86249995,0.10606603,0.053033054 +0.2625,0.86249995,0.094494075,0.094494045 +0.2625,0.86249995,0.06681743,0.1336348 +0.2625,0.86249995,0.13363479,0.06681746 +0.2625,0.86249995,0.11905508,0.11905497 +0.2625,0.8625,0.08418463,0.1683693 +0.2625,0.8625,0.1683693,0.08418465 +0.2625,0.88750005,0.07500002,0.07499999 +0.2625,0.88750005,0.053033024,0.10606593 +0.2625,0.88750005,0.10606603,0.053033054 +0.2625,0.88750005,0.094494075,0.094494045 +0.2625,0.88750005,0.06681743,0.13363475 +0.2625,0.88750005,0.13363479,0.06681746 +0.2625,0.88750005,0.11905508,0.11905497 +0.2625,0.8875,0.08418463,0.1683693 +0.2625,0.8875,0.1683693,0.08418465 +0.2625,0.9125,0.07500002,0.07499999 +0.2625,0.9125,0.053033024,0.10606593 +0.2625,0.9125,0.10606603,0.053033054 +0.2625,0.9125,0.094494075,0.094494045 +0.2625,0.9125,0.06681743,0.13363475 +0.2625,0.9125,0.13363479,0.06681746 +0.2625,0.9125,0.11905508,0.11905497 +0.2625,0.9125,0.08418463,0.1683693 +0.2625,0.9125,0.1683693,0.08418465 +0.2625,0.9375,0.07500002,0.07500005 +0.2625,0.9375,0.053033024,0.10606599 +0.2625,0.9375,0.10606603,0.053033113 +0.2625,0.9375,0.094494075,0.094494104 +0.2625,0.9375,0.06681743,0.1336348 +0.2625,0.9375,0.13363479,0.06681752 +0.2625,0.9375,0.11905508,0.11905503 +0.2625,0.9375,0.08418463,0.1683693 +0.2625,0.9375,0.1683693,0.08418465 +0.2625,0.9625,0.07500002,0.07499999 +0.2625,0.9625,0.053033024,0.10606593 +0.2625,0.9625,0.10606603,0.053033054 +0.2625,0.9625,0.094494075,0.094494045 +0.2625,0.9625,0.06681743,0.13363475 +0.2625,0.9625,0.13363479,0.06681746 +0.2625,0.9625,0.11905508,0.11905497 +0.2625,0.9625,0.08418463,0.1683693 +0.2625,0.9625,0.1683693,0.08418465 +0.2625,0.98749995,0.07500002,0.07499999 +0.2625,0.98749995,0.053033024,0.10606593 +0.2625,0.98749995,0.10606603,0.053033054 +0.2625,0.98749995,0.094494075,0.094494045 +0.2625,0.98749995,0.06681743,0.13363475 +0.2625,0.98749995,0.13363479,0.06681746 +0.2625,0.98749995,0.11905508,0.11905497 +0.2625,0.98749995,0.08418463,0.16836923 +0.2625,0.98749995,0.1683693,0.08418459 +0.2875,0.0125,0.07499999,0.075 +0.28750002,0.012499997,0.053033024,0.10606602 +0.2875,0.012499999,0.10606603,0.05303301 +0.2875,0.012499999,0.094494045,0.09449408 +0.28750002,0.012500001,0.06681743,0.1336348 +0.2875,0.012499999,0.1336348,0.0668174 +0.2875,0.012500001,0.11905508,0.11905508 +0.2875,0.012499999,0.08418465,0.1683693 +0.2875,0.012500002,0.1683693,0.084184654 +0.2875,0.0375,0.07499999,0.075 +0.28750002,0.037499998,0.053033024,0.10606601 +0.2875,0.0375,0.10606603,0.05303301 +0.2875,0.0375,0.094494045,0.094494075 +0.28750002,0.0375,0.06681743,0.1336348 +0.2875,0.0375,0.1336348,0.0668174 +0.2875,0.0375,0.11905508,0.11905508 +0.2875,0.0375,0.08418465,0.16836931 +0.2875,0.0375,0.1683693,0.08418466 +0.2875,0.0625,0.07499999,0.075 +0.28750002,0.0625,0.053033024,0.10606602 +0.2875,0.0625,0.10606603,0.05303301 +0.2875,0.0625,0.094494045,0.094494075 +0.28750002,0.0625,0.06681743,0.1336348 +0.2875,0.0625,0.1336348,0.0668174 +0.2875,0.0625,0.11905508,0.11905508 +0.2875,0.0625,0.08418465,0.16836932 +0.2875,0.0625,0.1683693,0.08418465 +0.2875,0.0875,0.07499999,0.075 +0.28750002,0.08749999,0.053033024,0.10606601 +0.2875,0.087500006,0.10606603,0.053033013 +0.2875,0.087500006,0.094494045,0.09449408 +0.28750002,0.087500006,0.06681743,0.1336348 +0.2875,0.0875,0.1336348,0.0668174 +0.2875,0.0875,0.11905508,0.11905508 +0.2875,0.0875,0.08418465,0.16836931 +0.2875,0.087500006,0.1683693,0.084184654 +0.2875,0.112500004,0.07499999,0.075 +0.28750002,0.1125,0.053033024,0.10606601 +0.2875,0.112500004,0.10606603,0.05303301 +0.2875,0.1125,0.094494045,0.094494075 +0.28750002,0.1125,0.06681743,0.1336348 +0.2875,0.1125,0.1336348,0.0668174 +0.2875,0.1125,0.11905508,0.119055085 +0.2875,0.112500004,0.08418465,0.16836931 +0.2875,0.1125,0.1683693,0.08418465 +0.2875,0.1375,0.07499999,0.074999996 +0.28750002,0.1375,0.053033024,0.10606602 +0.2875,0.1375,0.10606603,0.053033024 +0.2875,0.1375,0.094494045,0.09449408 +0.28750002,0.1375,0.06681743,0.1336348 +0.2875,0.1375,0.1336348,0.0668174 +0.2875,0.13749999,0.11905508,0.11905508 +0.2875,0.1375,0.08418465,0.1683693 +0.2875,0.1375,0.1683693,0.084184654 +0.2875,0.1625,0.07499999,0.075 +0.28750002,0.16250001,0.053033024,0.106066026 +0.2875,0.1625,0.10606603,0.05303301 +0.2875,0.1625,0.094494045,0.094494075 +0.28750002,0.1625,0.06681743,0.1336348 +0.2875,0.1625,0.1336348,0.0668174 +0.2875,0.1625,0.11905508,0.11905508 +0.2875,0.1625,0.08418465,0.1683693 +0.2875,0.1625,0.1683693,0.08418464 +0.2875,0.1875,0.07499999,0.07499999 +0.28750002,0.1875,0.053033024,0.10606603 +0.2875,0.1875,0.10606603,0.053033024 +0.2875,0.1875,0.094494045,0.09449406 +0.28750002,0.1875,0.06681743,0.1336348 +0.2875,0.1875,0.1336348,0.06681742 +0.2875,0.1875,0.11905508,0.11905509 +0.2875,0.1875,0.08418465,0.16836931 +0.2875,0.1875,0.1683693,0.08418465 +0.2875,0.2125,0.07499999,0.075 +0.28750002,0.2125,0.053033024,0.10606603 +0.2875,0.2125,0.10606603,0.05303301 +0.2875,0.21249999,0.094494045,0.094494075 +0.28750002,0.2125,0.06681743,0.1336348 +0.2875,0.2125,0.1336348,0.0668174 +0.2875,0.2125,0.11905508,0.11905509 +0.2875,0.2125,0.08418465,0.16836931 +0.2875,0.2125,0.1683693,0.08418465 +0.2875,0.23750001,0.07499999,0.075 +0.28750002,0.2375,0.053033024,0.10606602 +0.2875,0.2375,0.10606603,0.053033024 +0.2875,0.2375,0.094494045,0.094494075 +0.28750002,0.23750001,0.06681743,0.13363482 +0.2875,0.2375,0.1336348,0.06681743 +0.2875,0.2375,0.11905508,0.11905506 +0.2875,0.2375,0.08418465,0.16836932 +0.2875,0.23750001,0.1683693,0.08418466 +0.2875,0.2625,0.07499999,0.07500002 +0.28750002,0.2625,0.053033024,0.10606603 +0.2875,0.2625,0.10606603,0.053033024 +0.2875,0.2625,0.094494045,0.094494075 +0.28750002,0.2625,0.06681743,0.13363479 +0.2875,0.2625,0.1336348,0.06681743 +0.2875,0.2625,0.11905508,0.11905508 +0.2875,0.2625,0.08418465,0.1683693 +0.2875,0.2625,0.1683693,0.08418463 +0.2875,0.2875,0.07499999,0.07499999 +0.28750002,0.2875,0.053033024,0.10606603 +0.2875,0.28750002,0.10606603,0.053033024 +0.2875,0.2875,0.094494045,0.094494045 +0.28750002,0.2875,0.06681743,0.1336348 +0.2875,0.28750002,0.1336348,0.06681743 +0.2875,0.2875,0.11905508,0.11905508 +0.2875,0.2875,0.08418465,0.1683693 +0.2875,0.2875,0.1683693,0.08418465 +0.2875,0.3125,0.07499999,0.07499999 +0.28750002,0.3125,0.053033024,0.10606605 +0.2875,0.3125,0.10606603,0.053032994 +0.2875,0.3125,0.094494045,0.094494045 +0.28750002,0.3125,0.06681743,0.1336348 +0.2875,0.3125,0.1336348,0.0668174 +0.2875,0.3125,0.11905508,0.11905509 +0.2875,0.3125,0.08418465,0.1683693 +0.2875,0.3125,0.1683693,0.08418465 +0.2875,0.3375,0.07499999,0.07499999 +0.28750002,0.3375,0.053033024,0.10606605 +0.2875,0.33749998,0.10606603,0.053033024 +0.2875,0.3375,0.094494045,0.094494045 +0.28750002,0.33750004,0.06681743,0.13363484 +0.2875,0.33749998,0.1336348,0.06681743 +0.2875,0.3375,0.11905508,0.11905509 +0.2875,0.3375,0.08418465,0.1683693 +0.2875,0.3375,0.1683693,0.08418465 +0.2875,0.3625,0.07499999,0.07500002 +0.28750002,0.3625,0.053033024,0.10606602 +0.2875,0.3625,0.10606603,0.053033024 +0.2875,0.3625,0.094494045,0.094494075 +0.28750002,0.3625,0.06681743,0.1336348 +0.2875,0.3625,0.1336348,0.06681743 +0.2875,0.3625,0.11905508,0.11905506 +0.2875,0.3625,0.08418465,0.1683693 +0.2875,0.3625,0.1683693,0.08418465 +0.2875,0.3875,0.07499999,0.07500002 +0.28750002,0.3875,0.053033024,0.10606602 +0.2875,0.3875,0.10606603,0.053032994 +0.2875,0.3875,0.094494045,0.094494075 +0.28750002,0.3875,0.06681743,0.13363484 +0.2875,0.3875,0.1336348,0.0668174 +0.2875,0.3875,0.11905508,0.11905506 +0.2875,0.3875,0.08418465,0.1683693 +0.2875,0.3875,0.1683693,0.08418465 +0.2875,0.4125,0.07499999,0.07499999 +0.28750002,0.4125,0.053033024,0.10606605 +0.2875,0.4125,0.10606603,0.053032994 +0.2875,0.4125,0.094494045,0.094494045 +0.28750002,0.41250002,0.06681743,0.13363484 +0.2875,0.4125,0.1336348,0.0668174 +0.2875,0.4125,0.11905508,0.11905509 +0.2875,0.4125,0.08418465,0.1683693 +0.2875,0.4125,0.1683693,0.08418465 +0.2875,0.4375,0.07499999,0.07499999 +0.28750002,0.4375,0.053033024,0.10606605 +0.2875,0.4375,0.10606603,0.053032994 +0.2875,0.4375,0.094494045,0.094494045 +0.28750002,0.4375,0.06681743,0.1336348 +0.2875,0.4375,0.1336348,0.0668174 +0.2875,0.4375,0.11905508,0.11905509 +0.2875,0.4375,0.08418465,0.1683693 +0.2875,0.4375,0.1683693,0.08418465 +0.2875,0.4625,0.07499999,0.07499999 +0.28750002,0.4625,0.053033024,0.10606605 +0.2875,0.46249998,0.10606603,0.053032964 +0.2875,0.4625,0.094494045,0.094494045 +0.28750002,0.46250004,0.06681743,0.13363484 +0.2875,0.46249998,0.1336348,0.06681737 +0.2875,0.4625,0.11905508,0.11905509 +0.2875,0.46249998,0.08418465,0.16836926 +0.2875,0.46249998,0.1683693,0.08418462 +0.2875,0.48749998,0.07499999,0.07499999 +0.28750002,0.4875,0.053033024,0.10606602 +0.2875,0.4875,0.10606603,0.053032994 +0.2875,0.48749998,0.094494045,0.094494045 +0.28750002,0.4875,0.06681743,0.13363484 +0.2875,0.4875,0.1336348,0.0668174 +0.2875,0.4875,0.11905508,0.11905506 +0.2875,0.4875,0.08418465,0.1683693 +0.2875,0.4875,0.1683693,0.08418465 +0.2875,0.5125,0.07499999,0.07500002 +0.28750002,0.51250005,0.053033024,0.10606605 +0.2875,0.5125,0.10606603,0.053032964 +0.2875,0.5125,0.094494045,0.094494075 +0.28750002,0.51250005,0.06681743,0.13363487 +0.2875,0.5125,0.1336348,0.06681737 +0.2875,0.51250005,0.11905508,0.11905509 +0.2875,0.5125,0.08418465,0.1683693 +0.2875,0.5125,0.1683693,0.08418465 +0.2875,0.5375,0.07499999,0.07499999 +0.28750002,0.5375,0.053033024,0.10606605 +0.2875,0.5375,0.10606603,0.053032935 +0.2875,0.5375,0.094494045,0.094494045 +0.28750002,0.5375,0.06681743,0.13363487 +0.2875,0.5375,0.1336348,0.06681734 +0.2875,0.5375,0.11905508,0.11905509 +0.2875,0.5375,0.08418465,0.16836932 +0.2875,0.5375,0.1683693,0.08418468 +0.2875,0.5625,0.07499999,0.07500005 +0.28750002,0.5625,0.053033024,0.10606599 +0.2875,0.5625,0.10606603,0.053032994 +0.2875,0.5625,0.094494045,0.094494104 +0.28750002,0.5625,0.06681743,0.13363484 +0.2875,0.5625,0.1336348,0.0668174 +0.2875,0.5625,0.11905508,0.11905503 +0.2875,0.5625,0.08418465,0.1683693 +0.2875,0.5625,0.1683693,0.08418465 +0.2875,0.5875,0.07499999,0.07499999 +0.28750002,0.5875,0.053033024,0.10606605 +0.2875,0.5875,0.10606603,0.053032935 +0.2875,0.5875,0.094494045,0.094494045 +0.28750002,0.5875,0.06681743,0.13363487 +0.2875,0.5875,0.1336348,0.06681734 +0.2875,0.5875,0.11905508,0.11905509 +0.2875,0.5875,0.08418465,0.1683693 +0.2875,0.5875,0.1683693,0.08418465 +0.2875,0.61249995,0.07499999,0.07499999 +0.28750002,0.61249995,0.053033024,0.10606605 +0.2875,0.6125,0.10606603,0.053032994 +0.2875,0.61249995,0.094494045,0.094494045 +0.28750002,0.61249995,0.06681743,0.13363487 +0.2875,0.6125,0.1336348,0.0668174 +0.2875,0.61249995,0.11905508,0.11905509 +0.2875,0.6125,0.08418465,0.1683693 +0.2875,0.6125,0.1683693,0.08418465 +0.2875,0.63750005,0.07499999,0.07499999 +0.28750002,0.63750005,0.053033024,0.10606605 +0.2875,0.6375,0.10606603,0.053032994 +0.2875,0.63750005,0.094494045,0.094494045 +0.28750002,0.63750005,0.06681743,0.13363487 +0.2875,0.6375,0.1336348,0.0668174 +0.2875,0.63750005,0.11905508,0.11905509 +0.2875,0.6375,0.08418465,0.1683693 +0.2875,0.6375,0.1683693,0.08418465 +0.2875,0.6625,0.07499999,0.07499999 +0.28750002,0.6625,0.053033024,0.10606605 +0.2875,0.6625,0.10606603,0.053032935 +0.2875,0.6625,0.094494045,0.094494045 +0.28750002,0.6625,0.06681743,0.13363487 +0.2875,0.6625,0.1336348,0.06681734 +0.2875,0.6625,0.11905508,0.11905509 +0.2875,0.6625,0.08418465,0.1683693 +0.2875,0.6625,0.1683693,0.08418465 +0.2875,0.6875,0.07499999,0.07500005 +0.28750002,0.6875,0.053033024,0.10606599 +0.2875,0.6875,0.10606603,0.053032994 +0.2875,0.6875,0.094494045,0.094494104 +0.28750002,0.6875,0.06681743,0.1336348 +0.2875,0.6875,0.1336348,0.0668174 +0.2875,0.6875,0.11905508,0.11905503 +0.2875,0.6875,0.08418465,0.1683693 +0.2875,0.6875,0.1683693,0.08418465 +0.2875,0.7125,0.07499999,0.07499999 +0.28750002,0.7125,0.053033024,0.10606605 +0.2875,0.7125,0.10606603,0.053032935 +0.2875,0.7125,0.094494045,0.094494045 +0.28750002,0.7125,0.06681743,0.13363487 +0.2875,0.7125,0.1336348,0.06681734 +0.2875,0.7125,0.11905508,0.11905509 +0.2875,0.7125,0.08418465,0.1683693 +0.2875,0.7125,0.1683693,0.08418465 +0.2875,0.73749995,0.07499999,0.07499999 +0.28750002,0.73749995,0.053033024,0.10606605 +0.2875,0.7375,0.10606603,0.053032994 +0.2875,0.73749995,0.094494045,0.094494045 +0.28750002,0.73749995,0.06681743,0.1336348 +0.2875,0.7375,0.1336348,0.0668174 +0.2875,0.73749995,0.11905508,0.11905509 +0.2875,0.7375,0.08418465,0.1683693 +0.2875,0.7375,0.1683693,0.08418465 +0.2875,0.76250005,0.07499999,0.07499999 +0.28750002,0.7625,0.053033024,0.10606599 +0.2875,0.7625,0.10606603,0.053032994 +0.2875,0.76250005,0.094494045,0.094494045 +0.28750002,0.7625,0.06681743,0.1336348 +0.2875,0.7625,0.1336348,0.0668174 +0.2875,0.7625,0.11905508,0.11905503 +0.2875,0.7625,0.08418465,0.1683693 +0.2875,0.7625,0.1683693,0.08418465 +0.2875,0.7875,0.07499999,0.07499999 +0.28750002,0.78749996,0.053033024,0.10606599 +0.2875,0.7875,0.10606603,0.053032994 +0.2875,0.7875,0.094494045,0.094494045 +0.28750002,0.78749996,0.06681743,0.1336348 +0.2875,0.7875,0.1336348,0.0668174 +0.2875,0.78749996,0.11905508,0.11905503 +0.2875,0.7875,0.08418465,0.1683693 +0.2875,0.7875,0.1683693,0.08418465 +0.2875,0.8125,0.07499999,0.07500005 +0.28750002,0.8125,0.053033024,0.10606599 +0.2875,0.8125,0.10606603,0.053033054 +0.2875,0.8125,0.094494045,0.094494104 +0.28750002,0.8125,0.06681743,0.1336348 +0.2875,0.8125,0.1336348,0.06681746 +0.2875,0.8125,0.11905508,0.11905503 +0.2875,0.8125,0.08418465,0.1683693 +0.2875,0.8125,0.1683693,0.08418465 +0.2875,0.8375,0.07499999,0.07499999 +0.28750002,0.8375,0.053033024,0.10606599 +0.2875,0.8375,0.10606603,0.053033054 +0.2875,0.8375,0.094494045,0.094494045 +0.28750002,0.8375,0.06681743,0.1336348 +0.2875,0.8375,0.1336348,0.06681746 +0.2875,0.8375,0.11905508,0.11905503 +0.2875,0.8375,0.08418465,0.1683693 +0.2875,0.8375,0.1683693,0.08418465 +0.2875,0.86249995,0.07499999,0.07499999 +0.28750002,0.86249995,0.053033024,0.10606593 +0.2875,0.86249995,0.10606603,0.053033054 +0.2875,0.86249995,0.094494045,0.094494045 +0.28750002,0.86249995,0.06681743,0.1336348 +0.2875,0.86249995,0.1336348,0.06681746 +0.2875,0.86249995,0.11905508,0.11905497 +0.2875,0.8625,0.08418465,0.1683693 +0.2875,0.8625,0.1683693,0.08418465 +0.2875,0.88750005,0.07499999,0.07499999 +0.28750002,0.88750005,0.053033024,0.10606593 +0.2875,0.88750005,0.10606603,0.053033054 +0.2875,0.88750005,0.094494045,0.094494045 +0.28750002,0.88750005,0.06681743,0.13363475 +0.2875,0.88750005,0.1336348,0.06681746 +0.2875,0.88750005,0.11905508,0.11905497 +0.2875,0.8875,0.08418465,0.1683693 +0.2875,0.8875,0.1683693,0.08418465 +0.2875,0.9125,0.07499999,0.07499999 +0.28750002,0.9125,0.053033024,0.10606593 +0.2875,0.9125,0.10606603,0.053033054 +0.2875,0.9125,0.094494045,0.094494045 +0.28750002,0.9125,0.06681743,0.13363475 +0.2875,0.9125,0.1336348,0.06681746 +0.2875,0.9125,0.11905508,0.11905497 +0.2875,0.9125,0.08418465,0.1683693 +0.2875,0.9125,0.1683693,0.08418465 +0.2875,0.9375,0.07499999,0.07500005 +0.28750002,0.9375,0.053033024,0.10606599 +0.2875,0.9375,0.10606603,0.053033113 +0.2875,0.9375,0.094494045,0.094494104 +0.28750002,0.9375,0.06681743,0.1336348 +0.2875,0.9375,0.1336348,0.06681752 +0.2875,0.9375,0.11905508,0.11905503 +0.2875,0.9375,0.08418465,0.1683693 +0.2875,0.9375,0.1683693,0.08418465 +0.2875,0.9625,0.07499999,0.07499999 +0.28750002,0.9625,0.053033024,0.10606593 +0.2875,0.9625,0.10606603,0.053033054 +0.2875,0.9625,0.094494045,0.094494045 +0.28750002,0.9625,0.06681743,0.13363475 +0.2875,0.9625,0.1336348,0.06681746 +0.2875,0.9625,0.11905508,0.11905497 +0.2875,0.9625,0.08418465,0.1683693 +0.2875,0.9625,0.1683693,0.08418465 +0.2875,0.98749995,0.07499999,0.07499999 +0.28750002,0.98749995,0.053033024,0.10606593 +0.2875,0.98749995,0.10606603,0.053033054 +0.2875,0.98749995,0.094494045,0.094494045 +0.28750002,0.98749995,0.06681743,0.13363475 +0.2875,0.98749995,0.1336348,0.06681746 +0.2875,0.98749995,0.11905508,0.11905497 +0.2875,0.98749995,0.08418465,0.16836923 +0.2875,0.98749995,0.1683693,0.08418459 +0.3125,0.0125,0.07499999,0.075 +0.3125,0.012499997,0.053032994,0.10606602 +0.3125,0.012499999,0.10606605,0.05303301 +0.3125,0.012499999,0.094494045,0.09449408 +0.3125,0.012500001,0.0668174,0.1336348 +0.3125,0.012499999,0.1336348,0.0668174 +0.3125,0.012500001,0.11905509,0.11905508 +0.3125,0.012499999,0.08418465,0.1683693 +0.3125,0.012500002,0.1683693,0.084184654 +0.3125,0.0375,0.07499999,0.075 +0.3125,0.037499998,0.053032994,0.10606601 +0.3125,0.0375,0.10606605,0.05303301 +0.3125,0.0375,0.094494045,0.094494075 +0.3125,0.0375,0.0668174,0.1336348 +0.3125,0.0375,0.1336348,0.0668174 +0.3125,0.0375,0.11905509,0.11905508 +0.3125,0.0375,0.08418465,0.16836931 +0.3125,0.0375,0.1683693,0.08418466 +0.3125,0.0625,0.07499999,0.075 +0.3125,0.0625,0.053032994,0.10606602 +0.3125,0.0625,0.10606605,0.05303301 +0.3125,0.0625,0.094494045,0.094494075 +0.3125,0.0625,0.0668174,0.1336348 +0.3125,0.0625,0.1336348,0.0668174 +0.3125,0.0625,0.11905509,0.11905508 +0.3125,0.0625,0.08418465,0.16836932 +0.3125,0.0625,0.1683693,0.08418465 +0.3125,0.0875,0.07499999,0.075 +0.3125,0.08749999,0.053032994,0.10606601 +0.3125,0.087500006,0.10606605,0.053033013 +0.3125,0.087500006,0.094494045,0.09449408 +0.3125,0.087500006,0.0668174,0.1336348 +0.3125,0.0875,0.1336348,0.0668174 +0.3125,0.0875,0.11905509,0.11905508 +0.3125,0.0875,0.08418465,0.16836931 +0.3125,0.087500006,0.1683693,0.084184654 +0.3125,0.112500004,0.07499999,0.075 +0.3125,0.1125,0.053032994,0.10606601 +0.3125,0.112500004,0.10606605,0.05303301 +0.3125,0.1125,0.094494045,0.094494075 +0.3125,0.1125,0.0668174,0.1336348 +0.3125,0.1125,0.1336348,0.0668174 +0.3125,0.1125,0.11905509,0.119055085 +0.3125,0.112500004,0.08418465,0.16836931 +0.3125,0.1125,0.1683693,0.08418465 +0.3125,0.1375,0.07499999,0.074999996 +0.3125,0.1375,0.053032994,0.10606602 +0.3125,0.1375,0.10606605,0.053033024 +0.3125,0.1375,0.094494045,0.09449408 +0.3125,0.1375,0.0668174,0.1336348 +0.3125,0.1375,0.1336348,0.0668174 +0.3125,0.13749999,0.11905509,0.11905508 +0.3125,0.1375,0.08418465,0.1683693 +0.3125,0.1375,0.1683693,0.084184654 +0.3125,0.1625,0.07499999,0.075 +0.3125,0.16250001,0.053032994,0.106066026 +0.3125,0.1625,0.10606605,0.05303301 +0.3125,0.1625,0.094494045,0.094494075 +0.3125,0.1625,0.0668174,0.1336348 +0.3125,0.1625,0.1336348,0.0668174 +0.3125,0.1625,0.11905509,0.11905508 +0.3125,0.1625,0.08418465,0.1683693 +0.3125,0.1625,0.1683693,0.08418464 +0.3125,0.1875,0.07499999,0.07499999 +0.3125,0.1875,0.053032994,0.10606603 +0.3125,0.1875,0.10606605,0.053033024 +0.3125,0.1875,0.094494045,0.09449406 +0.3125,0.1875,0.0668174,0.1336348 +0.3125,0.1875,0.1336348,0.06681742 +0.3125,0.1875,0.11905509,0.11905509 +0.3125,0.1875,0.08418465,0.16836931 +0.3125,0.1875,0.1683693,0.08418465 +0.3125,0.2125,0.07499999,0.075 +0.3125,0.2125,0.053032994,0.10606603 +0.3125,0.2125,0.10606605,0.05303301 +0.3125,0.21249999,0.094494045,0.094494075 +0.3125,0.2125,0.0668174,0.1336348 +0.3125,0.2125,0.1336348,0.0668174 +0.3125,0.2125,0.11905509,0.11905509 +0.3125,0.2125,0.08418465,0.16836931 +0.3125,0.2125,0.1683693,0.08418465 +0.3125,0.23750001,0.07499999,0.075 +0.3125,0.2375,0.053032994,0.10606602 +0.3125,0.2375,0.10606605,0.053033024 +0.3125,0.2375,0.094494045,0.094494075 +0.3125,0.23750001,0.0668174,0.13363482 +0.3125,0.2375,0.1336348,0.06681743 +0.3125,0.2375,0.11905509,0.11905506 +0.3125,0.2375,0.08418465,0.16836932 +0.3125,0.23750001,0.1683693,0.08418466 +0.3125,0.2625,0.07499999,0.07500002 +0.3125,0.2625,0.053032994,0.10606603 +0.3125,0.2625,0.10606605,0.053033024 +0.3125,0.2625,0.094494045,0.094494075 +0.3125,0.2625,0.0668174,0.13363479 +0.3125,0.2625,0.1336348,0.06681743 +0.3125,0.2625,0.11905509,0.11905508 +0.3125,0.2625,0.08418465,0.1683693 +0.3125,0.2625,0.1683693,0.08418463 +0.3125,0.2875,0.07499999,0.07499999 +0.3125,0.2875,0.053032994,0.10606603 +0.3125,0.28750002,0.10606605,0.053033024 +0.3125,0.2875,0.094494045,0.094494045 +0.3125,0.2875,0.0668174,0.1336348 +0.3125,0.28750002,0.1336348,0.06681743 +0.3125,0.2875,0.11905509,0.11905508 +0.3125,0.2875,0.08418465,0.1683693 +0.3125,0.2875,0.1683693,0.08418465 +0.3125,0.3125,0.07499999,0.07499999 +0.3125,0.3125,0.053032994,0.10606605 +0.3125,0.3125,0.10606605,0.053032994 +0.3125,0.3125,0.094494045,0.094494045 +0.3125,0.3125,0.0668174,0.1336348 +0.3125,0.3125,0.1336348,0.0668174 +0.3125,0.3125,0.11905509,0.11905509 +0.3125,0.3125,0.08418465,0.1683693 +0.3125,0.3125,0.1683693,0.08418465 +0.3125,0.3375,0.07499999,0.07499999 +0.3125,0.3375,0.053032994,0.10606605 +0.3125,0.33749998,0.10606605,0.053033024 +0.3125,0.3375,0.094494045,0.094494045 +0.3125,0.33750004,0.0668174,0.13363484 +0.3125,0.33749998,0.1336348,0.06681743 +0.3125,0.3375,0.11905509,0.11905509 +0.3125,0.3375,0.08418465,0.1683693 +0.3125,0.3375,0.1683693,0.08418465 +0.3125,0.3625,0.07499999,0.07500002 +0.3125,0.3625,0.053032994,0.10606602 +0.3125,0.3625,0.10606605,0.053033024 +0.3125,0.3625,0.094494045,0.094494075 +0.3125,0.3625,0.0668174,0.1336348 +0.3125,0.3625,0.1336348,0.06681743 +0.3125,0.3625,0.11905509,0.11905506 +0.3125,0.3625,0.08418465,0.1683693 +0.3125,0.3625,0.1683693,0.08418465 +0.3125,0.3875,0.07499999,0.07500002 +0.3125,0.3875,0.053032994,0.10606602 +0.3125,0.3875,0.10606605,0.053032994 +0.3125,0.3875,0.094494045,0.094494075 +0.3125,0.3875,0.0668174,0.13363484 +0.3125,0.3875,0.1336348,0.0668174 +0.3125,0.3875,0.11905509,0.11905506 +0.3125,0.3875,0.08418465,0.1683693 +0.3125,0.3875,0.1683693,0.08418465 +0.3125,0.4125,0.07499999,0.07499999 +0.3125,0.4125,0.053032994,0.10606605 +0.3125,0.4125,0.10606605,0.053032994 +0.3125,0.4125,0.094494045,0.094494045 +0.3125,0.41250002,0.0668174,0.13363484 +0.3125,0.4125,0.1336348,0.0668174 +0.3125,0.4125,0.11905509,0.11905509 +0.3125,0.4125,0.08418465,0.1683693 +0.3125,0.4125,0.1683693,0.08418465 +0.3125,0.4375,0.07499999,0.07499999 +0.3125,0.4375,0.053032994,0.10606605 +0.3125,0.4375,0.10606605,0.053032994 +0.3125,0.4375,0.094494045,0.094494045 +0.3125,0.4375,0.0668174,0.1336348 +0.3125,0.4375,0.1336348,0.0668174 +0.3125,0.4375,0.11905509,0.11905509 +0.3125,0.4375,0.08418465,0.1683693 +0.3125,0.4375,0.1683693,0.08418465 +0.3125,0.4625,0.07499999,0.07499999 +0.3125,0.4625,0.053032994,0.10606605 +0.3125,0.46249998,0.10606605,0.053032964 +0.3125,0.4625,0.094494045,0.094494045 +0.3125,0.46250004,0.0668174,0.13363484 +0.3125,0.46249998,0.1336348,0.06681737 +0.3125,0.4625,0.11905509,0.11905509 +0.3125,0.46249998,0.08418465,0.16836926 +0.3125,0.46249998,0.1683693,0.08418462 +0.3125,0.48749998,0.07499999,0.07499999 +0.3125,0.4875,0.053032994,0.10606602 +0.3125,0.4875,0.10606605,0.053032994 +0.3125,0.48749998,0.094494045,0.094494045 +0.3125,0.4875,0.0668174,0.13363484 +0.3125,0.4875,0.1336348,0.0668174 +0.3125,0.4875,0.11905509,0.11905506 +0.3125,0.4875,0.08418465,0.1683693 +0.3125,0.4875,0.1683693,0.08418465 +0.3125,0.5125,0.07499999,0.07500002 +0.3125,0.51250005,0.053032994,0.10606605 +0.3125,0.5125,0.10606605,0.053032964 +0.3125,0.5125,0.094494045,0.094494075 +0.3125,0.51250005,0.0668174,0.13363487 +0.3125,0.5125,0.1336348,0.06681737 +0.3125,0.51250005,0.11905509,0.11905509 +0.3125,0.5125,0.08418465,0.1683693 +0.3125,0.5125,0.1683693,0.08418465 +0.3125,0.5375,0.07499999,0.07499999 +0.3125,0.5375,0.053032994,0.10606605 +0.3125,0.5375,0.10606605,0.053032935 +0.3125,0.5375,0.094494045,0.094494045 +0.3125,0.5375,0.0668174,0.13363487 +0.3125,0.5375,0.1336348,0.06681734 +0.3125,0.5375,0.11905509,0.11905509 +0.3125,0.5375,0.08418465,0.16836932 +0.3125,0.5375,0.1683693,0.08418468 +0.3125,0.5625,0.07499999,0.07500005 +0.3125,0.5625,0.053032994,0.10606599 +0.3125,0.5625,0.10606605,0.053032994 +0.3125,0.5625,0.094494045,0.094494104 +0.3125,0.5625,0.0668174,0.13363484 +0.3125,0.5625,0.1336348,0.0668174 +0.3125,0.5625,0.11905509,0.11905503 +0.3125,0.5625,0.08418465,0.1683693 +0.3125,0.5625,0.1683693,0.08418465 +0.3125,0.5875,0.07499999,0.07499999 +0.3125,0.5875,0.053032994,0.10606605 +0.3125,0.5875,0.10606605,0.053032935 +0.3125,0.5875,0.094494045,0.094494045 +0.3125,0.5875,0.0668174,0.13363487 +0.3125,0.5875,0.1336348,0.06681734 +0.3125,0.5875,0.11905509,0.11905509 +0.3125,0.5875,0.08418465,0.1683693 +0.3125,0.5875,0.1683693,0.08418465 +0.3125,0.61249995,0.07499999,0.07499999 +0.3125,0.61249995,0.053032994,0.10606605 +0.3125,0.6125,0.10606605,0.053032994 +0.3125,0.61249995,0.094494045,0.094494045 +0.3125,0.61249995,0.0668174,0.13363487 +0.3125,0.6125,0.1336348,0.0668174 +0.3125,0.61249995,0.11905509,0.11905509 +0.3125,0.6125,0.08418465,0.1683693 +0.3125,0.6125,0.1683693,0.08418465 +0.3125,0.63750005,0.07499999,0.07499999 +0.3125,0.63750005,0.053032994,0.10606605 +0.3125,0.6375,0.10606605,0.053032994 +0.3125,0.63750005,0.094494045,0.094494045 +0.3125,0.63750005,0.0668174,0.13363487 +0.3125,0.6375,0.1336348,0.0668174 +0.3125,0.63750005,0.11905509,0.11905509 +0.3125,0.6375,0.08418465,0.1683693 +0.3125,0.6375,0.1683693,0.08418465 +0.3125,0.6625,0.07499999,0.07499999 +0.3125,0.6625,0.053032994,0.10606605 +0.3125,0.6625,0.10606605,0.053032935 +0.3125,0.6625,0.094494045,0.094494045 +0.3125,0.6625,0.0668174,0.13363487 +0.3125,0.6625,0.1336348,0.06681734 +0.3125,0.6625,0.11905509,0.11905509 +0.3125,0.6625,0.08418465,0.1683693 +0.3125,0.6625,0.1683693,0.08418465 +0.3125,0.6875,0.07499999,0.07500005 +0.3125,0.6875,0.053032994,0.10606599 +0.3125,0.6875,0.10606605,0.053032994 +0.3125,0.6875,0.094494045,0.094494104 +0.3125,0.6875,0.0668174,0.1336348 +0.3125,0.6875,0.1336348,0.0668174 +0.3125,0.6875,0.11905509,0.11905503 +0.3125,0.6875,0.08418465,0.1683693 +0.3125,0.6875,0.1683693,0.08418465 +0.3125,0.7125,0.07499999,0.07499999 +0.3125,0.7125,0.053032994,0.10606605 +0.3125,0.7125,0.10606605,0.053032935 +0.3125,0.7125,0.094494045,0.094494045 +0.3125,0.7125,0.0668174,0.13363487 +0.3125,0.7125,0.1336348,0.06681734 +0.3125,0.7125,0.11905509,0.11905509 +0.3125,0.7125,0.08418465,0.1683693 +0.3125,0.7125,0.1683693,0.08418465 +0.3125,0.73749995,0.07499999,0.07499999 +0.3125,0.73749995,0.053032994,0.10606605 +0.3125,0.7375,0.10606605,0.053032994 +0.3125,0.73749995,0.094494045,0.094494045 +0.3125,0.73749995,0.0668174,0.1336348 +0.3125,0.7375,0.1336348,0.0668174 +0.3125,0.73749995,0.11905509,0.11905509 +0.3125,0.7375,0.08418465,0.1683693 +0.3125,0.7375,0.1683693,0.08418465 +0.3125,0.76250005,0.07499999,0.07499999 +0.3125,0.7625,0.053032994,0.10606599 +0.3125,0.7625,0.10606605,0.053032994 +0.3125,0.76250005,0.094494045,0.094494045 +0.3125,0.7625,0.0668174,0.1336348 +0.3125,0.7625,0.1336348,0.0668174 +0.3125,0.7625,0.11905509,0.11905503 +0.3125,0.7625,0.08418465,0.1683693 +0.3125,0.7625,0.1683693,0.08418465 +0.3125,0.7875,0.07499999,0.07499999 +0.3125,0.78749996,0.053032994,0.10606599 +0.3125,0.7875,0.10606605,0.053032994 +0.3125,0.7875,0.094494045,0.094494045 +0.3125,0.78749996,0.0668174,0.1336348 +0.3125,0.7875,0.1336348,0.0668174 +0.3125,0.78749996,0.11905509,0.11905503 +0.3125,0.7875,0.08418465,0.1683693 +0.3125,0.7875,0.1683693,0.08418465 +0.3125,0.8125,0.07499999,0.07500005 +0.3125,0.8125,0.053032994,0.10606599 +0.3125,0.8125,0.10606605,0.053033054 +0.3125,0.8125,0.094494045,0.094494104 +0.3125,0.8125,0.0668174,0.1336348 +0.3125,0.8125,0.1336348,0.06681746 +0.3125,0.8125,0.11905509,0.11905503 +0.3125,0.8125,0.08418465,0.1683693 +0.3125,0.8125,0.1683693,0.08418465 +0.3125,0.8375,0.07499999,0.07499999 +0.3125,0.8375,0.053032994,0.10606599 +0.3125,0.8375,0.10606605,0.053033054 +0.3125,0.8375,0.094494045,0.094494045 +0.3125,0.8375,0.0668174,0.1336348 +0.3125,0.8375,0.1336348,0.06681746 +0.3125,0.8375,0.11905509,0.11905503 +0.3125,0.8375,0.08418465,0.1683693 +0.3125,0.8375,0.1683693,0.08418465 +0.3125,0.86249995,0.07499999,0.07499999 +0.3125,0.86249995,0.053032994,0.10606593 +0.3125,0.86249995,0.10606605,0.053033054 +0.3125,0.86249995,0.094494045,0.094494045 +0.3125,0.86249995,0.0668174,0.1336348 +0.3125,0.86249995,0.1336348,0.06681746 +0.3125,0.86249995,0.11905509,0.11905497 +0.3125,0.8625,0.08418465,0.1683693 +0.3125,0.8625,0.1683693,0.08418465 +0.3125,0.88750005,0.07499999,0.07499999 +0.3125,0.88750005,0.053032994,0.10606593 +0.3125,0.88750005,0.10606605,0.053033054 +0.3125,0.88750005,0.094494045,0.094494045 +0.3125,0.88750005,0.0668174,0.13363475 +0.3125,0.88750005,0.1336348,0.06681746 +0.3125,0.88750005,0.11905509,0.11905497 +0.3125,0.8875,0.08418465,0.1683693 +0.3125,0.8875,0.1683693,0.08418465 +0.3125,0.9125,0.07499999,0.07499999 +0.3125,0.9125,0.053032994,0.10606593 +0.3125,0.9125,0.10606605,0.053033054 +0.3125,0.9125,0.094494045,0.094494045 +0.3125,0.9125,0.0668174,0.13363475 +0.3125,0.9125,0.1336348,0.06681746 +0.3125,0.9125,0.11905509,0.11905497 +0.3125,0.9125,0.08418465,0.1683693 +0.3125,0.9125,0.1683693,0.08418465 +0.3125,0.9375,0.07499999,0.07500005 +0.3125,0.9375,0.053032994,0.10606599 +0.3125,0.9375,0.10606605,0.053033113 +0.3125,0.9375,0.094494045,0.094494104 +0.3125,0.9375,0.0668174,0.1336348 +0.3125,0.9375,0.1336348,0.06681752 +0.3125,0.9375,0.11905509,0.11905503 +0.3125,0.9375,0.08418465,0.1683693 +0.3125,0.9375,0.1683693,0.08418465 +0.3125,0.9625,0.07499999,0.07499999 +0.3125,0.9625,0.053032994,0.10606593 +0.3125,0.9625,0.10606605,0.053033054 +0.3125,0.9625,0.094494045,0.094494045 +0.3125,0.9625,0.0668174,0.13363475 +0.3125,0.9625,0.1336348,0.06681746 +0.3125,0.9625,0.11905509,0.11905497 +0.3125,0.9625,0.08418465,0.1683693 +0.3125,0.9625,0.1683693,0.08418465 +0.3125,0.98749995,0.07499999,0.07499999 +0.3125,0.98749995,0.053032994,0.10606593 +0.3125,0.98749995,0.10606605,0.053033054 +0.3125,0.98749995,0.094494045,0.094494045 +0.3125,0.98749995,0.0668174,0.13363475 +0.3125,0.98749995,0.1336348,0.06681746 +0.3125,0.98749995,0.11905509,0.11905497 +0.3125,0.98749995,0.08418465,0.16836923 +0.3125,0.98749995,0.1683693,0.08418459 +0.3375,0.0125,0.07499999,0.075 +0.33749998,0.012499997,0.053033024,0.10606602 +0.3375,0.012499999,0.10606605,0.05303301 +0.3375,0.012499999,0.094494045,0.09449408 +0.33749998,0.012500001,0.06681743,0.1336348 +0.33750004,0.012499999,0.13363484,0.0668174 +0.3375,0.012500001,0.11905509,0.11905508 +0.3375,0.012499999,0.08418465,0.1683693 +0.3375,0.012500002,0.1683693,0.084184654 +0.3375,0.0375,0.07499999,0.075 +0.33749998,0.037499998,0.053033024,0.10606601 +0.3375,0.0375,0.10606605,0.05303301 +0.3375,0.0375,0.094494045,0.094494075 +0.33749998,0.0375,0.06681743,0.1336348 +0.33750004,0.0375,0.13363484,0.0668174 +0.3375,0.0375,0.11905509,0.11905508 +0.3375,0.0375,0.08418465,0.16836931 +0.3375,0.0375,0.1683693,0.08418466 +0.3375,0.0625,0.07499999,0.075 +0.33749998,0.0625,0.053033024,0.10606602 +0.3375,0.0625,0.10606605,0.05303301 +0.3375,0.0625,0.094494045,0.094494075 +0.33749998,0.0625,0.06681743,0.1336348 +0.33750004,0.0625,0.13363484,0.0668174 +0.3375,0.0625,0.11905509,0.11905508 +0.3375,0.0625,0.08418465,0.16836932 +0.3375,0.0625,0.1683693,0.08418465 +0.3375,0.0875,0.07499999,0.075 +0.33749998,0.08749999,0.053033024,0.10606601 +0.3375,0.087500006,0.10606605,0.053033013 +0.3375,0.087500006,0.094494045,0.09449408 +0.33749998,0.087500006,0.06681743,0.1336348 +0.33750004,0.0875,0.13363484,0.0668174 +0.3375,0.0875,0.11905509,0.11905508 +0.3375,0.0875,0.08418465,0.16836931 +0.3375,0.087500006,0.1683693,0.084184654 +0.3375,0.112500004,0.07499999,0.075 +0.33749998,0.1125,0.053033024,0.10606601 +0.3375,0.112500004,0.10606605,0.05303301 +0.3375,0.1125,0.094494045,0.094494075 +0.33749998,0.1125,0.06681743,0.1336348 +0.33750004,0.1125,0.13363484,0.0668174 +0.3375,0.1125,0.11905509,0.119055085 +0.3375,0.112500004,0.08418465,0.16836931 +0.3375,0.1125,0.1683693,0.08418465 +0.3375,0.1375,0.07499999,0.074999996 +0.33749998,0.1375,0.053033024,0.10606602 +0.3375,0.1375,0.10606605,0.053033024 +0.3375,0.1375,0.094494045,0.09449408 +0.33749998,0.1375,0.06681743,0.1336348 +0.33750004,0.1375,0.13363484,0.0668174 +0.3375,0.13749999,0.11905509,0.11905508 +0.3375,0.1375,0.08418465,0.1683693 +0.3375,0.1375,0.1683693,0.084184654 +0.3375,0.1625,0.07499999,0.075 +0.33749998,0.16250001,0.053033024,0.106066026 +0.3375,0.1625,0.10606605,0.05303301 +0.3375,0.1625,0.094494045,0.094494075 +0.33749998,0.1625,0.06681743,0.1336348 +0.33750004,0.1625,0.13363484,0.0668174 +0.3375,0.1625,0.11905509,0.11905508 +0.3375,0.1625,0.08418465,0.1683693 +0.3375,0.1625,0.1683693,0.08418464 +0.3375,0.1875,0.07499999,0.07499999 +0.33749998,0.1875,0.053033024,0.10606603 +0.3375,0.1875,0.10606605,0.053033024 +0.3375,0.1875,0.094494045,0.09449406 +0.33749998,0.1875,0.06681743,0.1336348 +0.33750004,0.1875,0.13363484,0.06681742 +0.3375,0.1875,0.11905509,0.11905509 +0.3375,0.1875,0.08418465,0.16836931 +0.3375,0.1875,0.1683693,0.08418465 +0.3375,0.2125,0.07499999,0.075 +0.33749998,0.2125,0.053033024,0.10606603 +0.3375,0.2125,0.10606605,0.05303301 +0.3375,0.21249999,0.094494045,0.094494075 +0.33749998,0.2125,0.06681743,0.1336348 +0.33750004,0.2125,0.13363484,0.0668174 +0.3375,0.2125,0.11905509,0.11905509 +0.3375,0.2125,0.08418465,0.16836931 +0.3375,0.2125,0.1683693,0.08418465 +0.3375,0.23750001,0.07499999,0.075 +0.33749998,0.2375,0.053033024,0.10606602 +0.3375,0.2375,0.10606605,0.053033024 +0.3375,0.2375,0.094494045,0.094494075 +0.33749998,0.23750001,0.06681743,0.13363482 +0.33750004,0.2375,0.13363484,0.06681743 +0.3375,0.2375,0.11905509,0.11905506 +0.3375,0.2375,0.08418465,0.16836932 +0.3375,0.23750001,0.1683693,0.08418466 +0.3375,0.2625,0.07499999,0.07500002 +0.33749998,0.2625,0.053033024,0.10606603 +0.3375,0.2625,0.10606605,0.053033024 +0.3375,0.2625,0.094494045,0.094494075 +0.33749998,0.2625,0.06681743,0.13363479 +0.33750004,0.2625,0.13363484,0.06681743 +0.3375,0.2625,0.11905509,0.11905508 +0.3375,0.2625,0.08418465,0.1683693 +0.3375,0.2625,0.1683693,0.08418463 +0.3375,0.2875,0.07499999,0.07499999 +0.33749998,0.2875,0.053033024,0.10606603 +0.3375,0.28750002,0.10606605,0.053033024 +0.3375,0.2875,0.094494045,0.094494045 +0.33749998,0.2875,0.06681743,0.1336348 +0.33750004,0.28750002,0.13363484,0.06681743 +0.3375,0.2875,0.11905509,0.11905508 +0.3375,0.2875,0.08418465,0.1683693 +0.3375,0.2875,0.1683693,0.08418465 +0.3375,0.3125,0.07499999,0.07499999 +0.33749998,0.3125,0.053033024,0.10606605 +0.3375,0.3125,0.10606605,0.053032994 +0.3375,0.3125,0.094494045,0.094494045 +0.33749998,0.3125,0.06681743,0.1336348 +0.33750004,0.3125,0.13363484,0.0668174 +0.3375,0.3125,0.11905509,0.11905509 +0.3375,0.3125,0.08418465,0.1683693 +0.3375,0.3125,0.1683693,0.08418465 +0.3375,0.3375,0.07499999,0.07499999 +0.33749998,0.3375,0.053033024,0.10606605 +0.3375,0.33749998,0.10606605,0.053033024 +0.3375,0.3375,0.094494045,0.094494045 +0.33749998,0.33750004,0.06681743,0.13363484 +0.33750004,0.33749998,0.13363484,0.06681743 +0.3375,0.3375,0.11905509,0.11905509 +0.3375,0.3375,0.08418465,0.1683693 +0.3375,0.3375,0.1683693,0.08418465 +0.3375,0.3625,0.07499999,0.07500002 +0.33749998,0.3625,0.053033024,0.10606602 +0.3375,0.3625,0.10606605,0.053033024 +0.3375,0.3625,0.094494045,0.094494075 +0.33749998,0.3625,0.06681743,0.1336348 +0.33750004,0.3625,0.13363484,0.06681743 +0.3375,0.3625,0.11905509,0.11905506 +0.3375,0.3625,0.08418465,0.1683693 +0.3375,0.3625,0.1683693,0.08418465 +0.3375,0.3875,0.07499999,0.07500002 +0.33749998,0.3875,0.053033024,0.10606602 +0.3375,0.3875,0.10606605,0.053032994 +0.3375,0.3875,0.094494045,0.094494075 +0.33749998,0.3875,0.06681743,0.13363484 +0.33750004,0.3875,0.13363484,0.0668174 +0.3375,0.3875,0.11905509,0.11905506 +0.3375,0.3875,0.08418465,0.1683693 +0.3375,0.3875,0.1683693,0.08418465 +0.3375,0.4125,0.07499999,0.07499999 +0.33749998,0.4125,0.053033024,0.10606605 +0.3375,0.4125,0.10606605,0.053032994 +0.3375,0.4125,0.094494045,0.094494045 +0.33749998,0.41250002,0.06681743,0.13363484 +0.33750004,0.4125,0.13363484,0.0668174 +0.3375,0.4125,0.11905509,0.11905509 +0.3375,0.4125,0.08418465,0.1683693 +0.3375,0.4125,0.1683693,0.08418465 +0.3375,0.4375,0.07499999,0.07499999 +0.33749998,0.4375,0.053033024,0.10606605 +0.3375,0.4375,0.10606605,0.053032994 +0.3375,0.4375,0.094494045,0.094494045 +0.33749998,0.4375,0.06681743,0.1336348 +0.33750004,0.4375,0.13363484,0.0668174 +0.3375,0.4375,0.11905509,0.11905509 +0.3375,0.4375,0.08418465,0.1683693 +0.3375,0.4375,0.1683693,0.08418465 +0.3375,0.4625,0.07499999,0.07499999 +0.33749998,0.4625,0.053033024,0.10606605 +0.3375,0.46249998,0.10606605,0.053032964 +0.3375,0.4625,0.094494045,0.094494045 +0.33749998,0.46250004,0.06681743,0.13363484 +0.33750004,0.46249998,0.13363484,0.06681737 +0.3375,0.4625,0.11905509,0.11905509 +0.3375,0.46249998,0.08418465,0.16836926 +0.3375,0.46249998,0.1683693,0.08418462 +0.3375,0.48749998,0.07499999,0.07499999 +0.33749998,0.4875,0.053033024,0.10606602 +0.3375,0.4875,0.10606605,0.053032994 +0.3375,0.48749998,0.094494045,0.094494045 +0.33749998,0.4875,0.06681743,0.13363484 +0.33750004,0.4875,0.13363484,0.0668174 +0.3375,0.4875,0.11905509,0.11905506 +0.3375,0.4875,0.08418465,0.1683693 +0.3375,0.4875,0.1683693,0.08418465 +0.3375,0.5125,0.07499999,0.07500002 +0.33749998,0.51250005,0.053033024,0.10606605 +0.3375,0.5125,0.10606605,0.053032964 +0.3375,0.5125,0.094494045,0.094494075 +0.33749998,0.51250005,0.06681743,0.13363487 +0.33750004,0.5125,0.13363484,0.06681737 +0.3375,0.51250005,0.11905509,0.11905509 +0.3375,0.5125,0.08418465,0.1683693 +0.3375,0.5125,0.1683693,0.08418465 +0.3375,0.5375,0.07499999,0.07499999 +0.33749998,0.5375,0.053033024,0.10606605 +0.3375,0.5375,0.10606605,0.053032935 +0.3375,0.5375,0.094494045,0.094494045 +0.33749998,0.5375,0.06681743,0.13363487 +0.33750004,0.5375,0.13363484,0.06681734 +0.3375,0.5375,0.11905509,0.11905509 +0.3375,0.5375,0.08418465,0.16836932 +0.3375,0.5375,0.1683693,0.08418468 +0.3375,0.5625,0.07499999,0.07500005 +0.33749998,0.5625,0.053033024,0.10606599 +0.3375,0.5625,0.10606605,0.053032994 +0.3375,0.5625,0.094494045,0.094494104 +0.33749998,0.5625,0.06681743,0.13363484 +0.33750004,0.5625,0.13363484,0.0668174 +0.3375,0.5625,0.11905509,0.11905503 +0.3375,0.5625,0.08418465,0.1683693 +0.3375,0.5625,0.1683693,0.08418465 +0.3375,0.5875,0.07499999,0.07499999 +0.33749998,0.5875,0.053033024,0.10606605 +0.3375,0.5875,0.10606605,0.053032935 +0.3375,0.5875,0.094494045,0.094494045 +0.33749998,0.5875,0.06681743,0.13363487 +0.33750004,0.5875,0.13363484,0.06681734 +0.3375,0.5875,0.11905509,0.11905509 +0.3375,0.5875,0.08418465,0.1683693 +0.3375,0.5875,0.1683693,0.08418465 +0.3375,0.61249995,0.07499999,0.07499999 +0.33749998,0.61249995,0.053033024,0.10606605 +0.3375,0.6125,0.10606605,0.053032994 +0.3375,0.61249995,0.094494045,0.094494045 +0.33749998,0.61249995,0.06681743,0.13363487 +0.33750004,0.6125,0.13363484,0.0668174 +0.3375,0.61249995,0.11905509,0.11905509 +0.3375,0.6125,0.08418465,0.1683693 +0.3375,0.6125,0.1683693,0.08418465 +0.3375,0.63750005,0.07499999,0.07499999 +0.33749998,0.63750005,0.053033024,0.10606605 +0.3375,0.6375,0.10606605,0.053032994 +0.3375,0.63750005,0.094494045,0.094494045 +0.33749998,0.63750005,0.06681743,0.13363487 +0.33750004,0.6375,0.13363484,0.0668174 +0.3375,0.63750005,0.11905509,0.11905509 +0.3375,0.6375,0.08418465,0.1683693 +0.3375,0.6375,0.1683693,0.08418465 +0.3375,0.6625,0.07499999,0.07499999 +0.33749998,0.6625,0.053033024,0.10606605 +0.3375,0.6625,0.10606605,0.053032935 +0.3375,0.6625,0.094494045,0.094494045 +0.33749998,0.6625,0.06681743,0.13363487 +0.33750004,0.6625,0.13363484,0.06681734 +0.3375,0.6625,0.11905509,0.11905509 +0.3375,0.6625,0.08418465,0.1683693 +0.3375,0.6625,0.1683693,0.08418465 +0.3375,0.6875,0.07499999,0.07500005 +0.33749998,0.6875,0.053033024,0.10606599 +0.3375,0.6875,0.10606605,0.053032994 +0.3375,0.6875,0.094494045,0.094494104 +0.33749998,0.6875,0.06681743,0.1336348 +0.33750004,0.6875,0.13363484,0.0668174 +0.3375,0.6875,0.11905509,0.11905503 +0.3375,0.6875,0.08418465,0.1683693 +0.3375,0.6875,0.1683693,0.08418465 +0.3375,0.7125,0.07499999,0.07499999 +0.33749998,0.7125,0.053033024,0.10606605 +0.3375,0.7125,0.10606605,0.053032935 +0.3375,0.7125,0.094494045,0.094494045 +0.33749998,0.7125,0.06681743,0.13363487 +0.33750004,0.7125,0.13363484,0.06681734 +0.3375,0.7125,0.11905509,0.11905509 +0.3375,0.7125,0.08418465,0.1683693 +0.3375,0.7125,0.1683693,0.08418465 +0.3375,0.73749995,0.07499999,0.07499999 +0.33749998,0.73749995,0.053033024,0.10606605 +0.3375,0.7375,0.10606605,0.053032994 +0.3375,0.73749995,0.094494045,0.094494045 +0.33749998,0.73749995,0.06681743,0.1336348 +0.33750004,0.7375,0.13363484,0.0668174 +0.3375,0.73749995,0.11905509,0.11905509 +0.3375,0.7375,0.08418465,0.1683693 +0.3375,0.7375,0.1683693,0.08418465 +0.3375,0.76250005,0.07499999,0.07499999 +0.33749998,0.7625,0.053033024,0.10606599 +0.3375,0.7625,0.10606605,0.053032994 +0.3375,0.76250005,0.094494045,0.094494045 +0.33749998,0.7625,0.06681743,0.1336348 +0.33750004,0.7625,0.13363484,0.0668174 +0.3375,0.7625,0.11905509,0.11905503 +0.3375,0.7625,0.08418465,0.1683693 +0.3375,0.7625,0.1683693,0.08418465 +0.3375,0.7875,0.07499999,0.07499999 +0.33749998,0.78749996,0.053033024,0.10606599 +0.3375,0.7875,0.10606605,0.053032994 +0.3375,0.7875,0.094494045,0.094494045 +0.33749998,0.78749996,0.06681743,0.1336348 +0.33750004,0.7875,0.13363484,0.0668174 +0.3375,0.78749996,0.11905509,0.11905503 +0.3375,0.7875,0.08418465,0.1683693 +0.3375,0.7875,0.1683693,0.08418465 +0.3375,0.8125,0.07499999,0.07500005 +0.33749998,0.8125,0.053033024,0.10606599 +0.3375,0.8125,0.10606605,0.053033054 +0.3375,0.8125,0.094494045,0.094494104 +0.33749998,0.8125,0.06681743,0.1336348 +0.33750004,0.8125,0.13363484,0.06681746 +0.3375,0.8125,0.11905509,0.11905503 +0.3375,0.8125,0.08418465,0.1683693 +0.3375,0.8125,0.1683693,0.08418465 +0.3375,0.8375,0.07499999,0.07499999 +0.33749998,0.8375,0.053033024,0.10606599 +0.3375,0.8375,0.10606605,0.053033054 +0.3375,0.8375,0.094494045,0.094494045 +0.33749998,0.8375,0.06681743,0.1336348 +0.33750004,0.8375,0.13363484,0.06681746 +0.3375,0.8375,0.11905509,0.11905503 +0.3375,0.8375,0.08418465,0.1683693 +0.3375,0.8375,0.1683693,0.08418465 +0.3375,0.86249995,0.07499999,0.07499999 +0.33749998,0.86249995,0.053033024,0.10606593 +0.3375,0.86249995,0.10606605,0.053033054 +0.3375,0.86249995,0.094494045,0.094494045 +0.33749998,0.86249995,0.06681743,0.1336348 +0.33750004,0.86249995,0.13363484,0.06681746 +0.3375,0.86249995,0.11905509,0.11905497 +0.3375,0.8625,0.08418465,0.1683693 +0.3375,0.8625,0.1683693,0.08418465 +0.3375,0.88750005,0.07499999,0.07499999 +0.33749998,0.88750005,0.053033024,0.10606593 +0.3375,0.88750005,0.10606605,0.053033054 +0.3375,0.88750005,0.094494045,0.094494045 +0.33749998,0.88750005,0.06681743,0.13363475 +0.33750004,0.88750005,0.13363484,0.06681746 +0.3375,0.88750005,0.11905509,0.11905497 +0.3375,0.8875,0.08418465,0.1683693 +0.3375,0.8875,0.1683693,0.08418465 +0.3375,0.9125,0.07499999,0.07499999 +0.33749998,0.9125,0.053033024,0.10606593 +0.3375,0.9125,0.10606605,0.053033054 +0.3375,0.9125,0.094494045,0.094494045 +0.33749998,0.9125,0.06681743,0.13363475 +0.33750004,0.9125,0.13363484,0.06681746 +0.3375,0.9125,0.11905509,0.11905497 +0.3375,0.9125,0.08418465,0.1683693 +0.3375,0.9125,0.1683693,0.08418465 +0.3375,0.9375,0.07499999,0.07500005 +0.33749998,0.9375,0.053033024,0.10606599 +0.3375,0.9375,0.10606605,0.053033113 +0.3375,0.9375,0.094494045,0.094494104 +0.33749998,0.9375,0.06681743,0.1336348 +0.33750004,0.9375,0.13363484,0.06681752 +0.3375,0.9375,0.11905509,0.11905503 +0.3375,0.9375,0.08418465,0.1683693 +0.3375,0.9375,0.1683693,0.08418465 +0.3375,0.9625,0.07499999,0.07499999 +0.33749998,0.9625,0.053033024,0.10606593 +0.3375,0.9625,0.10606605,0.053033054 +0.3375,0.9625,0.094494045,0.094494045 +0.33749998,0.9625,0.06681743,0.13363475 +0.33750004,0.9625,0.13363484,0.06681746 +0.3375,0.9625,0.11905509,0.11905497 +0.3375,0.9625,0.08418465,0.1683693 +0.3375,0.9625,0.1683693,0.08418465 +0.3375,0.98749995,0.07499999,0.07499999 +0.33749998,0.98749995,0.053033024,0.10606593 +0.3375,0.98749995,0.10606605,0.053033054 +0.3375,0.98749995,0.094494045,0.094494045 +0.33749998,0.98749995,0.06681743,0.13363475 +0.33750004,0.98749995,0.13363484,0.06681746 +0.3375,0.98749995,0.11905509,0.11905497 +0.3375,0.98749995,0.08418465,0.16836923 +0.3375,0.98749995,0.1683693,0.08418459 +0.3625,0.0125,0.07500002,0.075 +0.3625,0.012499997,0.053033024,0.10606602 +0.3625,0.012499999,0.10606602,0.05303301 +0.3625,0.012499999,0.094494075,0.09449408 +0.3625,0.012500001,0.06681743,0.1336348 +0.3625,0.012499999,0.1336348,0.0668174 +0.3625,0.012500001,0.11905506,0.11905508 +0.3625,0.012499999,0.08418465,0.1683693 +0.3625,0.012500002,0.1683693,0.084184654 +0.3625,0.0375,0.07500002,0.075 +0.3625,0.037499998,0.053033024,0.10606601 +0.3625,0.0375,0.10606602,0.05303301 +0.3625,0.0375,0.094494075,0.094494075 +0.3625,0.0375,0.06681743,0.1336348 +0.3625,0.0375,0.1336348,0.0668174 +0.3625,0.0375,0.11905506,0.11905508 +0.3625,0.0375,0.08418465,0.16836931 +0.3625,0.0375,0.1683693,0.08418466 +0.3625,0.0625,0.07500002,0.075 +0.3625,0.0625,0.053033024,0.10606602 +0.3625,0.0625,0.10606602,0.05303301 +0.3625,0.0625,0.094494075,0.094494075 +0.3625,0.0625,0.06681743,0.1336348 +0.3625,0.0625,0.1336348,0.0668174 +0.3625,0.0625,0.11905506,0.11905508 +0.3625,0.0625,0.08418465,0.16836932 +0.3625,0.0625,0.1683693,0.08418465 +0.3625,0.0875,0.07500002,0.075 +0.3625,0.08749999,0.053033024,0.10606601 +0.3625,0.087500006,0.10606602,0.053033013 +0.3625,0.087500006,0.094494075,0.09449408 +0.3625,0.087500006,0.06681743,0.1336348 +0.3625,0.0875,0.1336348,0.0668174 +0.3625,0.0875,0.11905506,0.11905508 +0.3625,0.0875,0.08418465,0.16836931 +0.3625,0.087500006,0.1683693,0.084184654 +0.3625,0.112500004,0.07500002,0.075 +0.3625,0.1125,0.053033024,0.10606601 +0.3625,0.112500004,0.10606602,0.05303301 +0.3625,0.1125,0.094494075,0.094494075 +0.3625,0.1125,0.06681743,0.1336348 +0.3625,0.1125,0.1336348,0.0668174 +0.3625,0.1125,0.11905506,0.119055085 +0.3625,0.112500004,0.08418465,0.16836931 +0.3625,0.1125,0.1683693,0.08418465 +0.3625,0.1375,0.07500002,0.074999996 +0.3625,0.1375,0.053033024,0.10606602 +0.3625,0.1375,0.10606602,0.053033024 +0.3625,0.1375,0.094494075,0.09449408 +0.3625,0.1375,0.06681743,0.1336348 +0.3625,0.1375,0.1336348,0.0668174 +0.3625,0.13749999,0.11905506,0.11905508 +0.3625,0.1375,0.08418465,0.1683693 +0.3625,0.1375,0.1683693,0.084184654 +0.3625,0.1625,0.07500002,0.075 +0.3625,0.16250001,0.053033024,0.106066026 +0.3625,0.1625,0.10606602,0.05303301 +0.3625,0.1625,0.094494075,0.094494075 +0.3625,0.1625,0.06681743,0.1336348 +0.3625,0.1625,0.1336348,0.0668174 +0.3625,0.1625,0.11905506,0.11905508 +0.3625,0.1625,0.08418465,0.1683693 +0.3625,0.1625,0.1683693,0.08418464 +0.3625,0.1875,0.07500002,0.07499999 +0.3625,0.1875,0.053033024,0.10606603 +0.3625,0.1875,0.10606602,0.053033024 +0.3625,0.1875,0.094494075,0.09449406 +0.3625,0.1875,0.06681743,0.1336348 +0.3625,0.1875,0.1336348,0.06681742 +0.3625,0.1875,0.11905506,0.11905509 +0.3625,0.1875,0.08418465,0.16836931 +0.3625,0.1875,0.1683693,0.08418465 +0.3625,0.2125,0.07500002,0.075 +0.3625,0.2125,0.053033024,0.10606603 +0.3625,0.2125,0.10606602,0.05303301 +0.3625,0.21249999,0.094494075,0.094494075 +0.3625,0.2125,0.06681743,0.1336348 +0.3625,0.2125,0.1336348,0.0668174 +0.3625,0.2125,0.11905506,0.11905509 +0.3625,0.2125,0.08418465,0.16836931 +0.3625,0.2125,0.1683693,0.08418465 +0.3625,0.23750001,0.07500002,0.075 +0.3625,0.2375,0.053033024,0.10606602 +0.3625,0.2375,0.10606602,0.053033024 +0.3625,0.2375,0.094494075,0.094494075 +0.3625,0.23750001,0.06681743,0.13363482 +0.3625,0.2375,0.1336348,0.06681743 +0.3625,0.2375,0.11905506,0.11905506 +0.3625,0.2375,0.08418465,0.16836932 +0.3625,0.23750001,0.1683693,0.08418466 +0.3625,0.2625,0.07500002,0.07500002 +0.3625,0.2625,0.053033024,0.10606603 +0.3625,0.2625,0.10606602,0.053033024 +0.3625,0.2625,0.094494075,0.094494075 +0.3625,0.2625,0.06681743,0.13363479 +0.3625,0.2625,0.1336348,0.06681743 +0.3625,0.2625,0.11905506,0.11905508 +0.3625,0.2625,0.08418465,0.1683693 +0.3625,0.2625,0.1683693,0.08418463 +0.3625,0.2875,0.07500002,0.07499999 +0.3625,0.2875,0.053033024,0.10606603 +0.3625,0.28750002,0.10606602,0.053033024 +0.3625,0.2875,0.094494075,0.094494045 +0.3625,0.2875,0.06681743,0.1336348 +0.3625,0.28750002,0.1336348,0.06681743 +0.3625,0.2875,0.11905506,0.11905508 +0.3625,0.2875,0.08418465,0.1683693 +0.3625,0.2875,0.1683693,0.08418465 +0.3625,0.3125,0.07500002,0.07499999 +0.3625,0.3125,0.053033024,0.10606605 +0.3625,0.3125,0.10606602,0.053032994 +0.3625,0.3125,0.094494075,0.094494045 +0.3625,0.3125,0.06681743,0.1336348 +0.3625,0.3125,0.1336348,0.0668174 +0.3625,0.3125,0.11905506,0.11905509 +0.3625,0.3125,0.08418465,0.1683693 +0.3625,0.3125,0.1683693,0.08418465 +0.3625,0.3375,0.07500002,0.07499999 +0.3625,0.3375,0.053033024,0.10606605 +0.3625,0.33749998,0.10606602,0.053033024 +0.3625,0.3375,0.094494075,0.094494045 +0.3625,0.33750004,0.06681743,0.13363484 +0.3625,0.33749998,0.1336348,0.06681743 +0.3625,0.3375,0.11905506,0.11905509 +0.3625,0.3375,0.08418465,0.1683693 +0.3625,0.3375,0.1683693,0.08418465 +0.3625,0.3625,0.07500002,0.07500002 +0.3625,0.3625,0.053033024,0.10606602 +0.3625,0.3625,0.10606602,0.053033024 +0.3625,0.3625,0.094494075,0.094494075 +0.3625,0.3625,0.06681743,0.1336348 +0.3625,0.3625,0.1336348,0.06681743 +0.3625,0.3625,0.11905506,0.11905506 +0.3625,0.3625,0.08418465,0.1683693 +0.3625,0.3625,0.1683693,0.08418465 +0.3625,0.3875,0.07500002,0.07500002 +0.3625,0.3875,0.053033024,0.10606602 +0.3625,0.3875,0.10606602,0.053032994 +0.3625,0.3875,0.094494075,0.094494075 +0.3625,0.3875,0.06681743,0.13363484 +0.3625,0.3875,0.1336348,0.0668174 +0.3625,0.3875,0.11905506,0.11905506 +0.3625,0.3875,0.08418465,0.1683693 +0.3625,0.3875,0.1683693,0.08418465 +0.3625,0.4125,0.07500002,0.07499999 +0.3625,0.4125,0.053033024,0.10606605 +0.3625,0.4125,0.10606602,0.053032994 +0.3625,0.4125,0.094494075,0.094494045 +0.3625,0.41250002,0.06681743,0.13363484 +0.3625,0.4125,0.1336348,0.0668174 +0.3625,0.4125,0.11905506,0.11905509 +0.3625,0.4125,0.08418465,0.1683693 +0.3625,0.4125,0.1683693,0.08418465 +0.3625,0.4375,0.07500002,0.07499999 +0.3625,0.4375,0.053033024,0.10606605 +0.3625,0.4375,0.10606602,0.053032994 +0.3625,0.4375,0.094494075,0.094494045 +0.3625,0.4375,0.06681743,0.1336348 +0.3625,0.4375,0.1336348,0.0668174 +0.3625,0.4375,0.11905506,0.11905509 +0.3625,0.4375,0.08418465,0.1683693 +0.3625,0.4375,0.1683693,0.08418465 +0.3625,0.4625,0.07500002,0.07499999 +0.3625,0.4625,0.053033024,0.10606605 +0.3625,0.46249998,0.10606602,0.053032964 +0.3625,0.4625,0.094494075,0.094494045 +0.3625,0.46250004,0.06681743,0.13363484 +0.3625,0.46249998,0.1336348,0.06681737 +0.3625,0.4625,0.11905506,0.11905509 +0.3625,0.46249998,0.08418465,0.16836926 +0.3625,0.46249998,0.1683693,0.08418462 +0.3625,0.48749998,0.07500002,0.07499999 +0.3625,0.4875,0.053033024,0.10606602 +0.3625,0.4875,0.10606602,0.053032994 +0.3625,0.48749998,0.094494075,0.094494045 +0.3625,0.4875,0.06681743,0.13363484 +0.3625,0.4875,0.1336348,0.0668174 +0.3625,0.4875,0.11905506,0.11905506 +0.3625,0.4875,0.08418465,0.1683693 +0.3625,0.4875,0.1683693,0.08418465 +0.3625,0.5125,0.07500002,0.07500002 +0.3625,0.51250005,0.053033024,0.10606605 +0.3625,0.5125,0.10606602,0.053032964 +0.3625,0.5125,0.094494075,0.094494075 +0.3625,0.51250005,0.06681743,0.13363487 +0.3625,0.5125,0.1336348,0.06681737 +0.3625,0.51250005,0.11905506,0.11905509 +0.3625,0.5125,0.08418465,0.1683693 +0.3625,0.5125,0.1683693,0.08418465 +0.3625,0.5375,0.07500002,0.07499999 +0.3625,0.5375,0.053033024,0.10606605 +0.3625,0.5375,0.10606602,0.053032935 +0.3625,0.5375,0.094494075,0.094494045 +0.3625,0.5375,0.06681743,0.13363487 +0.3625,0.5375,0.1336348,0.06681734 +0.3625,0.5375,0.11905506,0.11905509 +0.3625,0.5375,0.08418465,0.16836932 +0.3625,0.5375,0.1683693,0.08418468 +0.3625,0.5625,0.07500002,0.07500005 +0.3625,0.5625,0.053033024,0.10606599 +0.3625,0.5625,0.10606602,0.053032994 +0.3625,0.5625,0.094494075,0.094494104 +0.3625,0.5625,0.06681743,0.13363484 +0.3625,0.5625,0.1336348,0.0668174 +0.3625,0.5625,0.11905506,0.11905503 +0.3625,0.5625,0.08418465,0.1683693 +0.3625,0.5625,0.1683693,0.08418465 +0.3625,0.5875,0.07500002,0.07499999 +0.3625,0.5875,0.053033024,0.10606605 +0.3625,0.5875,0.10606602,0.053032935 +0.3625,0.5875,0.094494075,0.094494045 +0.3625,0.5875,0.06681743,0.13363487 +0.3625,0.5875,0.1336348,0.06681734 +0.3625,0.5875,0.11905506,0.11905509 +0.3625,0.5875,0.08418465,0.1683693 +0.3625,0.5875,0.1683693,0.08418465 +0.3625,0.61249995,0.07500002,0.07499999 +0.3625,0.61249995,0.053033024,0.10606605 +0.3625,0.6125,0.10606602,0.053032994 +0.3625,0.61249995,0.094494075,0.094494045 +0.3625,0.61249995,0.06681743,0.13363487 +0.3625,0.6125,0.1336348,0.0668174 +0.3625,0.61249995,0.11905506,0.11905509 +0.3625,0.6125,0.08418465,0.1683693 +0.3625,0.6125,0.1683693,0.08418465 +0.3625,0.63750005,0.07500002,0.07499999 +0.3625,0.63750005,0.053033024,0.10606605 +0.3625,0.6375,0.10606602,0.053032994 +0.3625,0.63750005,0.094494075,0.094494045 +0.3625,0.63750005,0.06681743,0.13363487 +0.3625,0.6375,0.1336348,0.0668174 +0.3625,0.63750005,0.11905506,0.11905509 +0.3625,0.6375,0.08418465,0.1683693 +0.3625,0.6375,0.1683693,0.08418465 +0.3625,0.6625,0.07500002,0.07499999 +0.3625,0.6625,0.053033024,0.10606605 +0.3625,0.6625,0.10606602,0.053032935 +0.3625,0.6625,0.094494075,0.094494045 +0.3625,0.6625,0.06681743,0.13363487 +0.3625,0.6625,0.1336348,0.06681734 +0.3625,0.6625,0.11905506,0.11905509 +0.3625,0.6625,0.08418465,0.1683693 +0.3625,0.6625,0.1683693,0.08418465 +0.3625,0.6875,0.07500002,0.07500005 +0.3625,0.6875,0.053033024,0.10606599 +0.3625,0.6875,0.10606602,0.053032994 +0.3625,0.6875,0.094494075,0.094494104 +0.3625,0.6875,0.06681743,0.1336348 +0.3625,0.6875,0.1336348,0.0668174 +0.3625,0.6875,0.11905506,0.11905503 +0.3625,0.6875,0.08418465,0.1683693 +0.3625,0.6875,0.1683693,0.08418465 +0.3625,0.7125,0.07500002,0.07499999 +0.3625,0.7125,0.053033024,0.10606605 +0.3625,0.7125,0.10606602,0.053032935 +0.3625,0.7125,0.094494075,0.094494045 +0.3625,0.7125,0.06681743,0.13363487 +0.3625,0.7125,0.1336348,0.06681734 +0.3625,0.7125,0.11905506,0.11905509 +0.3625,0.7125,0.08418465,0.1683693 +0.3625,0.7125,0.1683693,0.08418465 +0.3625,0.73749995,0.07500002,0.07499999 +0.3625,0.73749995,0.053033024,0.10606605 +0.3625,0.7375,0.10606602,0.053032994 +0.3625,0.73749995,0.094494075,0.094494045 +0.3625,0.73749995,0.06681743,0.1336348 +0.3625,0.7375,0.1336348,0.0668174 +0.3625,0.73749995,0.11905506,0.11905509 +0.3625,0.7375,0.08418465,0.1683693 +0.3625,0.7375,0.1683693,0.08418465 +0.3625,0.76250005,0.07500002,0.07499999 +0.3625,0.7625,0.053033024,0.10606599 +0.3625,0.7625,0.10606602,0.053032994 +0.3625,0.76250005,0.094494075,0.094494045 +0.3625,0.7625,0.06681743,0.1336348 +0.3625,0.7625,0.1336348,0.0668174 +0.3625,0.7625,0.11905506,0.11905503 +0.3625,0.7625,0.08418465,0.1683693 +0.3625,0.7625,0.1683693,0.08418465 +0.3625,0.7875,0.07500002,0.07499999 +0.3625,0.78749996,0.053033024,0.10606599 +0.3625,0.7875,0.10606602,0.053032994 +0.3625,0.7875,0.094494075,0.094494045 +0.3625,0.78749996,0.06681743,0.1336348 +0.3625,0.7875,0.1336348,0.0668174 +0.3625,0.78749996,0.11905506,0.11905503 +0.3625,0.7875,0.08418465,0.1683693 +0.3625,0.7875,0.1683693,0.08418465 +0.3625,0.8125,0.07500002,0.07500005 +0.3625,0.8125,0.053033024,0.10606599 +0.3625,0.8125,0.10606602,0.053033054 +0.3625,0.8125,0.094494075,0.094494104 +0.3625,0.8125,0.06681743,0.1336348 +0.3625,0.8125,0.1336348,0.06681746 +0.3625,0.8125,0.11905506,0.11905503 +0.3625,0.8125,0.08418465,0.1683693 +0.3625,0.8125,0.1683693,0.08418465 +0.3625,0.8375,0.07500002,0.07499999 +0.3625,0.8375,0.053033024,0.10606599 +0.3625,0.8375,0.10606602,0.053033054 +0.3625,0.8375,0.094494075,0.094494045 +0.3625,0.8375,0.06681743,0.1336348 +0.3625,0.8375,0.1336348,0.06681746 +0.3625,0.8375,0.11905506,0.11905503 +0.3625,0.8375,0.08418465,0.1683693 +0.3625,0.8375,0.1683693,0.08418465 +0.3625,0.86249995,0.07500002,0.07499999 +0.3625,0.86249995,0.053033024,0.10606593 +0.3625,0.86249995,0.10606602,0.053033054 +0.3625,0.86249995,0.094494075,0.094494045 +0.3625,0.86249995,0.06681743,0.1336348 +0.3625,0.86249995,0.1336348,0.06681746 +0.3625,0.86249995,0.11905506,0.11905497 +0.3625,0.8625,0.08418465,0.1683693 +0.3625,0.8625,0.1683693,0.08418465 +0.3625,0.88750005,0.07500002,0.07499999 +0.3625,0.88750005,0.053033024,0.10606593 +0.3625,0.88750005,0.10606602,0.053033054 +0.3625,0.88750005,0.094494075,0.094494045 +0.3625,0.88750005,0.06681743,0.13363475 +0.3625,0.88750005,0.1336348,0.06681746 +0.3625,0.88750005,0.11905506,0.11905497 +0.3625,0.8875,0.08418465,0.1683693 +0.3625,0.8875,0.1683693,0.08418465 +0.3625,0.9125,0.07500002,0.07499999 +0.3625,0.9125,0.053033024,0.10606593 +0.3625,0.9125,0.10606602,0.053033054 +0.3625,0.9125,0.094494075,0.094494045 +0.3625,0.9125,0.06681743,0.13363475 +0.3625,0.9125,0.1336348,0.06681746 +0.3625,0.9125,0.11905506,0.11905497 +0.3625,0.9125,0.08418465,0.1683693 +0.3625,0.9125,0.1683693,0.08418465 +0.3625,0.9375,0.07500002,0.07500005 +0.3625,0.9375,0.053033024,0.10606599 +0.3625,0.9375,0.10606602,0.053033113 +0.3625,0.9375,0.094494075,0.094494104 +0.3625,0.9375,0.06681743,0.1336348 +0.3625,0.9375,0.1336348,0.06681752 +0.3625,0.9375,0.11905506,0.11905503 +0.3625,0.9375,0.08418465,0.1683693 +0.3625,0.9375,0.1683693,0.08418465 +0.3625,0.9625,0.07500002,0.07499999 +0.3625,0.9625,0.053033024,0.10606593 +0.3625,0.9625,0.10606602,0.053033054 +0.3625,0.9625,0.094494075,0.094494045 +0.3625,0.9625,0.06681743,0.13363475 +0.3625,0.9625,0.1336348,0.06681746 +0.3625,0.9625,0.11905506,0.11905497 +0.3625,0.9625,0.08418465,0.1683693 +0.3625,0.9625,0.1683693,0.08418465 +0.3625,0.98749995,0.07500002,0.07499999 +0.3625,0.98749995,0.053033024,0.10606593 +0.3625,0.98749995,0.10606602,0.053033054 +0.3625,0.98749995,0.094494075,0.094494045 +0.3625,0.98749995,0.06681743,0.13363475 +0.3625,0.98749995,0.1336348,0.06681746 +0.3625,0.98749995,0.11905506,0.11905497 +0.3625,0.98749995,0.08418465,0.16836923 +0.3625,0.98749995,0.1683693,0.08418459 +0.3875,0.0125,0.07500002,0.075 +0.3875,0.012499997,0.053032994,0.10606602 +0.3875,0.012499999,0.10606602,0.05303301 +0.3875,0.012499999,0.094494075,0.09449408 +0.3875,0.012500001,0.0668174,0.1336348 +0.3875,0.012499999,0.13363484,0.0668174 +0.3875,0.012500001,0.11905506,0.11905508 +0.3875,0.012499999,0.08418465,0.1683693 +0.3875,0.012500002,0.1683693,0.084184654 +0.3875,0.0375,0.07500002,0.075 +0.3875,0.037499998,0.053032994,0.10606601 +0.3875,0.0375,0.10606602,0.05303301 +0.3875,0.0375,0.094494075,0.094494075 +0.3875,0.0375,0.0668174,0.1336348 +0.3875,0.0375,0.13363484,0.0668174 +0.3875,0.0375,0.11905506,0.11905508 +0.3875,0.0375,0.08418465,0.16836931 +0.3875,0.0375,0.1683693,0.08418466 +0.3875,0.0625,0.07500002,0.075 +0.3875,0.0625,0.053032994,0.10606602 +0.3875,0.0625,0.10606602,0.05303301 +0.3875,0.0625,0.094494075,0.094494075 +0.3875,0.0625,0.0668174,0.1336348 +0.3875,0.0625,0.13363484,0.0668174 +0.3875,0.0625,0.11905506,0.11905508 +0.3875,0.0625,0.08418465,0.16836932 +0.3875,0.0625,0.1683693,0.08418465 +0.3875,0.0875,0.07500002,0.075 +0.3875,0.08749999,0.053032994,0.10606601 +0.3875,0.087500006,0.10606602,0.053033013 +0.3875,0.087500006,0.094494075,0.09449408 +0.3875,0.087500006,0.0668174,0.1336348 +0.3875,0.0875,0.13363484,0.0668174 +0.3875,0.0875,0.11905506,0.11905508 +0.3875,0.0875,0.08418465,0.16836931 +0.3875,0.087500006,0.1683693,0.084184654 +0.3875,0.112500004,0.07500002,0.075 +0.3875,0.1125,0.053032994,0.10606601 +0.3875,0.112500004,0.10606602,0.05303301 +0.3875,0.1125,0.094494075,0.094494075 +0.3875,0.1125,0.0668174,0.1336348 +0.3875,0.1125,0.13363484,0.0668174 +0.3875,0.1125,0.11905506,0.119055085 +0.3875,0.112500004,0.08418465,0.16836931 +0.3875,0.1125,0.1683693,0.08418465 +0.3875,0.1375,0.07500002,0.074999996 +0.3875,0.1375,0.053032994,0.10606602 +0.3875,0.1375,0.10606602,0.053033024 +0.3875,0.1375,0.094494075,0.09449408 +0.3875,0.1375,0.0668174,0.1336348 +0.3875,0.1375,0.13363484,0.0668174 +0.3875,0.13749999,0.11905506,0.11905508 +0.3875,0.1375,0.08418465,0.1683693 +0.3875,0.1375,0.1683693,0.084184654 +0.3875,0.1625,0.07500002,0.075 +0.3875,0.16250001,0.053032994,0.106066026 +0.3875,0.1625,0.10606602,0.05303301 +0.3875,0.1625,0.094494075,0.094494075 +0.3875,0.1625,0.0668174,0.1336348 +0.3875,0.1625,0.13363484,0.0668174 +0.3875,0.1625,0.11905506,0.11905508 +0.3875,0.1625,0.08418465,0.1683693 +0.3875,0.1625,0.1683693,0.08418464 +0.3875,0.1875,0.07500002,0.07499999 +0.3875,0.1875,0.053032994,0.10606603 +0.3875,0.1875,0.10606602,0.053033024 +0.3875,0.1875,0.094494075,0.09449406 +0.3875,0.1875,0.0668174,0.1336348 +0.3875,0.1875,0.13363484,0.06681742 +0.3875,0.1875,0.11905506,0.11905509 +0.3875,0.1875,0.08418465,0.16836931 +0.3875,0.1875,0.1683693,0.08418465 +0.3875,0.2125,0.07500002,0.075 +0.3875,0.2125,0.053032994,0.10606603 +0.3875,0.2125,0.10606602,0.05303301 +0.3875,0.21249999,0.094494075,0.094494075 +0.3875,0.2125,0.0668174,0.1336348 +0.3875,0.2125,0.13363484,0.0668174 +0.3875,0.2125,0.11905506,0.11905509 +0.3875,0.2125,0.08418465,0.16836931 +0.3875,0.2125,0.1683693,0.08418465 +0.3875,0.23750001,0.07500002,0.075 +0.3875,0.2375,0.053032994,0.10606602 +0.3875,0.2375,0.10606602,0.053033024 +0.3875,0.2375,0.094494075,0.094494075 +0.3875,0.23750001,0.0668174,0.13363482 +0.3875,0.2375,0.13363484,0.06681743 +0.3875,0.2375,0.11905506,0.11905506 +0.3875,0.2375,0.08418465,0.16836932 +0.3875,0.23750001,0.1683693,0.08418466 +0.3875,0.2625,0.07500002,0.07500002 +0.3875,0.2625,0.053032994,0.10606603 +0.3875,0.2625,0.10606602,0.053033024 +0.3875,0.2625,0.094494075,0.094494075 +0.3875,0.2625,0.0668174,0.13363479 +0.3875,0.2625,0.13363484,0.06681743 +0.3875,0.2625,0.11905506,0.11905508 +0.3875,0.2625,0.08418465,0.1683693 +0.3875,0.2625,0.1683693,0.08418463 +0.3875,0.2875,0.07500002,0.07499999 +0.3875,0.2875,0.053032994,0.10606603 +0.3875,0.28750002,0.10606602,0.053033024 +0.3875,0.2875,0.094494075,0.094494045 +0.3875,0.2875,0.0668174,0.1336348 +0.3875,0.28750002,0.13363484,0.06681743 +0.3875,0.2875,0.11905506,0.11905508 +0.3875,0.2875,0.08418465,0.1683693 +0.3875,0.2875,0.1683693,0.08418465 +0.3875,0.3125,0.07500002,0.07499999 +0.3875,0.3125,0.053032994,0.10606605 +0.3875,0.3125,0.10606602,0.053032994 +0.3875,0.3125,0.094494075,0.094494045 +0.3875,0.3125,0.0668174,0.1336348 +0.3875,0.3125,0.13363484,0.0668174 +0.3875,0.3125,0.11905506,0.11905509 +0.3875,0.3125,0.08418465,0.1683693 +0.3875,0.3125,0.1683693,0.08418465 +0.3875,0.3375,0.07500002,0.07499999 +0.3875,0.3375,0.053032994,0.10606605 +0.3875,0.33749998,0.10606602,0.053033024 +0.3875,0.3375,0.094494075,0.094494045 +0.3875,0.33750004,0.0668174,0.13363484 +0.3875,0.33749998,0.13363484,0.06681743 +0.3875,0.3375,0.11905506,0.11905509 +0.3875,0.3375,0.08418465,0.1683693 +0.3875,0.3375,0.1683693,0.08418465 +0.3875,0.3625,0.07500002,0.07500002 +0.3875,0.3625,0.053032994,0.10606602 +0.3875,0.3625,0.10606602,0.053033024 +0.3875,0.3625,0.094494075,0.094494075 +0.3875,0.3625,0.0668174,0.1336348 +0.3875,0.3625,0.13363484,0.06681743 +0.3875,0.3625,0.11905506,0.11905506 +0.3875,0.3625,0.08418465,0.1683693 +0.3875,0.3625,0.1683693,0.08418465 +0.3875,0.3875,0.07500002,0.07500002 +0.3875,0.3875,0.053032994,0.10606602 +0.3875,0.3875,0.10606602,0.053032994 +0.3875,0.3875,0.094494075,0.094494075 +0.3875,0.3875,0.0668174,0.13363484 +0.3875,0.3875,0.13363484,0.0668174 +0.3875,0.3875,0.11905506,0.11905506 +0.3875,0.3875,0.08418465,0.1683693 +0.3875,0.3875,0.1683693,0.08418465 +0.3875,0.4125,0.07500002,0.07499999 +0.3875,0.4125,0.053032994,0.10606605 +0.3875,0.4125,0.10606602,0.053032994 +0.3875,0.4125,0.094494075,0.094494045 +0.3875,0.41250002,0.0668174,0.13363484 +0.3875,0.4125,0.13363484,0.0668174 +0.3875,0.4125,0.11905506,0.11905509 +0.3875,0.4125,0.08418465,0.1683693 +0.3875,0.4125,0.1683693,0.08418465 +0.3875,0.4375,0.07500002,0.07499999 +0.3875,0.4375,0.053032994,0.10606605 +0.3875,0.4375,0.10606602,0.053032994 +0.3875,0.4375,0.094494075,0.094494045 +0.3875,0.4375,0.0668174,0.1336348 +0.3875,0.4375,0.13363484,0.0668174 +0.3875,0.4375,0.11905506,0.11905509 +0.3875,0.4375,0.08418465,0.1683693 +0.3875,0.4375,0.1683693,0.08418465 +0.3875,0.4625,0.07500002,0.07499999 +0.3875,0.4625,0.053032994,0.10606605 +0.3875,0.46249998,0.10606602,0.053032964 +0.3875,0.4625,0.094494075,0.094494045 +0.3875,0.46250004,0.0668174,0.13363484 +0.3875,0.46249998,0.13363484,0.06681737 +0.3875,0.4625,0.11905506,0.11905509 +0.3875,0.46249998,0.08418465,0.16836926 +0.3875,0.46249998,0.1683693,0.08418462 +0.3875,0.48749998,0.07500002,0.07499999 +0.3875,0.4875,0.053032994,0.10606602 +0.3875,0.4875,0.10606602,0.053032994 +0.3875,0.48749998,0.094494075,0.094494045 +0.3875,0.4875,0.0668174,0.13363484 +0.3875,0.4875,0.13363484,0.0668174 +0.3875,0.4875,0.11905506,0.11905506 +0.3875,0.4875,0.08418465,0.1683693 +0.3875,0.4875,0.1683693,0.08418465 +0.3875,0.5125,0.07500002,0.07500002 +0.3875,0.51250005,0.053032994,0.10606605 +0.3875,0.5125,0.10606602,0.053032964 +0.3875,0.5125,0.094494075,0.094494075 +0.3875,0.51250005,0.0668174,0.13363487 +0.3875,0.5125,0.13363484,0.06681737 +0.3875,0.51250005,0.11905506,0.11905509 +0.3875,0.5125,0.08418465,0.1683693 +0.3875,0.5125,0.1683693,0.08418465 +0.3875,0.5375,0.07500002,0.07499999 +0.3875,0.5375,0.053032994,0.10606605 +0.3875,0.5375,0.10606602,0.053032935 +0.3875,0.5375,0.094494075,0.094494045 +0.3875,0.5375,0.0668174,0.13363487 +0.3875,0.5375,0.13363484,0.06681734 +0.3875,0.5375,0.11905506,0.11905509 +0.3875,0.5375,0.08418465,0.16836932 +0.3875,0.5375,0.1683693,0.08418468 +0.3875,0.5625,0.07500002,0.07500005 +0.3875,0.5625,0.053032994,0.10606599 +0.3875,0.5625,0.10606602,0.053032994 +0.3875,0.5625,0.094494075,0.094494104 +0.3875,0.5625,0.0668174,0.13363484 +0.3875,0.5625,0.13363484,0.0668174 +0.3875,0.5625,0.11905506,0.11905503 +0.3875,0.5625,0.08418465,0.1683693 +0.3875,0.5625,0.1683693,0.08418465 +0.3875,0.5875,0.07500002,0.07499999 +0.3875,0.5875,0.053032994,0.10606605 +0.3875,0.5875,0.10606602,0.053032935 +0.3875,0.5875,0.094494075,0.094494045 +0.3875,0.5875,0.0668174,0.13363487 +0.3875,0.5875,0.13363484,0.06681734 +0.3875,0.5875,0.11905506,0.11905509 +0.3875,0.5875,0.08418465,0.1683693 +0.3875,0.5875,0.1683693,0.08418465 +0.3875,0.61249995,0.07500002,0.07499999 +0.3875,0.61249995,0.053032994,0.10606605 +0.3875,0.6125,0.10606602,0.053032994 +0.3875,0.61249995,0.094494075,0.094494045 +0.3875,0.61249995,0.0668174,0.13363487 +0.3875,0.6125,0.13363484,0.0668174 +0.3875,0.61249995,0.11905506,0.11905509 +0.3875,0.6125,0.08418465,0.1683693 +0.3875,0.6125,0.1683693,0.08418465 +0.3875,0.63750005,0.07500002,0.07499999 +0.3875,0.63750005,0.053032994,0.10606605 +0.3875,0.6375,0.10606602,0.053032994 +0.3875,0.63750005,0.094494075,0.094494045 +0.3875,0.63750005,0.0668174,0.13363487 +0.3875,0.6375,0.13363484,0.0668174 +0.3875,0.63750005,0.11905506,0.11905509 +0.3875,0.6375,0.08418465,0.1683693 +0.3875,0.6375,0.1683693,0.08418465 +0.3875,0.6625,0.07500002,0.07499999 +0.3875,0.6625,0.053032994,0.10606605 +0.3875,0.6625,0.10606602,0.053032935 +0.3875,0.6625,0.094494075,0.094494045 +0.3875,0.6625,0.0668174,0.13363487 +0.3875,0.6625,0.13363484,0.06681734 +0.3875,0.6625,0.11905506,0.11905509 +0.3875,0.6625,0.08418465,0.1683693 +0.3875,0.6625,0.1683693,0.08418465 +0.3875,0.6875,0.07500002,0.07500005 +0.3875,0.6875,0.053032994,0.10606599 +0.3875,0.6875,0.10606602,0.053032994 +0.3875,0.6875,0.094494075,0.094494104 +0.3875,0.6875,0.0668174,0.1336348 +0.3875,0.6875,0.13363484,0.0668174 +0.3875,0.6875,0.11905506,0.11905503 +0.3875,0.6875,0.08418465,0.1683693 +0.3875,0.6875,0.1683693,0.08418465 +0.3875,0.7125,0.07500002,0.07499999 +0.3875,0.7125,0.053032994,0.10606605 +0.3875,0.7125,0.10606602,0.053032935 +0.3875,0.7125,0.094494075,0.094494045 +0.3875,0.7125,0.0668174,0.13363487 +0.3875,0.7125,0.13363484,0.06681734 +0.3875,0.7125,0.11905506,0.11905509 +0.3875,0.7125,0.08418465,0.1683693 +0.3875,0.7125,0.1683693,0.08418465 +0.3875,0.73749995,0.07500002,0.07499999 +0.3875,0.73749995,0.053032994,0.10606605 +0.3875,0.7375,0.10606602,0.053032994 +0.3875,0.73749995,0.094494075,0.094494045 +0.3875,0.73749995,0.0668174,0.1336348 +0.3875,0.7375,0.13363484,0.0668174 +0.3875,0.73749995,0.11905506,0.11905509 +0.3875,0.7375,0.08418465,0.1683693 +0.3875,0.7375,0.1683693,0.08418465 +0.3875,0.76250005,0.07500002,0.07499999 +0.3875,0.7625,0.053032994,0.10606599 +0.3875,0.7625,0.10606602,0.053032994 +0.3875,0.76250005,0.094494075,0.094494045 +0.3875,0.7625,0.0668174,0.1336348 +0.3875,0.7625,0.13363484,0.0668174 +0.3875,0.7625,0.11905506,0.11905503 +0.3875,0.7625,0.08418465,0.1683693 +0.3875,0.7625,0.1683693,0.08418465 +0.3875,0.7875,0.07500002,0.07499999 +0.3875,0.78749996,0.053032994,0.10606599 +0.3875,0.7875,0.10606602,0.053032994 +0.3875,0.7875,0.094494075,0.094494045 +0.3875,0.78749996,0.0668174,0.1336348 +0.3875,0.7875,0.13363484,0.0668174 +0.3875,0.78749996,0.11905506,0.11905503 +0.3875,0.7875,0.08418465,0.1683693 +0.3875,0.7875,0.1683693,0.08418465 +0.3875,0.8125,0.07500002,0.07500005 +0.3875,0.8125,0.053032994,0.10606599 +0.3875,0.8125,0.10606602,0.053033054 +0.3875,0.8125,0.094494075,0.094494104 +0.3875,0.8125,0.0668174,0.1336348 +0.3875,0.8125,0.13363484,0.06681746 +0.3875,0.8125,0.11905506,0.11905503 +0.3875,0.8125,0.08418465,0.1683693 +0.3875,0.8125,0.1683693,0.08418465 +0.3875,0.8375,0.07500002,0.07499999 +0.3875,0.8375,0.053032994,0.10606599 +0.3875,0.8375,0.10606602,0.053033054 +0.3875,0.8375,0.094494075,0.094494045 +0.3875,0.8375,0.0668174,0.1336348 +0.3875,0.8375,0.13363484,0.06681746 +0.3875,0.8375,0.11905506,0.11905503 +0.3875,0.8375,0.08418465,0.1683693 +0.3875,0.8375,0.1683693,0.08418465 +0.3875,0.86249995,0.07500002,0.07499999 +0.3875,0.86249995,0.053032994,0.10606593 +0.3875,0.86249995,0.10606602,0.053033054 +0.3875,0.86249995,0.094494075,0.094494045 +0.3875,0.86249995,0.0668174,0.1336348 +0.3875,0.86249995,0.13363484,0.06681746 +0.3875,0.86249995,0.11905506,0.11905497 +0.3875,0.8625,0.08418465,0.1683693 +0.3875,0.8625,0.1683693,0.08418465 +0.3875,0.88750005,0.07500002,0.07499999 +0.3875,0.88750005,0.053032994,0.10606593 +0.3875,0.88750005,0.10606602,0.053033054 +0.3875,0.88750005,0.094494075,0.094494045 +0.3875,0.88750005,0.0668174,0.13363475 +0.3875,0.88750005,0.13363484,0.06681746 +0.3875,0.88750005,0.11905506,0.11905497 +0.3875,0.8875,0.08418465,0.1683693 +0.3875,0.8875,0.1683693,0.08418465 +0.3875,0.9125,0.07500002,0.07499999 +0.3875,0.9125,0.053032994,0.10606593 +0.3875,0.9125,0.10606602,0.053033054 +0.3875,0.9125,0.094494075,0.094494045 +0.3875,0.9125,0.0668174,0.13363475 +0.3875,0.9125,0.13363484,0.06681746 +0.3875,0.9125,0.11905506,0.11905497 +0.3875,0.9125,0.08418465,0.1683693 +0.3875,0.9125,0.1683693,0.08418465 +0.3875,0.9375,0.07500002,0.07500005 +0.3875,0.9375,0.053032994,0.10606599 +0.3875,0.9375,0.10606602,0.053033113 +0.3875,0.9375,0.094494075,0.094494104 +0.3875,0.9375,0.0668174,0.1336348 +0.3875,0.9375,0.13363484,0.06681752 +0.3875,0.9375,0.11905506,0.11905503 +0.3875,0.9375,0.08418465,0.1683693 +0.3875,0.9375,0.1683693,0.08418465 +0.3875,0.9625,0.07500002,0.07499999 +0.3875,0.9625,0.053032994,0.10606593 +0.3875,0.9625,0.10606602,0.053033054 +0.3875,0.9625,0.094494075,0.094494045 +0.3875,0.9625,0.0668174,0.13363475 +0.3875,0.9625,0.13363484,0.06681746 +0.3875,0.9625,0.11905506,0.11905497 +0.3875,0.9625,0.08418465,0.1683693 +0.3875,0.9625,0.1683693,0.08418465 +0.3875,0.98749995,0.07500002,0.07499999 +0.3875,0.98749995,0.053032994,0.10606593 +0.3875,0.98749995,0.10606602,0.053033054 +0.3875,0.98749995,0.094494075,0.094494045 +0.3875,0.98749995,0.0668174,0.13363475 +0.3875,0.98749995,0.13363484,0.06681746 +0.3875,0.98749995,0.11905506,0.11905497 +0.3875,0.98749995,0.08418465,0.16836923 +0.3875,0.98749995,0.1683693,0.08418459 +0.4125,0.0125,0.07499999,0.075 +0.4125,0.012499997,0.053032994,0.10606602 +0.4125,0.012499999,0.10606605,0.05303301 +0.4125,0.012499999,0.094494045,0.09449408 +0.4125,0.012500001,0.0668174,0.1336348 +0.41250002,0.012499999,0.13363484,0.0668174 +0.4125,0.012500001,0.11905509,0.11905508 +0.4125,0.012499999,0.08418465,0.1683693 +0.4125,0.012500002,0.1683693,0.084184654 +0.4125,0.0375,0.07499999,0.075 +0.4125,0.037499998,0.053032994,0.10606601 +0.4125,0.0375,0.10606605,0.05303301 +0.4125,0.0375,0.094494045,0.094494075 +0.4125,0.0375,0.0668174,0.1336348 +0.41250002,0.0375,0.13363484,0.0668174 +0.4125,0.0375,0.11905509,0.11905508 +0.4125,0.0375,0.08418465,0.16836931 +0.4125,0.0375,0.1683693,0.08418466 +0.4125,0.0625,0.07499999,0.075 +0.4125,0.0625,0.053032994,0.10606602 +0.4125,0.0625,0.10606605,0.05303301 +0.4125,0.0625,0.094494045,0.094494075 +0.4125,0.0625,0.0668174,0.1336348 +0.41250002,0.0625,0.13363484,0.0668174 +0.4125,0.0625,0.11905509,0.11905508 +0.4125,0.0625,0.08418465,0.16836932 +0.4125,0.0625,0.1683693,0.08418465 +0.4125,0.0875,0.07499999,0.075 +0.4125,0.08749999,0.053032994,0.10606601 +0.4125,0.087500006,0.10606605,0.053033013 +0.4125,0.087500006,0.094494045,0.09449408 +0.4125,0.087500006,0.0668174,0.1336348 +0.41250002,0.0875,0.13363484,0.0668174 +0.4125,0.0875,0.11905509,0.11905508 +0.4125,0.0875,0.08418465,0.16836931 +0.4125,0.087500006,0.1683693,0.084184654 +0.4125,0.112500004,0.07499999,0.075 +0.4125,0.1125,0.053032994,0.10606601 +0.4125,0.112500004,0.10606605,0.05303301 +0.4125,0.1125,0.094494045,0.094494075 +0.4125,0.1125,0.0668174,0.1336348 +0.41250002,0.1125,0.13363484,0.0668174 +0.4125,0.1125,0.11905509,0.119055085 +0.4125,0.112500004,0.08418465,0.16836931 +0.4125,0.1125,0.1683693,0.08418465 +0.4125,0.1375,0.07499999,0.074999996 +0.4125,0.1375,0.053032994,0.10606602 +0.4125,0.1375,0.10606605,0.053033024 +0.4125,0.1375,0.094494045,0.09449408 +0.4125,0.1375,0.0668174,0.1336348 +0.41250002,0.1375,0.13363484,0.0668174 +0.4125,0.13749999,0.11905509,0.11905508 +0.4125,0.1375,0.08418465,0.1683693 +0.4125,0.1375,0.1683693,0.084184654 +0.4125,0.1625,0.07499999,0.075 +0.4125,0.16250001,0.053032994,0.106066026 +0.4125,0.1625,0.10606605,0.05303301 +0.4125,0.1625,0.094494045,0.094494075 +0.4125,0.1625,0.0668174,0.1336348 +0.41250002,0.1625,0.13363484,0.0668174 +0.4125,0.1625,0.11905509,0.11905508 +0.4125,0.1625,0.08418465,0.1683693 +0.4125,0.1625,0.1683693,0.08418464 +0.4125,0.1875,0.07499999,0.07499999 +0.4125,0.1875,0.053032994,0.10606603 +0.4125,0.1875,0.10606605,0.053033024 +0.4125,0.1875,0.094494045,0.09449406 +0.4125,0.1875,0.0668174,0.1336348 +0.41250002,0.1875,0.13363484,0.06681742 +0.4125,0.1875,0.11905509,0.11905509 +0.4125,0.1875,0.08418465,0.16836931 +0.4125,0.1875,0.1683693,0.08418465 +0.4125,0.2125,0.07499999,0.075 +0.4125,0.2125,0.053032994,0.10606603 +0.4125,0.2125,0.10606605,0.05303301 +0.4125,0.21249999,0.094494045,0.094494075 +0.4125,0.2125,0.0668174,0.1336348 +0.41250002,0.2125,0.13363484,0.0668174 +0.4125,0.2125,0.11905509,0.11905509 +0.4125,0.2125,0.08418465,0.16836931 +0.4125,0.2125,0.1683693,0.08418465 +0.4125,0.23750001,0.07499999,0.075 +0.4125,0.2375,0.053032994,0.10606602 +0.4125,0.2375,0.10606605,0.053033024 +0.4125,0.2375,0.094494045,0.094494075 +0.4125,0.23750001,0.0668174,0.13363482 +0.41250002,0.2375,0.13363484,0.06681743 +0.4125,0.2375,0.11905509,0.11905506 +0.4125,0.2375,0.08418465,0.16836932 +0.4125,0.23750001,0.1683693,0.08418466 +0.4125,0.2625,0.07499999,0.07500002 +0.4125,0.2625,0.053032994,0.10606603 +0.4125,0.2625,0.10606605,0.053033024 +0.4125,0.2625,0.094494045,0.094494075 +0.4125,0.2625,0.0668174,0.13363479 +0.41250002,0.2625,0.13363484,0.06681743 +0.4125,0.2625,0.11905509,0.11905508 +0.4125,0.2625,0.08418465,0.1683693 +0.4125,0.2625,0.1683693,0.08418463 +0.4125,0.2875,0.07499999,0.07499999 +0.4125,0.2875,0.053032994,0.10606603 +0.4125,0.28750002,0.10606605,0.053033024 +0.4125,0.2875,0.094494045,0.094494045 +0.4125,0.2875,0.0668174,0.1336348 +0.41250002,0.28750002,0.13363484,0.06681743 +0.4125,0.2875,0.11905509,0.11905508 +0.4125,0.2875,0.08418465,0.1683693 +0.4125,0.2875,0.1683693,0.08418465 +0.4125,0.3125,0.07499999,0.07499999 +0.4125,0.3125,0.053032994,0.10606605 +0.4125,0.3125,0.10606605,0.053032994 +0.4125,0.3125,0.094494045,0.094494045 +0.4125,0.3125,0.0668174,0.1336348 +0.41250002,0.3125,0.13363484,0.0668174 +0.4125,0.3125,0.11905509,0.11905509 +0.4125,0.3125,0.08418465,0.1683693 +0.4125,0.3125,0.1683693,0.08418465 +0.4125,0.3375,0.07499999,0.07499999 +0.4125,0.3375,0.053032994,0.10606605 +0.4125,0.33749998,0.10606605,0.053033024 +0.4125,0.3375,0.094494045,0.094494045 +0.4125,0.33750004,0.0668174,0.13363484 +0.41250002,0.33749998,0.13363484,0.06681743 +0.4125,0.3375,0.11905509,0.11905509 +0.4125,0.3375,0.08418465,0.1683693 +0.4125,0.3375,0.1683693,0.08418465 +0.4125,0.3625,0.07499999,0.07500002 +0.4125,0.3625,0.053032994,0.10606602 +0.4125,0.3625,0.10606605,0.053033024 +0.4125,0.3625,0.094494045,0.094494075 +0.4125,0.3625,0.0668174,0.1336348 +0.41250002,0.3625,0.13363484,0.06681743 +0.4125,0.3625,0.11905509,0.11905506 +0.4125,0.3625,0.08418465,0.1683693 +0.4125,0.3625,0.1683693,0.08418465 +0.4125,0.3875,0.07499999,0.07500002 +0.4125,0.3875,0.053032994,0.10606602 +0.4125,0.3875,0.10606605,0.053032994 +0.4125,0.3875,0.094494045,0.094494075 +0.4125,0.3875,0.0668174,0.13363484 +0.41250002,0.3875,0.13363484,0.0668174 +0.4125,0.3875,0.11905509,0.11905506 +0.4125,0.3875,0.08418465,0.1683693 +0.4125,0.3875,0.1683693,0.08418465 +0.4125,0.4125,0.07499999,0.07499999 +0.4125,0.4125,0.053032994,0.10606605 +0.4125,0.4125,0.10606605,0.053032994 +0.4125,0.4125,0.094494045,0.094494045 +0.4125,0.41250002,0.0668174,0.13363484 +0.41250002,0.4125,0.13363484,0.0668174 +0.4125,0.4125,0.11905509,0.11905509 +0.4125,0.4125,0.08418465,0.1683693 +0.4125,0.4125,0.1683693,0.08418465 +0.4125,0.4375,0.07499999,0.07499999 +0.4125,0.4375,0.053032994,0.10606605 +0.4125,0.4375,0.10606605,0.053032994 +0.4125,0.4375,0.094494045,0.094494045 +0.4125,0.4375,0.0668174,0.1336348 +0.41250002,0.4375,0.13363484,0.0668174 +0.4125,0.4375,0.11905509,0.11905509 +0.4125,0.4375,0.08418465,0.1683693 +0.4125,0.4375,0.1683693,0.08418465 +0.4125,0.4625,0.07499999,0.07499999 +0.4125,0.4625,0.053032994,0.10606605 +0.4125,0.46249998,0.10606605,0.053032964 +0.4125,0.4625,0.094494045,0.094494045 +0.4125,0.46250004,0.0668174,0.13363484 +0.41250002,0.46249998,0.13363484,0.06681737 +0.4125,0.4625,0.11905509,0.11905509 +0.4125,0.46249998,0.08418465,0.16836926 +0.4125,0.46249998,0.1683693,0.08418462 +0.4125,0.48749998,0.07499999,0.07499999 +0.4125,0.4875,0.053032994,0.10606602 +0.4125,0.4875,0.10606605,0.053032994 +0.4125,0.48749998,0.094494045,0.094494045 +0.4125,0.4875,0.0668174,0.13363484 +0.41250002,0.4875,0.13363484,0.0668174 +0.4125,0.4875,0.11905509,0.11905506 +0.4125,0.4875,0.08418465,0.1683693 +0.4125,0.4875,0.1683693,0.08418465 +0.4125,0.5125,0.07499999,0.07500002 +0.4125,0.51250005,0.053032994,0.10606605 +0.4125,0.5125,0.10606605,0.053032964 +0.4125,0.5125,0.094494045,0.094494075 +0.4125,0.51250005,0.0668174,0.13363487 +0.41250002,0.5125,0.13363484,0.06681737 +0.4125,0.51250005,0.11905509,0.11905509 +0.4125,0.5125,0.08418465,0.1683693 +0.4125,0.5125,0.1683693,0.08418465 +0.4125,0.5375,0.07499999,0.07499999 +0.4125,0.5375,0.053032994,0.10606605 +0.4125,0.5375,0.10606605,0.053032935 +0.4125,0.5375,0.094494045,0.094494045 +0.4125,0.5375,0.0668174,0.13363487 +0.41250002,0.5375,0.13363484,0.06681734 +0.4125,0.5375,0.11905509,0.11905509 +0.4125,0.5375,0.08418465,0.16836932 +0.4125,0.5375,0.1683693,0.08418468 +0.4125,0.5625,0.07499999,0.07500005 +0.4125,0.5625,0.053032994,0.10606599 +0.4125,0.5625,0.10606605,0.053032994 +0.4125,0.5625,0.094494045,0.094494104 +0.4125,0.5625,0.0668174,0.13363484 +0.41250002,0.5625,0.13363484,0.0668174 +0.4125,0.5625,0.11905509,0.11905503 +0.4125,0.5625,0.08418465,0.1683693 +0.4125,0.5625,0.1683693,0.08418465 +0.4125,0.5875,0.07499999,0.07499999 +0.4125,0.5875,0.053032994,0.10606605 +0.4125,0.5875,0.10606605,0.053032935 +0.4125,0.5875,0.094494045,0.094494045 +0.4125,0.5875,0.0668174,0.13363487 +0.41250002,0.5875,0.13363484,0.06681734 +0.4125,0.5875,0.11905509,0.11905509 +0.4125,0.5875,0.08418465,0.1683693 +0.4125,0.5875,0.1683693,0.08418465 +0.4125,0.61249995,0.07499999,0.07499999 +0.4125,0.61249995,0.053032994,0.10606605 +0.4125,0.6125,0.10606605,0.053032994 +0.4125,0.61249995,0.094494045,0.094494045 +0.4125,0.61249995,0.0668174,0.13363487 +0.41250002,0.6125,0.13363484,0.0668174 +0.4125,0.61249995,0.11905509,0.11905509 +0.4125,0.6125,0.08418465,0.1683693 +0.4125,0.6125,0.1683693,0.08418465 +0.4125,0.63750005,0.07499999,0.07499999 +0.4125,0.63750005,0.053032994,0.10606605 +0.4125,0.6375,0.10606605,0.053032994 +0.4125,0.63750005,0.094494045,0.094494045 +0.4125,0.63750005,0.0668174,0.13363487 +0.41250002,0.6375,0.13363484,0.0668174 +0.4125,0.63750005,0.11905509,0.11905509 +0.4125,0.6375,0.08418465,0.1683693 +0.4125,0.6375,0.1683693,0.08418465 +0.4125,0.6625,0.07499999,0.07499999 +0.4125,0.6625,0.053032994,0.10606605 +0.4125,0.6625,0.10606605,0.053032935 +0.4125,0.6625,0.094494045,0.094494045 +0.4125,0.6625,0.0668174,0.13363487 +0.41250002,0.6625,0.13363484,0.06681734 +0.4125,0.6625,0.11905509,0.11905509 +0.4125,0.6625,0.08418465,0.1683693 +0.4125,0.6625,0.1683693,0.08418465 +0.4125,0.6875,0.07499999,0.07500005 +0.4125,0.6875,0.053032994,0.10606599 +0.4125,0.6875,0.10606605,0.053032994 +0.4125,0.6875,0.094494045,0.094494104 +0.4125,0.6875,0.0668174,0.1336348 +0.41250002,0.6875,0.13363484,0.0668174 +0.4125,0.6875,0.11905509,0.11905503 +0.4125,0.6875,0.08418465,0.1683693 +0.4125,0.6875,0.1683693,0.08418465 +0.4125,0.7125,0.07499999,0.07499999 +0.4125,0.7125,0.053032994,0.10606605 +0.4125,0.7125,0.10606605,0.053032935 +0.4125,0.7125,0.094494045,0.094494045 +0.4125,0.7125,0.0668174,0.13363487 +0.41250002,0.7125,0.13363484,0.06681734 +0.4125,0.7125,0.11905509,0.11905509 +0.4125,0.7125,0.08418465,0.1683693 +0.4125,0.7125,0.1683693,0.08418465 +0.4125,0.73749995,0.07499999,0.07499999 +0.4125,0.73749995,0.053032994,0.10606605 +0.4125,0.7375,0.10606605,0.053032994 +0.4125,0.73749995,0.094494045,0.094494045 +0.4125,0.73749995,0.0668174,0.1336348 +0.41250002,0.7375,0.13363484,0.0668174 +0.4125,0.73749995,0.11905509,0.11905509 +0.4125,0.7375,0.08418465,0.1683693 +0.4125,0.7375,0.1683693,0.08418465 +0.4125,0.76250005,0.07499999,0.07499999 +0.4125,0.7625,0.053032994,0.10606599 +0.4125,0.7625,0.10606605,0.053032994 +0.4125,0.76250005,0.094494045,0.094494045 +0.4125,0.7625,0.0668174,0.1336348 +0.41250002,0.7625,0.13363484,0.0668174 +0.4125,0.7625,0.11905509,0.11905503 +0.4125,0.7625,0.08418465,0.1683693 +0.4125,0.7625,0.1683693,0.08418465 +0.4125,0.7875,0.07499999,0.07499999 +0.4125,0.78749996,0.053032994,0.10606599 +0.4125,0.7875,0.10606605,0.053032994 +0.4125,0.7875,0.094494045,0.094494045 +0.4125,0.78749996,0.0668174,0.1336348 +0.41250002,0.7875,0.13363484,0.0668174 +0.4125,0.78749996,0.11905509,0.11905503 +0.4125,0.7875,0.08418465,0.1683693 +0.4125,0.7875,0.1683693,0.08418465 +0.4125,0.8125,0.07499999,0.07500005 +0.4125,0.8125,0.053032994,0.10606599 +0.4125,0.8125,0.10606605,0.053033054 +0.4125,0.8125,0.094494045,0.094494104 +0.4125,0.8125,0.0668174,0.1336348 +0.41250002,0.8125,0.13363484,0.06681746 +0.4125,0.8125,0.11905509,0.11905503 +0.4125,0.8125,0.08418465,0.1683693 +0.4125,0.8125,0.1683693,0.08418465 +0.4125,0.8375,0.07499999,0.07499999 +0.4125,0.8375,0.053032994,0.10606599 +0.4125,0.8375,0.10606605,0.053033054 +0.4125,0.8375,0.094494045,0.094494045 +0.4125,0.8375,0.0668174,0.1336348 +0.41250002,0.8375,0.13363484,0.06681746 +0.4125,0.8375,0.11905509,0.11905503 +0.4125,0.8375,0.08418465,0.1683693 +0.4125,0.8375,0.1683693,0.08418465 +0.4125,0.86249995,0.07499999,0.07499999 +0.4125,0.86249995,0.053032994,0.10606593 +0.4125,0.86249995,0.10606605,0.053033054 +0.4125,0.86249995,0.094494045,0.094494045 +0.4125,0.86249995,0.0668174,0.1336348 +0.41250002,0.86249995,0.13363484,0.06681746 +0.4125,0.86249995,0.11905509,0.11905497 +0.4125,0.8625,0.08418465,0.1683693 +0.4125,0.8625,0.1683693,0.08418465 +0.4125,0.88750005,0.07499999,0.07499999 +0.4125,0.88750005,0.053032994,0.10606593 +0.4125,0.88750005,0.10606605,0.053033054 +0.4125,0.88750005,0.094494045,0.094494045 +0.4125,0.88750005,0.0668174,0.13363475 +0.41250002,0.88750005,0.13363484,0.06681746 +0.4125,0.88750005,0.11905509,0.11905497 +0.4125,0.8875,0.08418465,0.1683693 +0.4125,0.8875,0.1683693,0.08418465 +0.4125,0.9125,0.07499999,0.07499999 +0.4125,0.9125,0.053032994,0.10606593 +0.4125,0.9125,0.10606605,0.053033054 +0.4125,0.9125,0.094494045,0.094494045 +0.4125,0.9125,0.0668174,0.13363475 +0.41250002,0.9125,0.13363484,0.06681746 +0.4125,0.9125,0.11905509,0.11905497 +0.4125,0.9125,0.08418465,0.1683693 +0.4125,0.9125,0.1683693,0.08418465 +0.4125,0.9375,0.07499999,0.07500005 +0.4125,0.9375,0.053032994,0.10606599 +0.4125,0.9375,0.10606605,0.053033113 +0.4125,0.9375,0.094494045,0.094494104 +0.4125,0.9375,0.0668174,0.1336348 +0.41250002,0.9375,0.13363484,0.06681752 +0.4125,0.9375,0.11905509,0.11905503 +0.4125,0.9375,0.08418465,0.1683693 +0.4125,0.9375,0.1683693,0.08418465 +0.4125,0.9625,0.07499999,0.07499999 +0.4125,0.9625,0.053032994,0.10606593 +0.4125,0.9625,0.10606605,0.053033054 +0.4125,0.9625,0.094494045,0.094494045 +0.4125,0.9625,0.0668174,0.13363475 +0.41250002,0.9625,0.13363484,0.06681746 +0.4125,0.9625,0.11905509,0.11905497 +0.4125,0.9625,0.08418465,0.1683693 +0.4125,0.9625,0.1683693,0.08418465 +0.4125,0.98749995,0.07499999,0.07499999 +0.4125,0.98749995,0.053032994,0.10606593 +0.4125,0.98749995,0.10606605,0.053033054 +0.4125,0.98749995,0.094494045,0.094494045 +0.4125,0.98749995,0.0668174,0.13363475 +0.41250002,0.98749995,0.13363484,0.06681746 +0.4125,0.98749995,0.11905509,0.11905497 +0.4125,0.98749995,0.08418465,0.16836923 +0.4125,0.98749995,0.1683693,0.08418459 +0.4375,0.0125,0.07499999,0.075 +0.4375,0.012499997,0.053032994,0.10606602 +0.4375,0.012499999,0.10606605,0.05303301 +0.4375,0.012499999,0.094494045,0.09449408 +0.4375,0.012500001,0.0668174,0.1336348 +0.4375,0.012499999,0.1336348,0.0668174 +0.4375,0.012500001,0.11905509,0.11905508 +0.4375,0.012499999,0.08418465,0.1683693 +0.4375,0.012500002,0.1683693,0.084184654 +0.4375,0.0375,0.07499999,0.075 +0.4375,0.037499998,0.053032994,0.10606601 +0.4375,0.0375,0.10606605,0.05303301 +0.4375,0.0375,0.094494045,0.094494075 +0.4375,0.0375,0.0668174,0.1336348 +0.4375,0.0375,0.1336348,0.0668174 +0.4375,0.0375,0.11905509,0.11905508 +0.4375,0.0375,0.08418465,0.16836931 +0.4375,0.0375,0.1683693,0.08418466 +0.4375,0.0625,0.07499999,0.075 +0.4375,0.0625,0.053032994,0.10606602 +0.4375,0.0625,0.10606605,0.05303301 +0.4375,0.0625,0.094494045,0.094494075 +0.4375,0.0625,0.0668174,0.1336348 +0.4375,0.0625,0.1336348,0.0668174 +0.4375,0.0625,0.11905509,0.11905508 +0.4375,0.0625,0.08418465,0.16836932 +0.4375,0.0625,0.1683693,0.08418465 +0.4375,0.0875,0.07499999,0.075 +0.4375,0.08749999,0.053032994,0.10606601 +0.4375,0.087500006,0.10606605,0.053033013 +0.4375,0.087500006,0.094494045,0.09449408 +0.4375,0.087500006,0.0668174,0.1336348 +0.4375,0.0875,0.1336348,0.0668174 +0.4375,0.0875,0.11905509,0.11905508 +0.4375,0.0875,0.08418465,0.16836931 +0.4375,0.087500006,0.1683693,0.084184654 +0.4375,0.112500004,0.07499999,0.075 +0.4375,0.1125,0.053032994,0.10606601 +0.4375,0.112500004,0.10606605,0.05303301 +0.4375,0.1125,0.094494045,0.094494075 +0.4375,0.1125,0.0668174,0.1336348 +0.4375,0.1125,0.1336348,0.0668174 +0.4375,0.1125,0.11905509,0.119055085 +0.4375,0.112500004,0.08418465,0.16836931 +0.4375,0.1125,0.1683693,0.08418465 +0.4375,0.1375,0.07499999,0.074999996 +0.4375,0.1375,0.053032994,0.10606602 +0.4375,0.1375,0.10606605,0.053033024 +0.4375,0.1375,0.094494045,0.09449408 +0.4375,0.1375,0.0668174,0.1336348 +0.4375,0.1375,0.1336348,0.0668174 +0.4375,0.13749999,0.11905509,0.11905508 +0.4375,0.1375,0.08418465,0.1683693 +0.4375,0.1375,0.1683693,0.084184654 +0.4375,0.1625,0.07499999,0.075 +0.4375,0.16250001,0.053032994,0.106066026 +0.4375,0.1625,0.10606605,0.05303301 +0.4375,0.1625,0.094494045,0.094494075 +0.4375,0.1625,0.0668174,0.1336348 +0.4375,0.1625,0.1336348,0.0668174 +0.4375,0.1625,0.11905509,0.11905508 +0.4375,0.1625,0.08418465,0.1683693 +0.4375,0.1625,0.1683693,0.08418464 +0.4375,0.1875,0.07499999,0.07499999 +0.4375,0.1875,0.053032994,0.10606603 +0.4375,0.1875,0.10606605,0.053033024 +0.4375,0.1875,0.094494045,0.09449406 +0.4375,0.1875,0.0668174,0.1336348 +0.4375,0.1875,0.1336348,0.06681742 +0.4375,0.1875,0.11905509,0.11905509 +0.4375,0.1875,0.08418465,0.16836931 +0.4375,0.1875,0.1683693,0.08418465 +0.4375,0.2125,0.07499999,0.075 +0.4375,0.2125,0.053032994,0.10606603 +0.4375,0.2125,0.10606605,0.05303301 +0.4375,0.21249999,0.094494045,0.094494075 +0.4375,0.2125,0.0668174,0.1336348 +0.4375,0.2125,0.1336348,0.0668174 +0.4375,0.2125,0.11905509,0.11905509 +0.4375,0.2125,0.08418465,0.16836931 +0.4375,0.2125,0.1683693,0.08418465 +0.4375,0.23750001,0.07499999,0.075 +0.4375,0.2375,0.053032994,0.10606602 +0.4375,0.2375,0.10606605,0.053033024 +0.4375,0.2375,0.094494045,0.094494075 +0.4375,0.23750001,0.0668174,0.13363482 +0.4375,0.2375,0.1336348,0.06681743 +0.4375,0.2375,0.11905509,0.11905506 +0.4375,0.2375,0.08418465,0.16836932 +0.4375,0.23750001,0.1683693,0.08418466 +0.4375,0.2625,0.07499999,0.07500002 +0.4375,0.2625,0.053032994,0.10606603 +0.4375,0.2625,0.10606605,0.053033024 +0.4375,0.2625,0.094494045,0.094494075 +0.4375,0.2625,0.0668174,0.13363479 +0.4375,0.2625,0.1336348,0.06681743 +0.4375,0.2625,0.11905509,0.11905508 +0.4375,0.2625,0.08418465,0.1683693 +0.4375,0.2625,0.1683693,0.08418463 +0.4375,0.2875,0.07499999,0.07499999 +0.4375,0.2875,0.053032994,0.10606603 +0.4375,0.28750002,0.10606605,0.053033024 +0.4375,0.2875,0.094494045,0.094494045 +0.4375,0.2875,0.0668174,0.1336348 +0.4375,0.28750002,0.1336348,0.06681743 +0.4375,0.2875,0.11905509,0.11905508 +0.4375,0.2875,0.08418465,0.1683693 +0.4375,0.2875,0.1683693,0.08418465 +0.4375,0.3125,0.07499999,0.07499999 +0.4375,0.3125,0.053032994,0.10606605 +0.4375,0.3125,0.10606605,0.053032994 +0.4375,0.3125,0.094494045,0.094494045 +0.4375,0.3125,0.0668174,0.1336348 +0.4375,0.3125,0.1336348,0.0668174 +0.4375,0.3125,0.11905509,0.11905509 +0.4375,0.3125,0.08418465,0.1683693 +0.4375,0.3125,0.1683693,0.08418465 +0.4375,0.3375,0.07499999,0.07499999 +0.4375,0.3375,0.053032994,0.10606605 +0.4375,0.33749998,0.10606605,0.053033024 +0.4375,0.3375,0.094494045,0.094494045 +0.4375,0.33750004,0.0668174,0.13363484 +0.4375,0.33749998,0.1336348,0.06681743 +0.4375,0.3375,0.11905509,0.11905509 +0.4375,0.3375,0.08418465,0.1683693 +0.4375,0.3375,0.1683693,0.08418465 +0.4375,0.3625,0.07499999,0.07500002 +0.4375,0.3625,0.053032994,0.10606602 +0.4375,0.3625,0.10606605,0.053033024 +0.4375,0.3625,0.094494045,0.094494075 +0.4375,0.3625,0.0668174,0.1336348 +0.4375,0.3625,0.1336348,0.06681743 +0.4375,0.3625,0.11905509,0.11905506 +0.4375,0.3625,0.08418465,0.1683693 +0.4375,0.3625,0.1683693,0.08418465 +0.4375,0.3875,0.07499999,0.07500002 +0.4375,0.3875,0.053032994,0.10606602 +0.4375,0.3875,0.10606605,0.053032994 +0.4375,0.3875,0.094494045,0.094494075 +0.4375,0.3875,0.0668174,0.13363484 +0.4375,0.3875,0.1336348,0.0668174 +0.4375,0.3875,0.11905509,0.11905506 +0.4375,0.3875,0.08418465,0.1683693 +0.4375,0.3875,0.1683693,0.08418465 +0.4375,0.4125,0.07499999,0.07499999 +0.4375,0.4125,0.053032994,0.10606605 +0.4375,0.4125,0.10606605,0.053032994 +0.4375,0.4125,0.094494045,0.094494045 +0.4375,0.41250002,0.0668174,0.13363484 +0.4375,0.4125,0.1336348,0.0668174 +0.4375,0.4125,0.11905509,0.11905509 +0.4375,0.4125,0.08418465,0.1683693 +0.4375,0.4125,0.1683693,0.08418465 +0.4375,0.4375,0.07499999,0.07499999 +0.4375,0.4375,0.053032994,0.10606605 +0.4375,0.4375,0.10606605,0.053032994 +0.4375,0.4375,0.094494045,0.094494045 +0.4375,0.4375,0.0668174,0.1336348 +0.4375,0.4375,0.1336348,0.0668174 +0.4375,0.4375,0.11905509,0.11905509 +0.4375,0.4375,0.08418465,0.1683693 +0.4375,0.4375,0.1683693,0.08418465 +0.4375,0.4625,0.07499999,0.07499999 +0.4375,0.4625,0.053032994,0.10606605 +0.4375,0.46249998,0.10606605,0.053032964 +0.4375,0.4625,0.094494045,0.094494045 +0.4375,0.46250004,0.0668174,0.13363484 +0.4375,0.46249998,0.1336348,0.06681737 +0.4375,0.4625,0.11905509,0.11905509 +0.4375,0.46249998,0.08418465,0.16836926 +0.4375,0.46249998,0.1683693,0.08418462 +0.4375,0.48749998,0.07499999,0.07499999 +0.4375,0.4875,0.053032994,0.10606602 +0.4375,0.4875,0.10606605,0.053032994 +0.4375,0.48749998,0.094494045,0.094494045 +0.4375,0.4875,0.0668174,0.13363484 +0.4375,0.4875,0.1336348,0.0668174 +0.4375,0.4875,0.11905509,0.11905506 +0.4375,0.4875,0.08418465,0.1683693 +0.4375,0.4875,0.1683693,0.08418465 +0.4375,0.5125,0.07499999,0.07500002 +0.4375,0.51250005,0.053032994,0.10606605 +0.4375,0.5125,0.10606605,0.053032964 +0.4375,0.5125,0.094494045,0.094494075 +0.4375,0.51250005,0.0668174,0.13363487 +0.4375,0.5125,0.1336348,0.06681737 +0.4375,0.51250005,0.11905509,0.11905509 +0.4375,0.5125,0.08418465,0.1683693 +0.4375,0.5125,0.1683693,0.08418465 +0.4375,0.5375,0.07499999,0.07499999 +0.4375,0.5375,0.053032994,0.10606605 +0.4375,0.5375,0.10606605,0.053032935 +0.4375,0.5375,0.094494045,0.094494045 +0.4375,0.5375,0.0668174,0.13363487 +0.4375,0.5375,0.1336348,0.06681734 +0.4375,0.5375,0.11905509,0.11905509 +0.4375,0.5375,0.08418465,0.16836932 +0.4375,0.5375,0.1683693,0.08418468 +0.4375,0.5625,0.07499999,0.07500005 +0.4375,0.5625,0.053032994,0.10606599 +0.4375,0.5625,0.10606605,0.053032994 +0.4375,0.5625,0.094494045,0.094494104 +0.4375,0.5625,0.0668174,0.13363484 +0.4375,0.5625,0.1336348,0.0668174 +0.4375,0.5625,0.11905509,0.11905503 +0.4375,0.5625,0.08418465,0.1683693 +0.4375,0.5625,0.1683693,0.08418465 +0.4375,0.5875,0.07499999,0.07499999 +0.4375,0.5875,0.053032994,0.10606605 +0.4375,0.5875,0.10606605,0.053032935 +0.4375,0.5875,0.094494045,0.094494045 +0.4375,0.5875,0.0668174,0.13363487 +0.4375,0.5875,0.1336348,0.06681734 +0.4375,0.5875,0.11905509,0.11905509 +0.4375,0.5875,0.08418465,0.1683693 +0.4375,0.5875,0.1683693,0.08418465 +0.4375,0.61249995,0.07499999,0.07499999 +0.4375,0.61249995,0.053032994,0.10606605 +0.4375,0.6125,0.10606605,0.053032994 +0.4375,0.61249995,0.094494045,0.094494045 +0.4375,0.61249995,0.0668174,0.13363487 +0.4375,0.6125,0.1336348,0.0668174 +0.4375,0.61249995,0.11905509,0.11905509 +0.4375,0.6125,0.08418465,0.1683693 +0.4375,0.6125,0.1683693,0.08418465 +0.4375,0.63750005,0.07499999,0.07499999 +0.4375,0.63750005,0.053032994,0.10606605 +0.4375,0.6375,0.10606605,0.053032994 +0.4375,0.63750005,0.094494045,0.094494045 +0.4375,0.63750005,0.0668174,0.13363487 +0.4375,0.6375,0.1336348,0.0668174 +0.4375,0.63750005,0.11905509,0.11905509 +0.4375,0.6375,0.08418465,0.1683693 +0.4375,0.6375,0.1683693,0.08418465 +0.4375,0.6625,0.07499999,0.07499999 +0.4375,0.6625,0.053032994,0.10606605 +0.4375,0.6625,0.10606605,0.053032935 +0.4375,0.6625,0.094494045,0.094494045 +0.4375,0.6625,0.0668174,0.13363487 +0.4375,0.6625,0.1336348,0.06681734 +0.4375,0.6625,0.11905509,0.11905509 +0.4375,0.6625,0.08418465,0.1683693 +0.4375,0.6625,0.1683693,0.08418465 +0.4375,0.6875,0.07499999,0.07500005 +0.4375,0.6875,0.053032994,0.10606599 +0.4375,0.6875,0.10606605,0.053032994 +0.4375,0.6875,0.094494045,0.094494104 +0.4375,0.6875,0.0668174,0.1336348 +0.4375,0.6875,0.1336348,0.0668174 +0.4375,0.6875,0.11905509,0.11905503 +0.4375,0.6875,0.08418465,0.1683693 +0.4375,0.6875,0.1683693,0.08418465 +0.4375,0.7125,0.07499999,0.07499999 +0.4375,0.7125,0.053032994,0.10606605 +0.4375,0.7125,0.10606605,0.053032935 +0.4375,0.7125,0.094494045,0.094494045 +0.4375,0.7125,0.0668174,0.13363487 +0.4375,0.7125,0.1336348,0.06681734 +0.4375,0.7125,0.11905509,0.11905509 +0.4375,0.7125,0.08418465,0.1683693 +0.4375,0.7125,0.1683693,0.08418465 +0.4375,0.73749995,0.07499999,0.07499999 +0.4375,0.73749995,0.053032994,0.10606605 +0.4375,0.7375,0.10606605,0.053032994 +0.4375,0.73749995,0.094494045,0.094494045 +0.4375,0.73749995,0.0668174,0.1336348 +0.4375,0.7375,0.1336348,0.0668174 +0.4375,0.73749995,0.11905509,0.11905509 +0.4375,0.7375,0.08418465,0.1683693 +0.4375,0.7375,0.1683693,0.08418465 +0.4375,0.76250005,0.07499999,0.07499999 +0.4375,0.7625,0.053032994,0.10606599 +0.4375,0.7625,0.10606605,0.053032994 +0.4375,0.76250005,0.094494045,0.094494045 +0.4375,0.7625,0.0668174,0.1336348 +0.4375,0.7625,0.1336348,0.0668174 +0.4375,0.7625,0.11905509,0.11905503 +0.4375,0.7625,0.08418465,0.1683693 +0.4375,0.7625,0.1683693,0.08418465 +0.4375,0.7875,0.07499999,0.07499999 +0.4375,0.78749996,0.053032994,0.10606599 +0.4375,0.7875,0.10606605,0.053032994 +0.4375,0.7875,0.094494045,0.094494045 +0.4375,0.78749996,0.0668174,0.1336348 +0.4375,0.7875,0.1336348,0.0668174 +0.4375,0.78749996,0.11905509,0.11905503 +0.4375,0.7875,0.08418465,0.1683693 +0.4375,0.7875,0.1683693,0.08418465 +0.4375,0.8125,0.07499999,0.07500005 +0.4375,0.8125,0.053032994,0.10606599 +0.4375,0.8125,0.10606605,0.053033054 +0.4375,0.8125,0.094494045,0.094494104 +0.4375,0.8125,0.0668174,0.1336348 +0.4375,0.8125,0.1336348,0.06681746 +0.4375,0.8125,0.11905509,0.11905503 +0.4375,0.8125,0.08418465,0.1683693 +0.4375,0.8125,0.1683693,0.08418465 +0.4375,0.8375,0.07499999,0.07499999 +0.4375,0.8375,0.053032994,0.10606599 +0.4375,0.8375,0.10606605,0.053033054 +0.4375,0.8375,0.094494045,0.094494045 +0.4375,0.8375,0.0668174,0.1336348 +0.4375,0.8375,0.1336348,0.06681746 +0.4375,0.8375,0.11905509,0.11905503 +0.4375,0.8375,0.08418465,0.1683693 +0.4375,0.8375,0.1683693,0.08418465 +0.4375,0.86249995,0.07499999,0.07499999 +0.4375,0.86249995,0.053032994,0.10606593 +0.4375,0.86249995,0.10606605,0.053033054 +0.4375,0.86249995,0.094494045,0.094494045 +0.4375,0.86249995,0.0668174,0.1336348 +0.4375,0.86249995,0.1336348,0.06681746 +0.4375,0.86249995,0.11905509,0.11905497 +0.4375,0.8625,0.08418465,0.1683693 +0.4375,0.8625,0.1683693,0.08418465 +0.4375,0.88750005,0.07499999,0.07499999 +0.4375,0.88750005,0.053032994,0.10606593 +0.4375,0.88750005,0.10606605,0.053033054 +0.4375,0.88750005,0.094494045,0.094494045 +0.4375,0.88750005,0.0668174,0.13363475 +0.4375,0.88750005,0.1336348,0.06681746 +0.4375,0.88750005,0.11905509,0.11905497 +0.4375,0.8875,0.08418465,0.1683693 +0.4375,0.8875,0.1683693,0.08418465 +0.4375,0.9125,0.07499999,0.07499999 +0.4375,0.9125,0.053032994,0.10606593 +0.4375,0.9125,0.10606605,0.053033054 +0.4375,0.9125,0.094494045,0.094494045 +0.4375,0.9125,0.0668174,0.13363475 +0.4375,0.9125,0.1336348,0.06681746 +0.4375,0.9125,0.11905509,0.11905497 +0.4375,0.9125,0.08418465,0.1683693 +0.4375,0.9125,0.1683693,0.08418465 +0.4375,0.9375,0.07499999,0.07500005 +0.4375,0.9375,0.053032994,0.10606599 +0.4375,0.9375,0.10606605,0.053033113 +0.4375,0.9375,0.094494045,0.094494104 +0.4375,0.9375,0.0668174,0.1336348 +0.4375,0.9375,0.1336348,0.06681752 +0.4375,0.9375,0.11905509,0.11905503 +0.4375,0.9375,0.08418465,0.1683693 +0.4375,0.9375,0.1683693,0.08418465 +0.4375,0.9625,0.07499999,0.07499999 +0.4375,0.9625,0.053032994,0.10606593 +0.4375,0.9625,0.10606605,0.053033054 +0.4375,0.9625,0.094494045,0.094494045 +0.4375,0.9625,0.0668174,0.13363475 +0.4375,0.9625,0.1336348,0.06681746 +0.4375,0.9625,0.11905509,0.11905497 +0.4375,0.9625,0.08418465,0.1683693 +0.4375,0.9625,0.1683693,0.08418465 +0.4375,0.98749995,0.07499999,0.07499999 +0.4375,0.98749995,0.053032994,0.10606593 +0.4375,0.98749995,0.10606605,0.053033054 +0.4375,0.98749995,0.094494045,0.094494045 +0.4375,0.98749995,0.0668174,0.13363475 +0.4375,0.98749995,0.1336348,0.06681746 +0.4375,0.98749995,0.11905509,0.11905497 +0.4375,0.98749995,0.08418465,0.16836923 +0.4375,0.98749995,0.1683693,0.08418459 +0.4625,0.0125,0.07499999,0.075 +0.46249998,0.012499997,0.053032964,0.10606602 +0.4625,0.012499999,0.10606605,0.05303301 +0.4625,0.012499999,0.094494045,0.09449408 +0.46249998,0.012500001,0.06681737,0.1336348 +0.46250004,0.012499999,0.13363484,0.0668174 +0.4625,0.012500001,0.11905509,0.11905508 +0.46249998,0.012499999,0.08418462,0.1683693 +0.46249998,0.012500002,0.16836926,0.084184654 +0.4625,0.0375,0.07499999,0.075 +0.46249998,0.037499998,0.053032964,0.10606601 +0.4625,0.0375,0.10606605,0.05303301 +0.4625,0.0375,0.094494045,0.094494075 +0.46249998,0.0375,0.06681737,0.1336348 +0.46250004,0.0375,0.13363484,0.0668174 +0.4625,0.0375,0.11905509,0.11905508 +0.46249998,0.0375,0.08418462,0.16836931 +0.46249998,0.0375,0.16836926,0.08418466 +0.4625,0.0625,0.07499999,0.075 +0.46249998,0.0625,0.053032964,0.10606602 +0.4625,0.0625,0.10606605,0.05303301 +0.4625,0.0625,0.094494045,0.094494075 +0.46249998,0.0625,0.06681737,0.1336348 +0.46250004,0.0625,0.13363484,0.0668174 +0.4625,0.0625,0.11905509,0.11905508 +0.46249998,0.0625,0.08418462,0.16836932 +0.46249998,0.0625,0.16836926,0.08418465 +0.4625,0.0875,0.07499999,0.075 +0.46249998,0.08749999,0.053032964,0.10606601 +0.4625,0.087500006,0.10606605,0.053033013 +0.4625,0.087500006,0.094494045,0.09449408 +0.46249998,0.087500006,0.06681737,0.1336348 +0.46250004,0.0875,0.13363484,0.0668174 +0.4625,0.0875,0.11905509,0.11905508 +0.46249998,0.0875,0.08418462,0.16836931 +0.46249998,0.087500006,0.16836926,0.084184654 +0.4625,0.112500004,0.07499999,0.075 +0.46249998,0.1125,0.053032964,0.10606601 +0.4625,0.112500004,0.10606605,0.05303301 +0.4625,0.1125,0.094494045,0.094494075 +0.46249998,0.1125,0.06681737,0.1336348 +0.46250004,0.1125,0.13363484,0.0668174 +0.4625,0.1125,0.11905509,0.119055085 +0.46249998,0.112500004,0.08418462,0.16836931 +0.46249998,0.1125,0.16836926,0.08418465 +0.4625,0.1375,0.07499999,0.074999996 +0.46249998,0.1375,0.053032964,0.10606602 +0.4625,0.1375,0.10606605,0.053033024 +0.4625,0.1375,0.094494045,0.09449408 +0.46249998,0.1375,0.06681737,0.1336348 +0.46250004,0.1375,0.13363484,0.0668174 +0.4625,0.13749999,0.11905509,0.11905508 +0.46249998,0.1375,0.08418462,0.1683693 +0.46249998,0.1375,0.16836926,0.084184654 +0.4625,0.1625,0.07499999,0.075 +0.46249998,0.16250001,0.053032964,0.106066026 +0.4625,0.1625,0.10606605,0.05303301 +0.4625,0.1625,0.094494045,0.094494075 +0.46249998,0.1625,0.06681737,0.1336348 +0.46250004,0.1625,0.13363484,0.0668174 +0.4625,0.1625,0.11905509,0.11905508 +0.46249998,0.1625,0.08418462,0.1683693 +0.46249998,0.1625,0.16836926,0.08418464 +0.4625,0.1875,0.07499999,0.07499999 +0.46249998,0.1875,0.053032964,0.10606603 +0.4625,0.1875,0.10606605,0.053033024 +0.4625,0.1875,0.094494045,0.09449406 +0.46249998,0.1875,0.06681737,0.1336348 +0.46250004,0.1875,0.13363484,0.06681742 +0.4625,0.1875,0.11905509,0.11905509 +0.46249998,0.1875,0.08418462,0.16836931 +0.46249998,0.1875,0.16836926,0.08418465 +0.4625,0.2125,0.07499999,0.075 +0.46249998,0.2125,0.053032964,0.10606603 +0.4625,0.2125,0.10606605,0.05303301 +0.4625,0.21249999,0.094494045,0.094494075 +0.46249998,0.2125,0.06681737,0.1336348 +0.46250004,0.2125,0.13363484,0.0668174 +0.4625,0.2125,0.11905509,0.11905509 +0.46249998,0.2125,0.08418462,0.16836931 +0.46249998,0.2125,0.16836926,0.08418465 +0.4625,0.23750001,0.07499999,0.075 +0.46249998,0.2375,0.053032964,0.10606602 +0.4625,0.2375,0.10606605,0.053033024 +0.4625,0.2375,0.094494045,0.094494075 +0.46249998,0.23750001,0.06681737,0.13363482 +0.46250004,0.2375,0.13363484,0.06681743 +0.4625,0.2375,0.11905509,0.11905506 +0.46249998,0.2375,0.08418462,0.16836932 +0.46249998,0.23750001,0.16836926,0.08418466 +0.4625,0.2625,0.07499999,0.07500002 +0.46249998,0.2625,0.053032964,0.10606603 +0.4625,0.2625,0.10606605,0.053033024 +0.4625,0.2625,0.094494045,0.094494075 +0.46249998,0.2625,0.06681737,0.13363479 +0.46250004,0.2625,0.13363484,0.06681743 +0.4625,0.2625,0.11905509,0.11905508 +0.46249998,0.2625,0.08418462,0.1683693 +0.46249998,0.2625,0.16836926,0.08418463 +0.4625,0.2875,0.07499999,0.07499999 +0.46249998,0.2875,0.053032964,0.10606603 +0.4625,0.28750002,0.10606605,0.053033024 +0.4625,0.2875,0.094494045,0.094494045 +0.46249998,0.2875,0.06681737,0.1336348 +0.46250004,0.28750002,0.13363484,0.06681743 +0.4625,0.2875,0.11905509,0.11905508 +0.46249998,0.2875,0.08418462,0.1683693 +0.46249998,0.2875,0.16836926,0.08418465 +0.4625,0.3125,0.07499999,0.07499999 +0.46249998,0.3125,0.053032964,0.10606605 +0.4625,0.3125,0.10606605,0.053032994 +0.4625,0.3125,0.094494045,0.094494045 +0.46249998,0.3125,0.06681737,0.1336348 +0.46250004,0.3125,0.13363484,0.0668174 +0.4625,0.3125,0.11905509,0.11905509 +0.46249998,0.3125,0.08418462,0.1683693 +0.46249998,0.3125,0.16836926,0.08418465 +0.4625,0.3375,0.07499999,0.07499999 +0.46249998,0.3375,0.053032964,0.10606605 +0.4625,0.33749998,0.10606605,0.053033024 +0.4625,0.3375,0.094494045,0.094494045 +0.46249998,0.33750004,0.06681737,0.13363484 +0.46250004,0.33749998,0.13363484,0.06681743 +0.4625,0.3375,0.11905509,0.11905509 +0.46249998,0.3375,0.08418462,0.1683693 +0.46249998,0.3375,0.16836926,0.08418465 +0.4625,0.3625,0.07499999,0.07500002 +0.46249998,0.3625,0.053032964,0.10606602 +0.4625,0.3625,0.10606605,0.053033024 +0.4625,0.3625,0.094494045,0.094494075 +0.46249998,0.3625,0.06681737,0.1336348 +0.46250004,0.3625,0.13363484,0.06681743 +0.4625,0.3625,0.11905509,0.11905506 +0.46249998,0.3625,0.08418462,0.1683693 +0.46249998,0.3625,0.16836926,0.08418465 +0.4625,0.3875,0.07499999,0.07500002 +0.46249998,0.3875,0.053032964,0.10606602 +0.4625,0.3875,0.10606605,0.053032994 +0.4625,0.3875,0.094494045,0.094494075 +0.46249998,0.3875,0.06681737,0.13363484 +0.46250004,0.3875,0.13363484,0.0668174 +0.4625,0.3875,0.11905509,0.11905506 +0.46249998,0.3875,0.08418462,0.1683693 +0.46249998,0.3875,0.16836926,0.08418465 +0.4625,0.4125,0.07499999,0.07499999 +0.46249998,0.4125,0.053032964,0.10606605 +0.4625,0.4125,0.10606605,0.053032994 +0.4625,0.4125,0.094494045,0.094494045 +0.46249998,0.41250002,0.06681737,0.13363484 +0.46250004,0.4125,0.13363484,0.0668174 +0.4625,0.4125,0.11905509,0.11905509 +0.46249998,0.4125,0.08418462,0.1683693 +0.46249998,0.4125,0.16836926,0.08418465 +0.4625,0.4375,0.07499999,0.07499999 +0.46249998,0.4375,0.053032964,0.10606605 +0.4625,0.4375,0.10606605,0.053032994 +0.4625,0.4375,0.094494045,0.094494045 +0.46249998,0.4375,0.06681737,0.1336348 +0.46250004,0.4375,0.13363484,0.0668174 +0.4625,0.4375,0.11905509,0.11905509 +0.46249998,0.4375,0.08418462,0.1683693 +0.46249998,0.4375,0.16836926,0.08418465 +0.4625,0.4625,0.07499999,0.07499999 +0.46249998,0.4625,0.053032964,0.10606605 +0.4625,0.46249998,0.10606605,0.053032964 +0.4625,0.4625,0.094494045,0.094494045 +0.46249998,0.46250004,0.06681737,0.13363484 +0.46250004,0.46249998,0.13363484,0.06681737 +0.4625,0.4625,0.11905509,0.11905509 +0.46249998,0.46249998,0.08418462,0.16836926 +0.46249998,0.46249998,0.16836926,0.08418462 +0.4625,0.48749998,0.07499999,0.07499999 +0.46249998,0.4875,0.053032964,0.10606602 +0.4625,0.4875,0.10606605,0.053032994 +0.4625,0.48749998,0.094494045,0.094494045 +0.46249998,0.4875,0.06681737,0.13363484 +0.46250004,0.4875,0.13363484,0.0668174 +0.4625,0.4875,0.11905509,0.11905506 +0.46249998,0.4875,0.08418462,0.1683693 +0.46249998,0.4875,0.16836926,0.08418465 +0.4625,0.5125,0.07499999,0.07500002 +0.46249998,0.51250005,0.053032964,0.10606605 +0.4625,0.5125,0.10606605,0.053032964 +0.4625,0.5125,0.094494045,0.094494075 +0.46249998,0.51250005,0.06681737,0.13363487 +0.46250004,0.5125,0.13363484,0.06681737 +0.4625,0.51250005,0.11905509,0.11905509 +0.46249998,0.5125,0.08418462,0.1683693 +0.46249998,0.5125,0.16836926,0.08418465 +0.4625,0.5375,0.07499999,0.07499999 +0.46249998,0.5375,0.053032964,0.10606605 +0.4625,0.5375,0.10606605,0.053032935 +0.4625,0.5375,0.094494045,0.094494045 +0.46249998,0.5375,0.06681737,0.13363487 +0.46250004,0.5375,0.13363484,0.06681734 +0.4625,0.5375,0.11905509,0.11905509 +0.46249998,0.5375,0.08418462,0.16836932 +0.46249998,0.5375,0.16836926,0.08418468 +0.4625,0.5625,0.07499999,0.07500005 +0.46249998,0.5625,0.053032964,0.10606599 +0.4625,0.5625,0.10606605,0.053032994 +0.4625,0.5625,0.094494045,0.094494104 +0.46249998,0.5625,0.06681737,0.13363484 +0.46250004,0.5625,0.13363484,0.0668174 +0.4625,0.5625,0.11905509,0.11905503 +0.46249998,0.5625,0.08418462,0.1683693 +0.46249998,0.5625,0.16836926,0.08418465 +0.4625,0.5875,0.07499999,0.07499999 +0.46249998,0.5875,0.053032964,0.10606605 +0.4625,0.5875,0.10606605,0.053032935 +0.4625,0.5875,0.094494045,0.094494045 +0.46249998,0.5875,0.06681737,0.13363487 +0.46250004,0.5875,0.13363484,0.06681734 +0.4625,0.5875,0.11905509,0.11905509 +0.46249998,0.5875,0.08418462,0.1683693 +0.46249998,0.5875,0.16836926,0.08418465 +0.4625,0.61249995,0.07499999,0.07499999 +0.46249998,0.61249995,0.053032964,0.10606605 +0.4625,0.6125,0.10606605,0.053032994 +0.4625,0.61249995,0.094494045,0.094494045 +0.46249998,0.61249995,0.06681737,0.13363487 +0.46250004,0.6125,0.13363484,0.0668174 +0.4625,0.61249995,0.11905509,0.11905509 +0.46249998,0.6125,0.08418462,0.1683693 +0.46249998,0.6125,0.16836926,0.08418465 +0.4625,0.63750005,0.07499999,0.07499999 +0.46249998,0.63750005,0.053032964,0.10606605 +0.4625,0.6375,0.10606605,0.053032994 +0.4625,0.63750005,0.094494045,0.094494045 +0.46249998,0.63750005,0.06681737,0.13363487 +0.46250004,0.6375,0.13363484,0.0668174 +0.4625,0.63750005,0.11905509,0.11905509 +0.46249998,0.6375,0.08418462,0.1683693 +0.46249998,0.6375,0.16836926,0.08418465 +0.4625,0.6625,0.07499999,0.07499999 +0.46249998,0.6625,0.053032964,0.10606605 +0.4625,0.6625,0.10606605,0.053032935 +0.4625,0.6625,0.094494045,0.094494045 +0.46249998,0.6625,0.06681737,0.13363487 +0.46250004,0.6625,0.13363484,0.06681734 +0.4625,0.6625,0.11905509,0.11905509 +0.46249998,0.6625,0.08418462,0.1683693 +0.46249998,0.6625,0.16836926,0.08418465 +0.4625,0.6875,0.07499999,0.07500005 +0.46249998,0.6875,0.053032964,0.10606599 +0.4625,0.6875,0.10606605,0.053032994 +0.4625,0.6875,0.094494045,0.094494104 +0.46249998,0.6875,0.06681737,0.1336348 +0.46250004,0.6875,0.13363484,0.0668174 +0.4625,0.6875,0.11905509,0.11905503 +0.46249998,0.6875,0.08418462,0.1683693 +0.46249998,0.6875,0.16836926,0.08418465 +0.4625,0.7125,0.07499999,0.07499999 +0.46249998,0.7125,0.053032964,0.10606605 +0.4625,0.7125,0.10606605,0.053032935 +0.4625,0.7125,0.094494045,0.094494045 +0.46249998,0.7125,0.06681737,0.13363487 +0.46250004,0.7125,0.13363484,0.06681734 +0.4625,0.7125,0.11905509,0.11905509 +0.46249998,0.7125,0.08418462,0.1683693 +0.46249998,0.7125,0.16836926,0.08418465 +0.4625,0.73749995,0.07499999,0.07499999 +0.46249998,0.73749995,0.053032964,0.10606605 +0.4625,0.7375,0.10606605,0.053032994 +0.4625,0.73749995,0.094494045,0.094494045 +0.46249998,0.73749995,0.06681737,0.1336348 +0.46250004,0.7375,0.13363484,0.0668174 +0.4625,0.73749995,0.11905509,0.11905509 +0.46249998,0.7375,0.08418462,0.1683693 +0.46249998,0.7375,0.16836926,0.08418465 +0.4625,0.76250005,0.07499999,0.07499999 +0.46249998,0.7625,0.053032964,0.10606599 +0.4625,0.7625,0.10606605,0.053032994 +0.4625,0.76250005,0.094494045,0.094494045 +0.46249998,0.7625,0.06681737,0.1336348 +0.46250004,0.7625,0.13363484,0.0668174 +0.4625,0.7625,0.11905509,0.11905503 +0.46249998,0.7625,0.08418462,0.1683693 +0.46249998,0.7625,0.16836926,0.08418465 +0.4625,0.7875,0.07499999,0.07499999 +0.46249998,0.78749996,0.053032964,0.10606599 +0.4625,0.7875,0.10606605,0.053032994 +0.4625,0.7875,0.094494045,0.094494045 +0.46249998,0.78749996,0.06681737,0.1336348 +0.46250004,0.7875,0.13363484,0.0668174 +0.4625,0.78749996,0.11905509,0.11905503 +0.46249998,0.7875,0.08418462,0.1683693 +0.46249998,0.7875,0.16836926,0.08418465 +0.4625,0.8125,0.07499999,0.07500005 +0.46249998,0.8125,0.053032964,0.10606599 +0.4625,0.8125,0.10606605,0.053033054 +0.4625,0.8125,0.094494045,0.094494104 +0.46249998,0.8125,0.06681737,0.1336348 +0.46250004,0.8125,0.13363484,0.06681746 +0.4625,0.8125,0.11905509,0.11905503 +0.46249998,0.8125,0.08418462,0.1683693 +0.46249998,0.8125,0.16836926,0.08418465 +0.4625,0.8375,0.07499999,0.07499999 +0.46249998,0.8375,0.053032964,0.10606599 +0.4625,0.8375,0.10606605,0.053033054 +0.4625,0.8375,0.094494045,0.094494045 +0.46249998,0.8375,0.06681737,0.1336348 +0.46250004,0.8375,0.13363484,0.06681746 +0.4625,0.8375,0.11905509,0.11905503 +0.46249998,0.8375,0.08418462,0.1683693 +0.46249998,0.8375,0.16836926,0.08418465 +0.4625,0.86249995,0.07499999,0.07499999 +0.46249998,0.86249995,0.053032964,0.10606593 +0.4625,0.86249995,0.10606605,0.053033054 +0.4625,0.86249995,0.094494045,0.094494045 +0.46249998,0.86249995,0.06681737,0.1336348 +0.46250004,0.86249995,0.13363484,0.06681746 +0.4625,0.86249995,0.11905509,0.11905497 +0.46249998,0.8625,0.08418462,0.1683693 +0.46249998,0.8625,0.16836926,0.08418465 +0.4625,0.88750005,0.07499999,0.07499999 +0.46249998,0.88750005,0.053032964,0.10606593 +0.4625,0.88750005,0.10606605,0.053033054 +0.4625,0.88750005,0.094494045,0.094494045 +0.46249998,0.88750005,0.06681737,0.13363475 +0.46250004,0.88750005,0.13363484,0.06681746 +0.4625,0.88750005,0.11905509,0.11905497 +0.46249998,0.8875,0.08418462,0.1683693 +0.46249998,0.8875,0.16836926,0.08418465 +0.4625,0.9125,0.07499999,0.07499999 +0.46249998,0.9125,0.053032964,0.10606593 +0.4625,0.9125,0.10606605,0.053033054 +0.4625,0.9125,0.094494045,0.094494045 +0.46249998,0.9125,0.06681737,0.13363475 +0.46250004,0.9125,0.13363484,0.06681746 +0.4625,0.9125,0.11905509,0.11905497 +0.46249998,0.9125,0.08418462,0.1683693 +0.46249998,0.9125,0.16836926,0.08418465 +0.4625,0.9375,0.07499999,0.07500005 +0.46249998,0.9375,0.053032964,0.10606599 +0.4625,0.9375,0.10606605,0.053033113 +0.4625,0.9375,0.094494045,0.094494104 +0.46249998,0.9375,0.06681737,0.1336348 +0.46250004,0.9375,0.13363484,0.06681752 +0.4625,0.9375,0.11905509,0.11905503 +0.46249998,0.9375,0.08418462,0.1683693 +0.46249998,0.9375,0.16836926,0.08418465 +0.4625,0.9625,0.07499999,0.07499999 +0.46249998,0.9625,0.053032964,0.10606593 +0.4625,0.9625,0.10606605,0.053033054 +0.4625,0.9625,0.094494045,0.094494045 +0.46249998,0.9625,0.06681737,0.13363475 +0.46250004,0.9625,0.13363484,0.06681746 +0.4625,0.9625,0.11905509,0.11905497 +0.46249998,0.9625,0.08418462,0.1683693 +0.46249998,0.9625,0.16836926,0.08418465 +0.4625,0.98749995,0.07499999,0.07499999 +0.46249998,0.98749995,0.053032964,0.10606593 +0.4625,0.98749995,0.10606605,0.053033054 +0.4625,0.98749995,0.094494045,0.094494045 +0.46249998,0.98749995,0.06681737,0.13363475 +0.46250004,0.98749995,0.13363484,0.06681746 +0.4625,0.98749995,0.11905509,0.11905497 +0.46249998,0.98749995,0.08418462,0.16836923 +0.46249998,0.98749995,0.16836926,0.08418459 +0.48749998,0.0125,0.07499999,0.075 +0.4875,0.012499997,0.053032994,0.10606602 +0.4875,0.012499999,0.10606602,0.05303301 +0.48749998,0.012499999,0.094494045,0.09449408 +0.4875,0.012500001,0.0668174,0.1336348 +0.4875,0.012499999,0.13363484,0.0668174 +0.4875,0.012500001,0.11905506,0.11905508 +0.4875,0.012499999,0.08418465,0.1683693 +0.4875,0.012500002,0.1683693,0.084184654 +0.48749998,0.0375,0.07499999,0.075 +0.4875,0.037499998,0.053032994,0.10606601 +0.4875,0.0375,0.10606602,0.05303301 +0.48749998,0.0375,0.094494045,0.094494075 +0.4875,0.0375,0.0668174,0.1336348 +0.4875,0.0375,0.13363484,0.0668174 +0.4875,0.0375,0.11905506,0.11905508 +0.4875,0.0375,0.08418465,0.16836931 +0.4875,0.0375,0.1683693,0.08418466 +0.48749998,0.0625,0.07499999,0.075 +0.4875,0.0625,0.053032994,0.10606602 +0.4875,0.0625,0.10606602,0.05303301 +0.48749998,0.0625,0.094494045,0.094494075 +0.4875,0.0625,0.0668174,0.1336348 +0.4875,0.0625,0.13363484,0.0668174 +0.4875,0.0625,0.11905506,0.11905508 +0.4875,0.0625,0.08418465,0.16836932 +0.4875,0.0625,0.1683693,0.08418465 +0.48749998,0.0875,0.07499999,0.075 +0.4875,0.08749999,0.053032994,0.10606601 +0.4875,0.087500006,0.10606602,0.053033013 +0.48749998,0.087500006,0.094494045,0.09449408 +0.4875,0.087500006,0.0668174,0.1336348 +0.4875,0.0875,0.13363484,0.0668174 +0.4875,0.0875,0.11905506,0.11905508 +0.4875,0.0875,0.08418465,0.16836931 +0.4875,0.087500006,0.1683693,0.084184654 +0.48749998,0.112500004,0.07499999,0.075 +0.4875,0.1125,0.053032994,0.10606601 +0.4875,0.112500004,0.10606602,0.05303301 +0.48749998,0.1125,0.094494045,0.094494075 +0.4875,0.1125,0.0668174,0.1336348 +0.4875,0.1125,0.13363484,0.0668174 +0.4875,0.1125,0.11905506,0.119055085 +0.4875,0.112500004,0.08418465,0.16836931 +0.4875,0.1125,0.1683693,0.08418465 +0.48749998,0.1375,0.07499999,0.074999996 +0.4875,0.1375,0.053032994,0.10606602 +0.4875,0.1375,0.10606602,0.053033024 +0.48749998,0.1375,0.094494045,0.09449408 +0.4875,0.1375,0.0668174,0.1336348 +0.4875,0.1375,0.13363484,0.0668174 +0.4875,0.13749999,0.11905506,0.11905508 +0.4875,0.1375,0.08418465,0.1683693 +0.4875,0.1375,0.1683693,0.084184654 +0.48749998,0.1625,0.07499999,0.075 +0.4875,0.16250001,0.053032994,0.106066026 +0.4875,0.1625,0.10606602,0.05303301 +0.48749998,0.1625,0.094494045,0.094494075 +0.4875,0.1625,0.0668174,0.1336348 +0.4875,0.1625,0.13363484,0.0668174 +0.4875,0.1625,0.11905506,0.11905508 +0.4875,0.1625,0.08418465,0.1683693 +0.4875,0.1625,0.1683693,0.08418464 +0.48749998,0.1875,0.07499999,0.07499999 +0.4875,0.1875,0.053032994,0.10606603 +0.4875,0.1875,0.10606602,0.053033024 +0.48749998,0.1875,0.094494045,0.09449406 +0.4875,0.1875,0.0668174,0.1336348 +0.4875,0.1875,0.13363484,0.06681742 +0.4875,0.1875,0.11905506,0.11905509 +0.4875,0.1875,0.08418465,0.16836931 +0.4875,0.1875,0.1683693,0.08418465 +0.48749998,0.2125,0.07499999,0.075 +0.4875,0.2125,0.053032994,0.10606603 +0.4875,0.2125,0.10606602,0.05303301 +0.48749998,0.21249999,0.094494045,0.094494075 +0.4875,0.2125,0.0668174,0.1336348 +0.4875,0.2125,0.13363484,0.0668174 +0.4875,0.2125,0.11905506,0.11905509 +0.4875,0.2125,0.08418465,0.16836931 +0.4875,0.2125,0.1683693,0.08418465 +0.48749998,0.23750001,0.07499999,0.075 +0.4875,0.2375,0.053032994,0.10606602 +0.4875,0.2375,0.10606602,0.053033024 +0.48749998,0.2375,0.094494045,0.094494075 +0.4875,0.23750001,0.0668174,0.13363482 +0.4875,0.2375,0.13363484,0.06681743 +0.4875,0.2375,0.11905506,0.11905506 +0.4875,0.2375,0.08418465,0.16836932 +0.4875,0.23750001,0.1683693,0.08418466 +0.48749998,0.2625,0.07499999,0.07500002 +0.4875,0.2625,0.053032994,0.10606603 +0.4875,0.2625,0.10606602,0.053033024 +0.48749998,0.2625,0.094494045,0.094494075 +0.4875,0.2625,0.0668174,0.13363479 +0.4875,0.2625,0.13363484,0.06681743 +0.4875,0.2625,0.11905506,0.11905508 +0.4875,0.2625,0.08418465,0.1683693 +0.4875,0.2625,0.1683693,0.08418463 +0.48749998,0.2875,0.07499999,0.07499999 +0.4875,0.2875,0.053032994,0.10606603 +0.4875,0.28750002,0.10606602,0.053033024 +0.48749998,0.2875,0.094494045,0.094494045 +0.4875,0.2875,0.0668174,0.1336348 +0.4875,0.28750002,0.13363484,0.06681743 +0.4875,0.2875,0.11905506,0.11905508 +0.4875,0.2875,0.08418465,0.1683693 +0.4875,0.2875,0.1683693,0.08418465 +0.48749998,0.3125,0.07499999,0.07499999 +0.4875,0.3125,0.053032994,0.10606605 +0.4875,0.3125,0.10606602,0.053032994 +0.48749998,0.3125,0.094494045,0.094494045 +0.4875,0.3125,0.0668174,0.1336348 +0.4875,0.3125,0.13363484,0.0668174 +0.4875,0.3125,0.11905506,0.11905509 +0.4875,0.3125,0.08418465,0.1683693 +0.4875,0.3125,0.1683693,0.08418465 +0.48749998,0.3375,0.07499999,0.07499999 +0.4875,0.3375,0.053032994,0.10606605 +0.4875,0.33749998,0.10606602,0.053033024 +0.48749998,0.3375,0.094494045,0.094494045 +0.4875,0.33750004,0.0668174,0.13363484 +0.4875,0.33749998,0.13363484,0.06681743 +0.4875,0.3375,0.11905506,0.11905509 +0.4875,0.3375,0.08418465,0.1683693 +0.4875,0.3375,0.1683693,0.08418465 +0.48749998,0.3625,0.07499999,0.07500002 +0.4875,0.3625,0.053032994,0.10606602 +0.4875,0.3625,0.10606602,0.053033024 +0.48749998,0.3625,0.094494045,0.094494075 +0.4875,0.3625,0.0668174,0.1336348 +0.4875,0.3625,0.13363484,0.06681743 +0.4875,0.3625,0.11905506,0.11905506 +0.4875,0.3625,0.08418465,0.1683693 +0.4875,0.3625,0.1683693,0.08418465 +0.48749998,0.3875,0.07499999,0.07500002 +0.4875,0.3875,0.053032994,0.10606602 +0.4875,0.3875,0.10606602,0.053032994 +0.48749998,0.3875,0.094494045,0.094494075 +0.4875,0.3875,0.0668174,0.13363484 +0.4875,0.3875,0.13363484,0.0668174 +0.4875,0.3875,0.11905506,0.11905506 +0.4875,0.3875,0.08418465,0.1683693 +0.4875,0.3875,0.1683693,0.08418465 +0.48749998,0.4125,0.07499999,0.07499999 +0.4875,0.4125,0.053032994,0.10606605 +0.4875,0.4125,0.10606602,0.053032994 +0.48749998,0.4125,0.094494045,0.094494045 +0.4875,0.41250002,0.0668174,0.13363484 +0.4875,0.4125,0.13363484,0.0668174 +0.4875,0.4125,0.11905506,0.11905509 +0.4875,0.4125,0.08418465,0.1683693 +0.4875,0.4125,0.1683693,0.08418465 +0.48749998,0.4375,0.07499999,0.07499999 +0.4875,0.4375,0.053032994,0.10606605 +0.4875,0.4375,0.10606602,0.053032994 +0.48749998,0.4375,0.094494045,0.094494045 +0.4875,0.4375,0.0668174,0.1336348 +0.4875,0.4375,0.13363484,0.0668174 +0.4875,0.4375,0.11905506,0.11905509 +0.4875,0.4375,0.08418465,0.1683693 +0.4875,0.4375,0.1683693,0.08418465 +0.48749998,0.4625,0.07499999,0.07499999 +0.4875,0.4625,0.053032994,0.10606605 +0.4875,0.46249998,0.10606602,0.053032964 +0.48749998,0.4625,0.094494045,0.094494045 +0.4875,0.46250004,0.0668174,0.13363484 +0.4875,0.46249998,0.13363484,0.06681737 +0.4875,0.4625,0.11905506,0.11905509 +0.4875,0.46249998,0.08418465,0.16836926 +0.4875,0.46249998,0.1683693,0.08418462 +0.48749998,0.48749998,0.07499999,0.07499999 +0.4875,0.4875,0.053032994,0.10606602 +0.4875,0.4875,0.10606602,0.053032994 +0.48749998,0.48749998,0.094494045,0.094494045 +0.4875,0.4875,0.0668174,0.13363484 +0.4875,0.4875,0.13363484,0.0668174 +0.4875,0.4875,0.11905506,0.11905506 +0.4875,0.4875,0.08418465,0.1683693 +0.4875,0.4875,0.1683693,0.08418465 +0.48749998,0.5125,0.07499999,0.07500002 +0.4875,0.51250005,0.053032994,0.10606605 +0.4875,0.5125,0.10606602,0.053032964 +0.48749998,0.5125,0.094494045,0.094494075 +0.4875,0.51250005,0.0668174,0.13363487 +0.4875,0.5125,0.13363484,0.06681737 +0.4875,0.51250005,0.11905506,0.11905509 +0.4875,0.5125,0.08418465,0.1683693 +0.4875,0.5125,0.1683693,0.08418465 +0.48749998,0.5375,0.07499999,0.07499999 +0.4875,0.5375,0.053032994,0.10606605 +0.4875,0.5375,0.10606602,0.053032935 +0.48749998,0.5375,0.094494045,0.094494045 +0.4875,0.5375,0.0668174,0.13363487 +0.4875,0.5375,0.13363484,0.06681734 +0.4875,0.5375,0.11905506,0.11905509 +0.4875,0.5375,0.08418465,0.16836932 +0.4875,0.5375,0.1683693,0.08418468 +0.48749998,0.5625,0.07499999,0.07500005 +0.4875,0.5625,0.053032994,0.10606599 +0.4875,0.5625,0.10606602,0.053032994 +0.48749998,0.5625,0.094494045,0.094494104 +0.4875,0.5625,0.0668174,0.13363484 +0.4875,0.5625,0.13363484,0.0668174 +0.4875,0.5625,0.11905506,0.11905503 +0.4875,0.5625,0.08418465,0.1683693 +0.4875,0.5625,0.1683693,0.08418465 +0.48749998,0.5875,0.07499999,0.07499999 +0.4875,0.5875,0.053032994,0.10606605 +0.4875,0.5875,0.10606602,0.053032935 +0.48749998,0.5875,0.094494045,0.094494045 +0.4875,0.5875,0.0668174,0.13363487 +0.4875,0.5875,0.13363484,0.06681734 +0.4875,0.5875,0.11905506,0.11905509 +0.4875,0.5875,0.08418465,0.1683693 +0.4875,0.5875,0.1683693,0.08418465 +0.48749998,0.61249995,0.07499999,0.07499999 +0.4875,0.61249995,0.053032994,0.10606605 +0.4875,0.6125,0.10606602,0.053032994 +0.48749998,0.61249995,0.094494045,0.094494045 +0.4875,0.61249995,0.0668174,0.13363487 +0.4875,0.6125,0.13363484,0.0668174 +0.4875,0.61249995,0.11905506,0.11905509 +0.4875,0.6125,0.08418465,0.1683693 +0.4875,0.6125,0.1683693,0.08418465 +0.48749998,0.63750005,0.07499999,0.07499999 +0.4875,0.63750005,0.053032994,0.10606605 +0.4875,0.6375,0.10606602,0.053032994 +0.48749998,0.63750005,0.094494045,0.094494045 +0.4875,0.63750005,0.0668174,0.13363487 +0.4875,0.6375,0.13363484,0.0668174 +0.4875,0.63750005,0.11905506,0.11905509 +0.4875,0.6375,0.08418465,0.1683693 +0.4875,0.6375,0.1683693,0.08418465 +0.48749998,0.6625,0.07499999,0.07499999 +0.4875,0.6625,0.053032994,0.10606605 +0.4875,0.6625,0.10606602,0.053032935 +0.48749998,0.6625,0.094494045,0.094494045 +0.4875,0.6625,0.0668174,0.13363487 +0.4875,0.6625,0.13363484,0.06681734 +0.4875,0.6625,0.11905506,0.11905509 +0.4875,0.6625,0.08418465,0.1683693 +0.4875,0.6625,0.1683693,0.08418465 +0.48749998,0.6875,0.07499999,0.07500005 +0.4875,0.6875,0.053032994,0.10606599 +0.4875,0.6875,0.10606602,0.053032994 +0.48749998,0.6875,0.094494045,0.094494104 +0.4875,0.6875,0.0668174,0.1336348 +0.4875,0.6875,0.13363484,0.0668174 +0.4875,0.6875,0.11905506,0.11905503 +0.4875,0.6875,0.08418465,0.1683693 +0.4875,0.6875,0.1683693,0.08418465 +0.48749998,0.7125,0.07499999,0.07499999 +0.4875,0.7125,0.053032994,0.10606605 +0.4875,0.7125,0.10606602,0.053032935 +0.48749998,0.7125,0.094494045,0.094494045 +0.4875,0.7125,0.0668174,0.13363487 +0.4875,0.7125,0.13363484,0.06681734 +0.4875,0.7125,0.11905506,0.11905509 +0.4875,0.7125,0.08418465,0.1683693 +0.4875,0.7125,0.1683693,0.08418465 +0.48749998,0.73749995,0.07499999,0.07499999 +0.4875,0.73749995,0.053032994,0.10606605 +0.4875,0.7375,0.10606602,0.053032994 +0.48749998,0.73749995,0.094494045,0.094494045 +0.4875,0.73749995,0.0668174,0.1336348 +0.4875,0.7375,0.13363484,0.0668174 +0.4875,0.73749995,0.11905506,0.11905509 +0.4875,0.7375,0.08418465,0.1683693 +0.4875,0.7375,0.1683693,0.08418465 +0.48749998,0.76250005,0.07499999,0.07499999 +0.4875,0.7625,0.053032994,0.10606599 +0.4875,0.7625,0.10606602,0.053032994 +0.48749998,0.76250005,0.094494045,0.094494045 +0.4875,0.7625,0.0668174,0.1336348 +0.4875,0.7625,0.13363484,0.0668174 +0.4875,0.7625,0.11905506,0.11905503 +0.4875,0.7625,0.08418465,0.1683693 +0.4875,0.7625,0.1683693,0.08418465 +0.48749998,0.7875,0.07499999,0.07499999 +0.4875,0.78749996,0.053032994,0.10606599 +0.4875,0.7875,0.10606602,0.053032994 +0.48749998,0.7875,0.094494045,0.094494045 +0.4875,0.78749996,0.0668174,0.1336348 +0.4875,0.7875,0.13363484,0.0668174 +0.4875,0.78749996,0.11905506,0.11905503 +0.4875,0.7875,0.08418465,0.1683693 +0.4875,0.7875,0.1683693,0.08418465 +0.48749998,0.8125,0.07499999,0.07500005 +0.4875,0.8125,0.053032994,0.10606599 +0.4875,0.8125,0.10606602,0.053033054 +0.48749998,0.8125,0.094494045,0.094494104 +0.4875,0.8125,0.0668174,0.1336348 +0.4875,0.8125,0.13363484,0.06681746 +0.4875,0.8125,0.11905506,0.11905503 +0.4875,0.8125,0.08418465,0.1683693 +0.4875,0.8125,0.1683693,0.08418465 +0.48749998,0.8375,0.07499999,0.07499999 +0.4875,0.8375,0.053032994,0.10606599 +0.4875,0.8375,0.10606602,0.053033054 +0.48749998,0.8375,0.094494045,0.094494045 +0.4875,0.8375,0.0668174,0.1336348 +0.4875,0.8375,0.13363484,0.06681746 +0.4875,0.8375,0.11905506,0.11905503 +0.4875,0.8375,0.08418465,0.1683693 +0.4875,0.8375,0.1683693,0.08418465 +0.48749998,0.86249995,0.07499999,0.07499999 +0.4875,0.86249995,0.053032994,0.10606593 +0.4875,0.86249995,0.10606602,0.053033054 +0.48749998,0.86249995,0.094494045,0.094494045 +0.4875,0.86249995,0.0668174,0.1336348 +0.4875,0.86249995,0.13363484,0.06681746 +0.4875,0.86249995,0.11905506,0.11905497 +0.4875,0.8625,0.08418465,0.1683693 +0.4875,0.8625,0.1683693,0.08418465 +0.48749998,0.88750005,0.07499999,0.07499999 +0.4875,0.88750005,0.053032994,0.10606593 +0.4875,0.88750005,0.10606602,0.053033054 +0.48749998,0.88750005,0.094494045,0.094494045 +0.4875,0.88750005,0.0668174,0.13363475 +0.4875,0.88750005,0.13363484,0.06681746 +0.4875,0.88750005,0.11905506,0.11905497 +0.4875,0.8875,0.08418465,0.1683693 +0.4875,0.8875,0.1683693,0.08418465 +0.48749998,0.9125,0.07499999,0.07499999 +0.4875,0.9125,0.053032994,0.10606593 +0.4875,0.9125,0.10606602,0.053033054 +0.48749998,0.9125,0.094494045,0.094494045 +0.4875,0.9125,0.0668174,0.13363475 +0.4875,0.9125,0.13363484,0.06681746 +0.4875,0.9125,0.11905506,0.11905497 +0.4875,0.9125,0.08418465,0.1683693 +0.4875,0.9125,0.1683693,0.08418465 +0.48749998,0.9375,0.07499999,0.07500005 +0.4875,0.9375,0.053032994,0.10606599 +0.4875,0.9375,0.10606602,0.053033113 +0.48749998,0.9375,0.094494045,0.094494104 +0.4875,0.9375,0.0668174,0.1336348 +0.4875,0.9375,0.13363484,0.06681752 +0.4875,0.9375,0.11905506,0.11905503 +0.4875,0.9375,0.08418465,0.1683693 +0.4875,0.9375,0.1683693,0.08418465 +0.48749998,0.9625,0.07499999,0.07499999 +0.4875,0.9625,0.053032994,0.10606593 +0.4875,0.9625,0.10606602,0.053033054 +0.48749998,0.9625,0.094494045,0.094494045 +0.4875,0.9625,0.0668174,0.13363475 +0.4875,0.9625,0.13363484,0.06681746 +0.4875,0.9625,0.11905506,0.11905497 +0.4875,0.9625,0.08418465,0.1683693 +0.4875,0.9625,0.1683693,0.08418465 +0.48749998,0.98749995,0.07499999,0.07499999 +0.4875,0.98749995,0.053032994,0.10606593 +0.4875,0.98749995,0.10606602,0.053033054 +0.48749998,0.98749995,0.094494045,0.094494045 +0.4875,0.98749995,0.0668174,0.13363475 +0.4875,0.98749995,0.13363484,0.06681746 +0.4875,0.98749995,0.11905506,0.11905497 +0.4875,0.98749995,0.08418465,0.16836923 +0.4875,0.98749995,0.1683693,0.08418459 +0.5125,0.0125,0.07500002,0.075 +0.5125,0.012499997,0.053032964,0.10606602 +0.51250005,0.012499999,0.10606605,0.05303301 +0.5125,0.012499999,0.094494075,0.09449408 +0.5125,0.012500001,0.06681737,0.1336348 +0.51250005,0.012499999,0.13363487,0.0668174 +0.51250005,0.012500001,0.11905509,0.11905508 +0.5125,0.012499999,0.08418465,0.1683693 +0.5125,0.012500002,0.1683693,0.084184654 +0.5125,0.0375,0.07500002,0.075 +0.5125,0.037499998,0.053032964,0.10606601 +0.51250005,0.0375,0.10606605,0.05303301 +0.5125,0.0375,0.094494075,0.094494075 +0.5125,0.0375,0.06681737,0.1336348 +0.51250005,0.0375,0.13363487,0.0668174 +0.51250005,0.0375,0.11905509,0.11905508 +0.5125,0.0375,0.08418465,0.16836931 +0.5125,0.0375,0.1683693,0.08418466 +0.5125,0.0625,0.07500002,0.075 +0.5125,0.0625,0.053032964,0.10606602 +0.51250005,0.0625,0.10606605,0.05303301 +0.5125,0.0625,0.094494075,0.094494075 +0.5125,0.0625,0.06681737,0.1336348 +0.51250005,0.0625,0.13363487,0.0668174 +0.51250005,0.0625,0.11905509,0.11905508 +0.5125,0.0625,0.08418465,0.16836932 +0.5125,0.0625,0.1683693,0.08418465 +0.5125,0.0875,0.07500002,0.075 +0.5125,0.08749999,0.053032964,0.10606601 +0.51250005,0.087500006,0.10606605,0.053033013 +0.5125,0.087500006,0.094494075,0.09449408 +0.5125,0.087500006,0.06681737,0.1336348 +0.51250005,0.0875,0.13363487,0.0668174 +0.51250005,0.0875,0.11905509,0.11905508 +0.5125,0.0875,0.08418465,0.16836931 +0.5125,0.087500006,0.1683693,0.084184654 +0.5125,0.112500004,0.07500002,0.075 +0.5125,0.1125,0.053032964,0.10606601 +0.51250005,0.112500004,0.10606605,0.05303301 +0.5125,0.1125,0.094494075,0.094494075 +0.5125,0.1125,0.06681737,0.1336348 +0.51250005,0.1125,0.13363487,0.0668174 +0.51250005,0.1125,0.11905509,0.119055085 +0.5125,0.112500004,0.08418465,0.16836931 +0.5125,0.1125,0.1683693,0.08418465 +0.5125,0.1375,0.07500002,0.074999996 +0.5125,0.1375,0.053032964,0.10606602 +0.51250005,0.1375,0.10606605,0.053033024 +0.5125,0.1375,0.094494075,0.09449408 +0.5125,0.1375,0.06681737,0.1336348 +0.51250005,0.1375,0.13363487,0.0668174 +0.51250005,0.13749999,0.11905509,0.11905508 +0.5125,0.1375,0.08418465,0.1683693 +0.5125,0.1375,0.1683693,0.084184654 +0.5125,0.1625,0.07500002,0.075 +0.5125,0.16250001,0.053032964,0.106066026 +0.51250005,0.1625,0.10606605,0.05303301 +0.5125,0.1625,0.094494075,0.094494075 +0.5125,0.1625,0.06681737,0.1336348 +0.51250005,0.1625,0.13363487,0.0668174 +0.51250005,0.1625,0.11905509,0.11905508 +0.5125,0.1625,0.08418465,0.1683693 +0.5125,0.1625,0.1683693,0.08418464 +0.5125,0.1875,0.07500002,0.07499999 +0.5125,0.1875,0.053032964,0.10606603 +0.51250005,0.1875,0.10606605,0.053033024 +0.5125,0.1875,0.094494075,0.09449406 +0.5125,0.1875,0.06681737,0.1336348 +0.51250005,0.1875,0.13363487,0.06681742 +0.51250005,0.1875,0.11905509,0.11905509 +0.5125,0.1875,0.08418465,0.16836931 +0.5125,0.1875,0.1683693,0.08418465 +0.5125,0.2125,0.07500002,0.075 +0.5125,0.2125,0.053032964,0.10606603 +0.51250005,0.2125,0.10606605,0.05303301 +0.5125,0.21249999,0.094494075,0.094494075 +0.5125,0.2125,0.06681737,0.1336348 +0.51250005,0.2125,0.13363487,0.0668174 +0.51250005,0.2125,0.11905509,0.11905509 +0.5125,0.2125,0.08418465,0.16836931 +0.5125,0.2125,0.1683693,0.08418465 +0.5125,0.23750001,0.07500002,0.075 +0.5125,0.2375,0.053032964,0.10606602 +0.51250005,0.2375,0.10606605,0.053033024 +0.5125,0.2375,0.094494075,0.094494075 +0.5125,0.23750001,0.06681737,0.13363482 +0.51250005,0.2375,0.13363487,0.06681743 +0.51250005,0.2375,0.11905509,0.11905506 +0.5125,0.2375,0.08418465,0.16836932 +0.5125,0.23750001,0.1683693,0.08418466 +0.5125,0.2625,0.07500002,0.07500002 +0.5125,0.2625,0.053032964,0.10606603 +0.51250005,0.2625,0.10606605,0.053033024 +0.5125,0.2625,0.094494075,0.094494075 +0.5125,0.2625,0.06681737,0.13363479 +0.51250005,0.2625,0.13363487,0.06681743 +0.51250005,0.2625,0.11905509,0.11905508 +0.5125,0.2625,0.08418465,0.1683693 +0.5125,0.2625,0.1683693,0.08418463 +0.5125,0.2875,0.07500002,0.07499999 +0.5125,0.2875,0.053032964,0.10606603 +0.51250005,0.28750002,0.10606605,0.053033024 +0.5125,0.2875,0.094494075,0.094494045 +0.5125,0.2875,0.06681737,0.1336348 +0.51250005,0.28750002,0.13363487,0.06681743 +0.51250005,0.2875,0.11905509,0.11905508 +0.5125,0.2875,0.08418465,0.1683693 +0.5125,0.2875,0.1683693,0.08418465 +0.5125,0.3125,0.07500002,0.07499999 +0.5125,0.3125,0.053032964,0.10606605 +0.51250005,0.3125,0.10606605,0.053032994 +0.5125,0.3125,0.094494075,0.094494045 +0.5125,0.3125,0.06681737,0.1336348 +0.51250005,0.3125,0.13363487,0.0668174 +0.51250005,0.3125,0.11905509,0.11905509 +0.5125,0.3125,0.08418465,0.1683693 +0.5125,0.3125,0.1683693,0.08418465 +0.5125,0.3375,0.07500002,0.07499999 +0.5125,0.3375,0.053032964,0.10606605 +0.51250005,0.33749998,0.10606605,0.053033024 +0.5125,0.3375,0.094494075,0.094494045 +0.5125,0.33750004,0.06681737,0.13363484 +0.51250005,0.33749998,0.13363487,0.06681743 +0.51250005,0.3375,0.11905509,0.11905509 +0.5125,0.3375,0.08418465,0.1683693 +0.5125,0.3375,0.1683693,0.08418465 +0.5125,0.3625,0.07500002,0.07500002 +0.5125,0.3625,0.053032964,0.10606602 +0.51250005,0.3625,0.10606605,0.053033024 +0.5125,0.3625,0.094494075,0.094494075 +0.5125,0.3625,0.06681737,0.1336348 +0.51250005,0.3625,0.13363487,0.06681743 +0.51250005,0.3625,0.11905509,0.11905506 +0.5125,0.3625,0.08418465,0.1683693 +0.5125,0.3625,0.1683693,0.08418465 +0.5125,0.3875,0.07500002,0.07500002 +0.5125,0.3875,0.053032964,0.10606602 +0.51250005,0.3875,0.10606605,0.053032994 +0.5125,0.3875,0.094494075,0.094494075 +0.5125,0.3875,0.06681737,0.13363484 +0.51250005,0.3875,0.13363487,0.0668174 +0.51250005,0.3875,0.11905509,0.11905506 +0.5125,0.3875,0.08418465,0.1683693 +0.5125,0.3875,0.1683693,0.08418465 +0.5125,0.4125,0.07500002,0.07499999 +0.5125,0.4125,0.053032964,0.10606605 +0.51250005,0.4125,0.10606605,0.053032994 +0.5125,0.4125,0.094494075,0.094494045 +0.5125,0.41250002,0.06681737,0.13363484 +0.51250005,0.4125,0.13363487,0.0668174 +0.51250005,0.4125,0.11905509,0.11905509 +0.5125,0.4125,0.08418465,0.1683693 +0.5125,0.4125,0.1683693,0.08418465 +0.5125,0.4375,0.07500002,0.07499999 +0.5125,0.4375,0.053032964,0.10606605 +0.51250005,0.4375,0.10606605,0.053032994 +0.5125,0.4375,0.094494075,0.094494045 +0.5125,0.4375,0.06681737,0.1336348 +0.51250005,0.4375,0.13363487,0.0668174 +0.51250005,0.4375,0.11905509,0.11905509 +0.5125,0.4375,0.08418465,0.1683693 +0.5125,0.4375,0.1683693,0.08418465 +0.5125,0.4625,0.07500002,0.07499999 +0.5125,0.4625,0.053032964,0.10606605 +0.51250005,0.46249998,0.10606605,0.053032964 +0.5125,0.4625,0.094494075,0.094494045 +0.5125,0.46250004,0.06681737,0.13363484 +0.51250005,0.46249998,0.13363487,0.06681737 +0.51250005,0.4625,0.11905509,0.11905509 +0.5125,0.46249998,0.08418465,0.16836926 +0.5125,0.46249998,0.1683693,0.08418462 +0.5125,0.48749998,0.07500002,0.07499999 +0.5125,0.4875,0.053032964,0.10606602 +0.51250005,0.4875,0.10606605,0.053032994 +0.5125,0.48749998,0.094494075,0.094494045 +0.5125,0.4875,0.06681737,0.13363484 +0.51250005,0.4875,0.13363487,0.0668174 +0.51250005,0.4875,0.11905509,0.11905506 +0.5125,0.4875,0.08418465,0.1683693 +0.5125,0.4875,0.1683693,0.08418465 +0.5125,0.5125,0.07500002,0.07500002 +0.5125,0.51250005,0.053032964,0.10606605 +0.51250005,0.5125,0.10606605,0.053032964 +0.5125,0.5125,0.094494075,0.094494075 +0.5125,0.51250005,0.06681737,0.13363487 +0.51250005,0.5125,0.13363487,0.06681737 +0.51250005,0.51250005,0.11905509,0.11905509 +0.5125,0.5125,0.08418465,0.1683693 +0.5125,0.5125,0.1683693,0.08418465 +0.5125,0.5375,0.07500002,0.07499999 +0.5125,0.5375,0.053032964,0.10606605 +0.51250005,0.5375,0.10606605,0.053032935 +0.5125,0.5375,0.094494075,0.094494045 +0.5125,0.5375,0.06681737,0.13363487 +0.51250005,0.5375,0.13363487,0.06681734 +0.51250005,0.5375,0.11905509,0.11905509 +0.5125,0.5375,0.08418465,0.16836932 +0.5125,0.5375,0.1683693,0.08418468 +0.5125,0.5625,0.07500002,0.07500005 +0.5125,0.5625,0.053032964,0.10606599 +0.51250005,0.5625,0.10606605,0.053032994 +0.5125,0.5625,0.094494075,0.094494104 +0.5125,0.5625,0.06681737,0.13363484 +0.51250005,0.5625,0.13363487,0.0668174 +0.51250005,0.5625,0.11905509,0.11905503 +0.5125,0.5625,0.08418465,0.1683693 +0.5125,0.5625,0.1683693,0.08418465 +0.5125,0.5875,0.07500002,0.07499999 +0.5125,0.5875,0.053032964,0.10606605 +0.51250005,0.5875,0.10606605,0.053032935 +0.5125,0.5875,0.094494075,0.094494045 +0.5125,0.5875,0.06681737,0.13363487 +0.51250005,0.5875,0.13363487,0.06681734 +0.51250005,0.5875,0.11905509,0.11905509 +0.5125,0.5875,0.08418465,0.1683693 +0.5125,0.5875,0.1683693,0.08418465 +0.5125,0.61249995,0.07500002,0.07499999 +0.5125,0.61249995,0.053032964,0.10606605 +0.51250005,0.6125,0.10606605,0.053032994 +0.5125,0.61249995,0.094494075,0.094494045 +0.5125,0.61249995,0.06681737,0.13363487 +0.51250005,0.6125,0.13363487,0.0668174 +0.51250005,0.61249995,0.11905509,0.11905509 +0.5125,0.6125,0.08418465,0.1683693 +0.5125,0.6125,0.1683693,0.08418465 +0.5125,0.63750005,0.07500002,0.07499999 +0.5125,0.63750005,0.053032964,0.10606605 +0.51250005,0.6375,0.10606605,0.053032994 +0.5125,0.63750005,0.094494075,0.094494045 +0.5125,0.63750005,0.06681737,0.13363487 +0.51250005,0.6375,0.13363487,0.0668174 +0.51250005,0.63750005,0.11905509,0.11905509 +0.5125,0.6375,0.08418465,0.1683693 +0.5125,0.6375,0.1683693,0.08418465 +0.5125,0.6625,0.07500002,0.07499999 +0.5125,0.6625,0.053032964,0.10606605 +0.51250005,0.6625,0.10606605,0.053032935 +0.5125,0.6625,0.094494075,0.094494045 +0.5125,0.6625,0.06681737,0.13363487 +0.51250005,0.6625,0.13363487,0.06681734 +0.51250005,0.6625,0.11905509,0.11905509 +0.5125,0.6625,0.08418465,0.1683693 +0.5125,0.6625,0.1683693,0.08418465 +0.5125,0.6875,0.07500002,0.07500005 +0.5125,0.6875,0.053032964,0.10606599 +0.51250005,0.6875,0.10606605,0.053032994 +0.5125,0.6875,0.094494075,0.094494104 +0.5125,0.6875,0.06681737,0.1336348 +0.51250005,0.6875,0.13363487,0.0668174 +0.51250005,0.6875,0.11905509,0.11905503 +0.5125,0.6875,0.08418465,0.1683693 +0.5125,0.6875,0.1683693,0.08418465 +0.5125,0.7125,0.07500002,0.07499999 +0.5125,0.7125,0.053032964,0.10606605 +0.51250005,0.7125,0.10606605,0.053032935 +0.5125,0.7125,0.094494075,0.094494045 +0.5125,0.7125,0.06681737,0.13363487 +0.51250005,0.7125,0.13363487,0.06681734 +0.51250005,0.7125,0.11905509,0.11905509 +0.5125,0.7125,0.08418465,0.1683693 +0.5125,0.7125,0.1683693,0.08418465 +0.5125,0.73749995,0.07500002,0.07499999 +0.5125,0.73749995,0.053032964,0.10606605 +0.51250005,0.7375,0.10606605,0.053032994 +0.5125,0.73749995,0.094494075,0.094494045 +0.5125,0.73749995,0.06681737,0.1336348 +0.51250005,0.7375,0.13363487,0.0668174 +0.51250005,0.73749995,0.11905509,0.11905509 +0.5125,0.7375,0.08418465,0.1683693 +0.5125,0.7375,0.1683693,0.08418465 +0.5125,0.76250005,0.07500002,0.07499999 +0.5125,0.7625,0.053032964,0.10606599 +0.51250005,0.7625,0.10606605,0.053032994 +0.5125,0.76250005,0.094494075,0.094494045 +0.5125,0.7625,0.06681737,0.1336348 +0.51250005,0.7625,0.13363487,0.0668174 +0.51250005,0.7625,0.11905509,0.11905503 +0.5125,0.7625,0.08418465,0.1683693 +0.5125,0.7625,0.1683693,0.08418465 +0.5125,0.7875,0.07500002,0.07499999 +0.5125,0.78749996,0.053032964,0.10606599 +0.51250005,0.7875,0.10606605,0.053032994 +0.5125,0.7875,0.094494075,0.094494045 +0.5125,0.78749996,0.06681737,0.1336348 +0.51250005,0.7875,0.13363487,0.0668174 +0.51250005,0.78749996,0.11905509,0.11905503 +0.5125,0.7875,0.08418465,0.1683693 +0.5125,0.7875,0.1683693,0.08418465 +0.5125,0.8125,0.07500002,0.07500005 +0.5125,0.8125,0.053032964,0.10606599 +0.51250005,0.8125,0.10606605,0.053033054 +0.5125,0.8125,0.094494075,0.094494104 +0.5125,0.8125,0.06681737,0.1336348 +0.51250005,0.8125,0.13363487,0.06681746 +0.51250005,0.8125,0.11905509,0.11905503 +0.5125,0.8125,0.08418465,0.1683693 +0.5125,0.8125,0.1683693,0.08418465 +0.5125,0.8375,0.07500002,0.07499999 +0.5125,0.8375,0.053032964,0.10606599 +0.51250005,0.8375,0.10606605,0.053033054 +0.5125,0.8375,0.094494075,0.094494045 +0.5125,0.8375,0.06681737,0.1336348 +0.51250005,0.8375,0.13363487,0.06681746 +0.51250005,0.8375,0.11905509,0.11905503 +0.5125,0.8375,0.08418465,0.1683693 +0.5125,0.8375,0.1683693,0.08418465 +0.5125,0.86249995,0.07500002,0.07499999 +0.5125,0.86249995,0.053032964,0.10606593 +0.51250005,0.86249995,0.10606605,0.053033054 +0.5125,0.86249995,0.094494075,0.094494045 +0.5125,0.86249995,0.06681737,0.1336348 +0.51250005,0.86249995,0.13363487,0.06681746 +0.51250005,0.86249995,0.11905509,0.11905497 +0.5125,0.8625,0.08418465,0.1683693 +0.5125,0.8625,0.1683693,0.08418465 +0.5125,0.88750005,0.07500002,0.07499999 +0.5125,0.88750005,0.053032964,0.10606593 +0.51250005,0.88750005,0.10606605,0.053033054 +0.5125,0.88750005,0.094494075,0.094494045 +0.5125,0.88750005,0.06681737,0.13363475 +0.51250005,0.88750005,0.13363487,0.06681746 +0.51250005,0.88750005,0.11905509,0.11905497 +0.5125,0.8875,0.08418465,0.1683693 +0.5125,0.8875,0.1683693,0.08418465 +0.5125,0.9125,0.07500002,0.07499999 +0.5125,0.9125,0.053032964,0.10606593 +0.51250005,0.9125,0.10606605,0.053033054 +0.5125,0.9125,0.094494075,0.094494045 +0.5125,0.9125,0.06681737,0.13363475 +0.51250005,0.9125,0.13363487,0.06681746 +0.51250005,0.9125,0.11905509,0.11905497 +0.5125,0.9125,0.08418465,0.1683693 +0.5125,0.9125,0.1683693,0.08418465 +0.5125,0.9375,0.07500002,0.07500005 +0.5125,0.9375,0.053032964,0.10606599 +0.51250005,0.9375,0.10606605,0.053033113 +0.5125,0.9375,0.094494075,0.094494104 +0.5125,0.9375,0.06681737,0.1336348 +0.51250005,0.9375,0.13363487,0.06681752 +0.51250005,0.9375,0.11905509,0.11905503 +0.5125,0.9375,0.08418465,0.1683693 +0.5125,0.9375,0.1683693,0.08418465 +0.5125,0.9625,0.07500002,0.07499999 +0.5125,0.9625,0.053032964,0.10606593 +0.51250005,0.9625,0.10606605,0.053033054 +0.5125,0.9625,0.094494075,0.094494045 +0.5125,0.9625,0.06681737,0.13363475 +0.51250005,0.9625,0.13363487,0.06681746 +0.51250005,0.9625,0.11905509,0.11905497 +0.5125,0.9625,0.08418465,0.1683693 +0.5125,0.9625,0.1683693,0.08418465 +0.5125,0.98749995,0.07500002,0.07499999 +0.5125,0.98749995,0.053032964,0.10606593 +0.51250005,0.98749995,0.10606605,0.053033054 +0.5125,0.98749995,0.094494075,0.094494045 +0.5125,0.98749995,0.06681737,0.13363475 +0.51250005,0.98749995,0.13363487,0.06681746 +0.51250005,0.98749995,0.11905509,0.11905497 +0.5125,0.98749995,0.08418465,0.16836923 +0.5125,0.98749995,0.1683693,0.08418459 +0.5375,0.0125,0.07499999,0.075 +0.5375,0.012499997,0.053032935,0.10606602 +0.5375,0.012499999,0.10606605,0.05303301 +0.5375,0.012499999,0.094494045,0.09449408 +0.5375,0.012500001,0.06681734,0.1336348 +0.5375,0.012499999,0.13363487,0.0668174 +0.5375,0.012500001,0.11905509,0.11905508 +0.5375,0.012499999,0.08418468,0.1683693 +0.5375,0.012500002,0.16836932,0.084184654 +0.5375,0.0375,0.07499999,0.075 +0.5375,0.037499998,0.053032935,0.10606601 +0.5375,0.0375,0.10606605,0.05303301 +0.5375,0.0375,0.094494045,0.094494075 +0.5375,0.0375,0.06681734,0.1336348 +0.5375,0.0375,0.13363487,0.0668174 +0.5375,0.0375,0.11905509,0.11905508 +0.5375,0.0375,0.08418468,0.16836931 +0.5375,0.0375,0.16836932,0.08418466 +0.5375,0.0625,0.07499999,0.075 +0.5375,0.0625,0.053032935,0.10606602 +0.5375,0.0625,0.10606605,0.05303301 +0.5375,0.0625,0.094494045,0.094494075 +0.5375,0.0625,0.06681734,0.1336348 +0.5375,0.0625,0.13363487,0.0668174 +0.5375,0.0625,0.11905509,0.11905508 +0.5375,0.0625,0.08418468,0.16836932 +0.5375,0.0625,0.16836932,0.08418465 +0.5375,0.0875,0.07499999,0.075 +0.5375,0.08749999,0.053032935,0.10606601 +0.5375,0.087500006,0.10606605,0.053033013 +0.5375,0.087500006,0.094494045,0.09449408 +0.5375,0.087500006,0.06681734,0.1336348 +0.5375,0.0875,0.13363487,0.0668174 +0.5375,0.0875,0.11905509,0.11905508 +0.5375,0.0875,0.08418468,0.16836931 +0.5375,0.087500006,0.16836932,0.084184654 +0.5375,0.112500004,0.07499999,0.075 +0.5375,0.1125,0.053032935,0.10606601 +0.5375,0.112500004,0.10606605,0.05303301 +0.5375,0.1125,0.094494045,0.094494075 +0.5375,0.1125,0.06681734,0.1336348 +0.5375,0.1125,0.13363487,0.0668174 +0.5375,0.1125,0.11905509,0.119055085 +0.5375,0.112500004,0.08418468,0.16836931 +0.5375,0.1125,0.16836932,0.08418465 +0.5375,0.1375,0.07499999,0.074999996 +0.5375,0.1375,0.053032935,0.10606602 +0.5375,0.1375,0.10606605,0.053033024 +0.5375,0.1375,0.094494045,0.09449408 +0.5375,0.1375,0.06681734,0.1336348 +0.5375,0.1375,0.13363487,0.0668174 +0.5375,0.13749999,0.11905509,0.11905508 +0.5375,0.1375,0.08418468,0.1683693 +0.5375,0.1375,0.16836932,0.084184654 +0.5375,0.1625,0.07499999,0.075 +0.5375,0.16250001,0.053032935,0.106066026 +0.5375,0.1625,0.10606605,0.05303301 +0.5375,0.1625,0.094494045,0.094494075 +0.5375,0.1625,0.06681734,0.1336348 +0.5375,0.1625,0.13363487,0.0668174 +0.5375,0.1625,0.11905509,0.11905508 +0.5375,0.1625,0.08418468,0.1683693 +0.5375,0.1625,0.16836932,0.08418464 +0.5375,0.1875,0.07499999,0.07499999 +0.5375,0.1875,0.053032935,0.10606603 +0.5375,0.1875,0.10606605,0.053033024 +0.5375,0.1875,0.094494045,0.09449406 +0.5375,0.1875,0.06681734,0.1336348 +0.5375,0.1875,0.13363487,0.06681742 +0.5375,0.1875,0.11905509,0.11905509 +0.5375,0.1875,0.08418468,0.16836931 +0.5375,0.1875,0.16836932,0.08418465 +0.5375,0.2125,0.07499999,0.075 +0.5375,0.2125,0.053032935,0.10606603 +0.5375,0.2125,0.10606605,0.05303301 +0.5375,0.21249999,0.094494045,0.094494075 +0.5375,0.2125,0.06681734,0.1336348 +0.5375,0.2125,0.13363487,0.0668174 +0.5375,0.2125,0.11905509,0.11905509 +0.5375,0.2125,0.08418468,0.16836931 +0.5375,0.2125,0.16836932,0.08418465 +0.5375,0.23750001,0.07499999,0.075 +0.5375,0.2375,0.053032935,0.10606602 +0.5375,0.2375,0.10606605,0.053033024 +0.5375,0.2375,0.094494045,0.094494075 +0.5375,0.23750001,0.06681734,0.13363482 +0.5375,0.2375,0.13363487,0.06681743 +0.5375,0.2375,0.11905509,0.11905506 +0.5375,0.2375,0.08418468,0.16836932 +0.5375,0.23750001,0.16836932,0.08418466 +0.5375,0.2625,0.07499999,0.07500002 +0.5375,0.2625,0.053032935,0.10606603 +0.5375,0.2625,0.10606605,0.053033024 +0.5375,0.2625,0.094494045,0.094494075 +0.5375,0.2625,0.06681734,0.13363479 +0.5375,0.2625,0.13363487,0.06681743 +0.5375,0.2625,0.11905509,0.11905508 +0.5375,0.2625,0.08418468,0.1683693 +0.5375,0.2625,0.16836932,0.08418463 +0.5375,0.2875,0.07499999,0.07499999 +0.5375,0.2875,0.053032935,0.10606603 +0.5375,0.28750002,0.10606605,0.053033024 +0.5375,0.2875,0.094494045,0.094494045 +0.5375,0.2875,0.06681734,0.1336348 +0.5375,0.28750002,0.13363487,0.06681743 +0.5375,0.2875,0.11905509,0.11905508 +0.5375,0.2875,0.08418468,0.1683693 +0.5375,0.2875,0.16836932,0.08418465 +0.5375,0.3125,0.07499999,0.07499999 +0.5375,0.3125,0.053032935,0.10606605 +0.5375,0.3125,0.10606605,0.053032994 +0.5375,0.3125,0.094494045,0.094494045 +0.5375,0.3125,0.06681734,0.1336348 +0.5375,0.3125,0.13363487,0.0668174 +0.5375,0.3125,0.11905509,0.11905509 +0.5375,0.3125,0.08418468,0.1683693 +0.5375,0.3125,0.16836932,0.08418465 +0.5375,0.3375,0.07499999,0.07499999 +0.5375,0.3375,0.053032935,0.10606605 +0.5375,0.33749998,0.10606605,0.053033024 +0.5375,0.3375,0.094494045,0.094494045 +0.5375,0.33750004,0.06681734,0.13363484 +0.5375,0.33749998,0.13363487,0.06681743 +0.5375,0.3375,0.11905509,0.11905509 +0.5375,0.3375,0.08418468,0.1683693 +0.5375,0.3375,0.16836932,0.08418465 +0.5375,0.3625,0.07499999,0.07500002 +0.5375,0.3625,0.053032935,0.10606602 +0.5375,0.3625,0.10606605,0.053033024 +0.5375,0.3625,0.094494045,0.094494075 +0.5375,0.3625,0.06681734,0.1336348 +0.5375,0.3625,0.13363487,0.06681743 +0.5375,0.3625,0.11905509,0.11905506 +0.5375,0.3625,0.08418468,0.1683693 +0.5375,0.3625,0.16836932,0.08418465 +0.5375,0.3875,0.07499999,0.07500002 +0.5375,0.3875,0.053032935,0.10606602 +0.5375,0.3875,0.10606605,0.053032994 +0.5375,0.3875,0.094494045,0.094494075 +0.5375,0.3875,0.06681734,0.13363484 +0.5375,0.3875,0.13363487,0.0668174 +0.5375,0.3875,0.11905509,0.11905506 +0.5375,0.3875,0.08418468,0.1683693 +0.5375,0.3875,0.16836932,0.08418465 +0.5375,0.4125,0.07499999,0.07499999 +0.5375,0.4125,0.053032935,0.10606605 +0.5375,0.4125,0.10606605,0.053032994 +0.5375,0.4125,0.094494045,0.094494045 +0.5375,0.41250002,0.06681734,0.13363484 +0.5375,0.4125,0.13363487,0.0668174 +0.5375,0.4125,0.11905509,0.11905509 +0.5375,0.4125,0.08418468,0.1683693 +0.5375,0.4125,0.16836932,0.08418465 +0.5375,0.4375,0.07499999,0.07499999 +0.5375,0.4375,0.053032935,0.10606605 +0.5375,0.4375,0.10606605,0.053032994 +0.5375,0.4375,0.094494045,0.094494045 +0.5375,0.4375,0.06681734,0.1336348 +0.5375,0.4375,0.13363487,0.0668174 +0.5375,0.4375,0.11905509,0.11905509 +0.5375,0.4375,0.08418468,0.1683693 +0.5375,0.4375,0.16836932,0.08418465 +0.5375,0.4625,0.07499999,0.07499999 +0.5375,0.4625,0.053032935,0.10606605 +0.5375,0.46249998,0.10606605,0.053032964 +0.5375,0.4625,0.094494045,0.094494045 +0.5375,0.46250004,0.06681734,0.13363484 +0.5375,0.46249998,0.13363487,0.06681737 +0.5375,0.4625,0.11905509,0.11905509 +0.5375,0.46249998,0.08418468,0.16836926 +0.5375,0.46249998,0.16836932,0.08418462 +0.5375,0.48749998,0.07499999,0.07499999 +0.5375,0.4875,0.053032935,0.10606602 +0.5375,0.4875,0.10606605,0.053032994 +0.5375,0.48749998,0.094494045,0.094494045 +0.5375,0.4875,0.06681734,0.13363484 +0.5375,0.4875,0.13363487,0.0668174 +0.5375,0.4875,0.11905509,0.11905506 +0.5375,0.4875,0.08418468,0.1683693 +0.5375,0.4875,0.16836932,0.08418465 +0.5375,0.5125,0.07499999,0.07500002 +0.5375,0.51250005,0.053032935,0.10606605 +0.5375,0.5125,0.10606605,0.053032964 +0.5375,0.5125,0.094494045,0.094494075 +0.5375,0.51250005,0.06681734,0.13363487 +0.5375,0.5125,0.13363487,0.06681737 +0.5375,0.51250005,0.11905509,0.11905509 +0.5375,0.5125,0.08418468,0.1683693 +0.5375,0.5125,0.16836932,0.08418465 +0.5375,0.5375,0.07499999,0.07499999 +0.5375,0.5375,0.053032935,0.10606605 +0.5375,0.5375,0.10606605,0.053032935 +0.5375,0.5375,0.094494045,0.094494045 +0.5375,0.5375,0.06681734,0.13363487 +0.5375,0.5375,0.13363487,0.06681734 +0.5375,0.5375,0.11905509,0.11905509 +0.5375,0.5375,0.08418468,0.16836932 +0.5375,0.5375,0.16836932,0.08418468 +0.5375,0.5625,0.07499999,0.07500005 +0.5375,0.5625,0.053032935,0.10606599 +0.5375,0.5625,0.10606605,0.053032994 +0.5375,0.5625,0.094494045,0.094494104 +0.5375,0.5625,0.06681734,0.13363484 +0.5375,0.5625,0.13363487,0.0668174 +0.5375,0.5625,0.11905509,0.11905503 +0.5375,0.5625,0.08418468,0.1683693 +0.5375,0.5625,0.16836932,0.08418465 +0.5375,0.5875,0.07499999,0.07499999 +0.5375,0.5875,0.053032935,0.10606605 +0.5375,0.5875,0.10606605,0.053032935 +0.5375,0.5875,0.094494045,0.094494045 +0.5375,0.5875,0.06681734,0.13363487 +0.5375,0.5875,0.13363487,0.06681734 +0.5375,0.5875,0.11905509,0.11905509 +0.5375,0.5875,0.08418468,0.1683693 +0.5375,0.5875,0.16836932,0.08418465 +0.5375,0.61249995,0.07499999,0.07499999 +0.5375,0.61249995,0.053032935,0.10606605 +0.5375,0.6125,0.10606605,0.053032994 +0.5375,0.61249995,0.094494045,0.094494045 +0.5375,0.61249995,0.06681734,0.13363487 +0.5375,0.6125,0.13363487,0.0668174 +0.5375,0.61249995,0.11905509,0.11905509 +0.5375,0.6125,0.08418468,0.1683693 +0.5375,0.6125,0.16836932,0.08418465 +0.5375,0.63750005,0.07499999,0.07499999 +0.5375,0.63750005,0.053032935,0.10606605 +0.5375,0.6375,0.10606605,0.053032994 +0.5375,0.63750005,0.094494045,0.094494045 +0.5375,0.63750005,0.06681734,0.13363487 +0.5375,0.6375,0.13363487,0.0668174 +0.5375,0.63750005,0.11905509,0.11905509 +0.5375,0.6375,0.08418468,0.1683693 +0.5375,0.6375,0.16836932,0.08418465 +0.5375,0.6625,0.07499999,0.07499999 +0.5375,0.6625,0.053032935,0.10606605 +0.5375,0.6625,0.10606605,0.053032935 +0.5375,0.6625,0.094494045,0.094494045 +0.5375,0.6625,0.06681734,0.13363487 +0.5375,0.6625,0.13363487,0.06681734 +0.5375,0.6625,0.11905509,0.11905509 +0.5375,0.6625,0.08418468,0.1683693 +0.5375,0.6625,0.16836932,0.08418465 +0.5375,0.6875,0.07499999,0.07500005 +0.5375,0.6875,0.053032935,0.10606599 +0.5375,0.6875,0.10606605,0.053032994 +0.5375,0.6875,0.094494045,0.094494104 +0.5375,0.6875,0.06681734,0.1336348 +0.5375,0.6875,0.13363487,0.0668174 +0.5375,0.6875,0.11905509,0.11905503 +0.5375,0.6875,0.08418468,0.1683693 +0.5375,0.6875,0.16836932,0.08418465 +0.5375,0.7125,0.07499999,0.07499999 +0.5375,0.7125,0.053032935,0.10606605 +0.5375,0.7125,0.10606605,0.053032935 +0.5375,0.7125,0.094494045,0.094494045 +0.5375,0.7125,0.06681734,0.13363487 +0.5375,0.7125,0.13363487,0.06681734 +0.5375,0.7125,0.11905509,0.11905509 +0.5375,0.7125,0.08418468,0.1683693 +0.5375,0.7125,0.16836932,0.08418465 +0.5375,0.73749995,0.07499999,0.07499999 +0.5375,0.73749995,0.053032935,0.10606605 +0.5375,0.7375,0.10606605,0.053032994 +0.5375,0.73749995,0.094494045,0.094494045 +0.5375,0.73749995,0.06681734,0.1336348 +0.5375,0.7375,0.13363487,0.0668174 +0.5375,0.73749995,0.11905509,0.11905509 +0.5375,0.7375,0.08418468,0.1683693 +0.5375,0.7375,0.16836932,0.08418465 +0.5375,0.76250005,0.07499999,0.07499999 +0.5375,0.7625,0.053032935,0.10606599 +0.5375,0.7625,0.10606605,0.053032994 +0.5375,0.76250005,0.094494045,0.094494045 +0.5375,0.7625,0.06681734,0.1336348 +0.5375,0.7625,0.13363487,0.0668174 +0.5375,0.7625,0.11905509,0.11905503 +0.5375,0.7625,0.08418468,0.1683693 +0.5375,0.7625,0.16836932,0.08418465 +0.5375,0.7875,0.07499999,0.07499999 +0.5375,0.78749996,0.053032935,0.10606599 +0.5375,0.7875,0.10606605,0.053032994 +0.5375,0.7875,0.094494045,0.094494045 +0.5375,0.78749996,0.06681734,0.1336348 +0.5375,0.7875,0.13363487,0.0668174 +0.5375,0.78749996,0.11905509,0.11905503 +0.5375,0.7875,0.08418468,0.1683693 +0.5375,0.7875,0.16836932,0.08418465 +0.5375,0.8125,0.07499999,0.07500005 +0.5375,0.8125,0.053032935,0.10606599 +0.5375,0.8125,0.10606605,0.053033054 +0.5375,0.8125,0.094494045,0.094494104 +0.5375,0.8125,0.06681734,0.1336348 +0.5375,0.8125,0.13363487,0.06681746 +0.5375,0.8125,0.11905509,0.11905503 +0.5375,0.8125,0.08418468,0.1683693 +0.5375,0.8125,0.16836932,0.08418465 +0.5375,0.8375,0.07499999,0.07499999 +0.5375,0.8375,0.053032935,0.10606599 +0.5375,0.8375,0.10606605,0.053033054 +0.5375,0.8375,0.094494045,0.094494045 +0.5375,0.8375,0.06681734,0.1336348 +0.5375,0.8375,0.13363487,0.06681746 +0.5375,0.8375,0.11905509,0.11905503 +0.5375,0.8375,0.08418468,0.1683693 +0.5375,0.8375,0.16836932,0.08418465 +0.5375,0.86249995,0.07499999,0.07499999 +0.5375,0.86249995,0.053032935,0.10606593 +0.5375,0.86249995,0.10606605,0.053033054 +0.5375,0.86249995,0.094494045,0.094494045 +0.5375,0.86249995,0.06681734,0.1336348 +0.5375,0.86249995,0.13363487,0.06681746 +0.5375,0.86249995,0.11905509,0.11905497 +0.5375,0.8625,0.08418468,0.1683693 +0.5375,0.8625,0.16836932,0.08418465 +0.5375,0.88750005,0.07499999,0.07499999 +0.5375,0.88750005,0.053032935,0.10606593 +0.5375,0.88750005,0.10606605,0.053033054 +0.5375,0.88750005,0.094494045,0.094494045 +0.5375,0.88750005,0.06681734,0.13363475 +0.5375,0.88750005,0.13363487,0.06681746 +0.5375,0.88750005,0.11905509,0.11905497 +0.5375,0.8875,0.08418468,0.1683693 +0.5375,0.8875,0.16836932,0.08418465 +0.5375,0.9125,0.07499999,0.07499999 +0.5375,0.9125,0.053032935,0.10606593 +0.5375,0.9125,0.10606605,0.053033054 +0.5375,0.9125,0.094494045,0.094494045 +0.5375,0.9125,0.06681734,0.13363475 +0.5375,0.9125,0.13363487,0.06681746 +0.5375,0.9125,0.11905509,0.11905497 +0.5375,0.9125,0.08418468,0.1683693 +0.5375,0.9125,0.16836932,0.08418465 +0.5375,0.9375,0.07499999,0.07500005 +0.5375,0.9375,0.053032935,0.10606599 +0.5375,0.9375,0.10606605,0.053033113 +0.5375,0.9375,0.094494045,0.094494104 +0.5375,0.9375,0.06681734,0.1336348 +0.5375,0.9375,0.13363487,0.06681752 +0.5375,0.9375,0.11905509,0.11905503 +0.5375,0.9375,0.08418468,0.1683693 +0.5375,0.9375,0.16836932,0.08418465 +0.5375,0.9625,0.07499999,0.07499999 +0.5375,0.9625,0.053032935,0.10606593 +0.5375,0.9625,0.10606605,0.053033054 +0.5375,0.9625,0.094494045,0.094494045 +0.5375,0.9625,0.06681734,0.13363475 +0.5375,0.9625,0.13363487,0.06681746 +0.5375,0.9625,0.11905509,0.11905497 +0.5375,0.9625,0.08418468,0.1683693 +0.5375,0.9625,0.16836932,0.08418465 +0.5375,0.98749995,0.07499999,0.07499999 +0.5375,0.98749995,0.053032935,0.10606593 +0.5375,0.98749995,0.10606605,0.053033054 +0.5375,0.98749995,0.094494045,0.094494045 +0.5375,0.98749995,0.06681734,0.13363475 +0.5375,0.98749995,0.13363487,0.06681746 +0.5375,0.98749995,0.11905509,0.11905497 +0.5375,0.98749995,0.08418468,0.16836923 +0.5375,0.98749995,0.16836932,0.08418459 +0.5625,0.0125,0.07500005,0.075 +0.5625,0.012499997,0.053032994,0.10606602 +0.5625,0.012499999,0.10606599,0.05303301 +0.5625,0.012499999,0.094494104,0.09449408 +0.5625,0.012500001,0.0668174,0.1336348 +0.5625,0.012499999,0.13363484,0.0668174 +0.5625,0.012500001,0.11905503,0.11905508 +0.5625,0.012499999,0.08418465,0.1683693 +0.5625,0.012500002,0.1683693,0.084184654 +0.5625,0.0375,0.07500005,0.075 +0.5625,0.037499998,0.053032994,0.10606601 +0.5625,0.0375,0.10606599,0.05303301 +0.5625,0.0375,0.094494104,0.094494075 +0.5625,0.0375,0.0668174,0.1336348 +0.5625,0.0375,0.13363484,0.0668174 +0.5625,0.0375,0.11905503,0.11905508 +0.5625,0.0375,0.08418465,0.16836931 +0.5625,0.0375,0.1683693,0.08418466 +0.5625,0.0625,0.07500005,0.075 +0.5625,0.0625,0.053032994,0.10606602 +0.5625,0.0625,0.10606599,0.05303301 +0.5625,0.0625,0.094494104,0.094494075 +0.5625,0.0625,0.0668174,0.1336348 +0.5625,0.0625,0.13363484,0.0668174 +0.5625,0.0625,0.11905503,0.11905508 +0.5625,0.0625,0.08418465,0.16836932 +0.5625,0.0625,0.1683693,0.08418465 +0.5625,0.0875,0.07500005,0.075 +0.5625,0.08749999,0.053032994,0.10606601 +0.5625,0.087500006,0.10606599,0.053033013 +0.5625,0.087500006,0.094494104,0.09449408 +0.5625,0.087500006,0.0668174,0.1336348 +0.5625,0.0875,0.13363484,0.0668174 +0.5625,0.0875,0.11905503,0.11905508 +0.5625,0.0875,0.08418465,0.16836931 +0.5625,0.087500006,0.1683693,0.084184654 +0.5625,0.112500004,0.07500005,0.075 +0.5625,0.1125,0.053032994,0.10606601 +0.5625,0.112500004,0.10606599,0.05303301 +0.5625,0.1125,0.094494104,0.094494075 +0.5625,0.1125,0.0668174,0.1336348 +0.5625,0.1125,0.13363484,0.0668174 +0.5625,0.1125,0.11905503,0.119055085 +0.5625,0.112500004,0.08418465,0.16836931 +0.5625,0.1125,0.1683693,0.08418465 +0.5625,0.1375,0.07500005,0.074999996 +0.5625,0.1375,0.053032994,0.10606602 +0.5625,0.1375,0.10606599,0.053033024 +0.5625,0.1375,0.094494104,0.09449408 +0.5625,0.1375,0.0668174,0.1336348 +0.5625,0.1375,0.13363484,0.0668174 +0.5625,0.13749999,0.11905503,0.11905508 +0.5625,0.1375,0.08418465,0.1683693 +0.5625,0.1375,0.1683693,0.084184654 +0.5625,0.1625,0.07500005,0.075 +0.5625,0.16250001,0.053032994,0.106066026 +0.5625,0.1625,0.10606599,0.05303301 +0.5625,0.1625,0.094494104,0.094494075 +0.5625,0.1625,0.0668174,0.1336348 +0.5625,0.1625,0.13363484,0.0668174 +0.5625,0.1625,0.11905503,0.11905508 +0.5625,0.1625,0.08418465,0.1683693 +0.5625,0.1625,0.1683693,0.08418464 +0.5625,0.1875,0.07500005,0.07499999 +0.5625,0.1875,0.053032994,0.10606603 +0.5625,0.1875,0.10606599,0.053033024 +0.5625,0.1875,0.094494104,0.09449406 +0.5625,0.1875,0.0668174,0.1336348 +0.5625,0.1875,0.13363484,0.06681742 +0.5625,0.1875,0.11905503,0.11905509 +0.5625,0.1875,0.08418465,0.16836931 +0.5625,0.1875,0.1683693,0.08418465 +0.5625,0.2125,0.07500005,0.075 +0.5625,0.2125,0.053032994,0.10606603 +0.5625,0.2125,0.10606599,0.05303301 +0.5625,0.21249999,0.094494104,0.094494075 +0.5625,0.2125,0.0668174,0.1336348 +0.5625,0.2125,0.13363484,0.0668174 +0.5625,0.2125,0.11905503,0.11905509 +0.5625,0.2125,0.08418465,0.16836931 +0.5625,0.2125,0.1683693,0.08418465 +0.5625,0.23750001,0.07500005,0.075 +0.5625,0.2375,0.053032994,0.10606602 +0.5625,0.2375,0.10606599,0.053033024 +0.5625,0.2375,0.094494104,0.094494075 +0.5625,0.23750001,0.0668174,0.13363482 +0.5625,0.2375,0.13363484,0.06681743 +0.5625,0.2375,0.11905503,0.11905506 +0.5625,0.2375,0.08418465,0.16836932 +0.5625,0.23750001,0.1683693,0.08418466 +0.5625,0.2625,0.07500005,0.07500002 +0.5625,0.2625,0.053032994,0.10606603 +0.5625,0.2625,0.10606599,0.053033024 +0.5625,0.2625,0.094494104,0.094494075 +0.5625,0.2625,0.0668174,0.13363479 +0.5625,0.2625,0.13363484,0.06681743 +0.5625,0.2625,0.11905503,0.11905508 +0.5625,0.2625,0.08418465,0.1683693 +0.5625,0.2625,0.1683693,0.08418463 +0.5625,0.2875,0.07500005,0.07499999 +0.5625,0.2875,0.053032994,0.10606603 +0.5625,0.28750002,0.10606599,0.053033024 +0.5625,0.2875,0.094494104,0.094494045 +0.5625,0.2875,0.0668174,0.1336348 +0.5625,0.28750002,0.13363484,0.06681743 +0.5625,0.2875,0.11905503,0.11905508 +0.5625,0.2875,0.08418465,0.1683693 +0.5625,0.2875,0.1683693,0.08418465 +0.5625,0.3125,0.07500005,0.07499999 +0.5625,0.3125,0.053032994,0.10606605 +0.5625,0.3125,0.10606599,0.053032994 +0.5625,0.3125,0.094494104,0.094494045 +0.5625,0.3125,0.0668174,0.1336348 +0.5625,0.3125,0.13363484,0.0668174 +0.5625,0.3125,0.11905503,0.11905509 +0.5625,0.3125,0.08418465,0.1683693 +0.5625,0.3125,0.1683693,0.08418465 +0.5625,0.3375,0.07500005,0.07499999 +0.5625,0.3375,0.053032994,0.10606605 +0.5625,0.33749998,0.10606599,0.053033024 +0.5625,0.3375,0.094494104,0.094494045 +0.5625,0.33750004,0.0668174,0.13363484 +0.5625,0.33749998,0.13363484,0.06681743 +0.5625,0.3375,0.11905503,0.11905509 +0.5625,0.3375,0.08418465,0.1683693 +0.5625,0.3375,0.1683693,0.08418465 +0.5625,0.3625,0.07500005,0.07500002 +0.5625,0.3625,0.053032994,0.10606602 +0.5625,0.3625,0.10606599,0.053033024 +0.5625,0.3625,0.094494104,0.094494075 +0.5625,0.3625,0.0668174,0.1336348 +0.5625,0.3625,0.13363484,0.06681743 +0.5625,0.3625,0.11905503,0.11905506 +0.5625,0.3625,0.08418465,0.1683693 +0.5625,0.3625,0.1683693,0.08418465 +0.5625,0.3875,0.07500005,0.07500002 +0.5625,0.3875,0.053032994,0.10606602 +0.5625,0.3875,0.10606599,0.053032994 +0.5625,0.3875,0.094494104,0.094494075 +0.5625,0.3875,0.0668174,0.13363484 +0.5625,0.3875,0.13363484,0.0668174 +0.5625,0.3875,0.11905503,0.11905506 +0.5625,0.3875,0.08418465,0.1683693 +0.5625,0.3875,0.1683693,0.08418465 +0.5625,0.4125,0.07500005,0.07499999 +0.5625,0.4125,0.053032994,0.10606605 +0.5625,0.4125,0.10606599,0.053032994 +0.5625,0.4125,0.094494104,0.094494045 +0.5625,0.41250002,0.0668174,0.13363484 +0.5625,0.4125,0.13363484,0.0668174 +0.5625,0.4125,0.11905503,0.11905509 +0.5625,0.4125,0.08418465,0.1683693 +0.5625,0.4125,0.1683693,0.08418465 +0.5625,0.4375,0.07500005,0.07499999 +0.5625,0.4375,0.053032994,0.10606605 +0.5625,0.4375,0.10606599,0.053032994 +0.5625,0.4375,0.094494104,0.094494045 +0.5625,0.4375,0.0668174,0.1336348 +0.5625,0.4375,0.13363484,0.0668174 +0.5625,0.4375,0.11905503,0.11905509 +0.5625,0.4375,0.08418465,0.1683693 +0.5625,0.4375,0.1683693,0.08418465 +0.5625,0.4625,0.07500005,0.07499999 +0.5625,0.4625,0.053032994,0.10606605 +0.5625,0.46249998,0.10606599,0.053032964 +0.5625,0.4625,0.094494104,0.094494045 +0.5625,0.46250004,0.0668174,0.13363484 +0.5625,0.46249998,0.13363484,0.06681737 +0.5625,0.4625,0.11905503,0.11905509 +0.5625,0.46249998,0.08418465,0.16836926 +0.5625,0.46249998,0.1683693,0.08418462 +0.5625,0.48749998,0.07500005,0.07499999 +0.5625,0.4875,0.053032994,0.10606602 +0.5625,0.4875,0.10606599,0.053032994 +0.5625,0.48749998,0.094494104,0.094494045 +0.5625,0.4875,0.0668174,0.13363484 +0.5625,0.4875,0.13363484,0.0668174 +0.5625,0.4875,0.11905503,0.11905506 +0.5625,0.4875,0.08418465,0.1683693 +0.5625,0.4875,0.1683693,0.08418465 +0.5625,0.5125,0.07500005,0.07500002 +0.5625,0.51250005,0.053032994,0.10606605 +0.5625,0.5125,0.10606599,0.053032964 +0.5625,0.5125,0.094494104,0.094494075 +0.5625,0.51250005,0.0668174,0.13363487 +0.5625,0.5125,0.13363484,0.06681737 +0.5625,0.51250005,0.11905503,0.11905509 +0.5625,0.5125,0.08418465,0.1683693 +0.5625,0.5125,0.1683693,0.08418465 +0.5625,0.5375,0.07500005,0.07499999 +0.5625,0.5375,0.053032994,0.10606605 +0.5625,0.5375,0.10606599,0.053032935 +0.5625,0.5375,0.094494104,0.094494045 +0.5625,0.5375,0.0668174,0.13363487 +0.5625,0.5375,0.13363484,0.06681734 +0.5625,0.5375,0.11905503,0.11905509 +0.5625,0.5375,0.08418465,0.16836932 +0.5625,0.5375,0.1683693,0.08418468 +0.5625,0.5625,0.07500005,0.07500005 +0.5625,0.5625,0.053032994,0.10606599 +0.5625,0.5625,0.10606599,0.053032994 +0.5625,0.5625,0.094494104,0.094494104 +0.5625,0.5625,0.0668174,0.13363484 +0.5625,0.5625,0.13363484,0.0668174 +0.5625,0.5625,0.11905503,0.11905503 +0.5625,0.5625,0.08418465,0.1683693 +0.5625,0.5625,0.1683693,0.08418465 +0.5625,0.5875,0.07500005,0.07499999 +0.5625,0.5875,0.053032994,0.10606605 +0.5625,0.5875,0.10606599,0.053032935 +0.5625,0.5875,0.094494104,0.094494045 +0.5625,0.5875,0.0668174,0.13363487 +0.5625,0.5875,0.13363484,0.06681734 +0.5625,0.5875,0.11905503,0.11905509 +0.5625,0.5875,0.08418465,0.1683693 +0.5625,0.5875,0.1683693,0.08418465 +0.5625,0.61249995,0.07500005,0.07499999 +0.5625,0.61249995,0.053032994,0.10606605 +0.5625,0.6125,0.10606599,0.053032994 +0.5625,0.61249995,0.094494104,0.094494045 +0.5625,0.61249995,0.0668174,0.13363487 +0.5625,0.6125,0.13363484,0.0668174 +0.5625,0.61249995,0.11905503,0.11905509 +0.5625,0.6125,0.08418465,0.1683693 +0.5625,0.6125,0.1683693,0.08418465 +0.5625,0.63750005,0.07500005,0.07499999 +0.5625,0.63750005,0.053032994,0.10606605 +0.5625,0.6375,0.10606599,0.053032994 +0.5625,0.63750005,0.094494104,0.094494045 +0.5625,0.63750005,0.0668174,0.13363487 +0.5625,0.6375,0.13363484,0.0668174 +0.5625,0.63750005,0.11905503,0.11905509 +0.5625,0.6375,0.08418465,0.1683693 +0.5625,0.6375,0.1683693,0.08418465 +0.5625,0.6625,0.07500005,0.07499999 +0.5625,0.6625,0.053032994,0.10606605 +0.5625,0.6625,0.10606599,0.053032935 +0.5625,0.6625,0.094494104,0.094494045 +0.5625,0.6625,0.0668174,0.13363487 +0.5625,0.6625,0.13363484,0.06681734 +0.5625,0.6625,0.11905503,0.11905509 +0.5625,0.6625,0.08418465,0.1683693 +0.5625,0.6625,0.1683693,0.08418465 +0.5625,0.6875,0.07500005,0.07500005 +0.5625,0.6875,0.053032994,0.10606599 +0.5625,0.6875,0.10606599,0.053032994 +0.5625,0.6875,0.094494104,0.094494104 +0.5625,0.6875,0.0668174,0.1336348 +0.5625,0.6875,0.13363484,0.0668174 +0.5625,0.6875,0.11905503,0.11905503 +0.5625,0.6875,0.08418465,0.1683693 +0.5625,0.6875,0.1683693,0.08418465 +0.5625,0.7125,0.07500005,0.07499999 +0.5625,0.7125,0.053032994,0.10606605 +0.5625,0.7125,0.10606599,0.053032935 +0.5625,0.7125,0.094494104,0.094494045 +0.5625,0.7125,0.0668174,0.13363487 +0.5625,0.7125,0.13363484,0.06681734 +0.5625,0.7125,0.11905503,0.11905509 +0.5625,0.7125,0.08418465,0.1683693 +0.5625,0.7125,0.1683693,0.08418465 +0.5625,0.73749995,0.07500005,0.07499999 +0.5625,0.73749995,0.053032994,0.10606605 +0.5625,0.7375,0.10606599,0.053032994 +0.5625,0.73749995,0.094494104,0.094494045 +0.5625,0.73749995,0.0668174,0.1336348 +0.5625,0.7375,0.13363484,0.0668174 +0.5625,0.73749995,0.11905503,0.11905509 +0.5625,0.7375,0.08418465,0.1683693 +0.5625,0.7375,0.1683693,0.08418465 +0.5625,0.76250005,0.07500005,0.07499999 +0.5625,0.7625,0.053032994,0.10606599 +0.5625,0.7625,0.10606599,0.053032994 +0.5625,0.76250005,0.094494104,0.094494045 +0.5625,0.7625,0.0668174,0.1336348 +0.5625,0.7625,0.13363484,0.0668174 +0.5625,0.7625,0.11905503,0.11905503 +0.5625,0.7625,0.08418465,0.1683693 +0.5625,0.7625,0.1683693,0.08418465 +0.5625,0.7875,0.07500005,0.07499999 +0.5625,0.78749996,0.053032994,0.10606599 +0.5625,0.7875,0.10606599,0.053032994 +0.5625,0.7875,0.094494104,0.094494045 +0.5625,0.78749996,0.0668174,0.1336348 +0.5625,0.7875,0.13363484,0.0668174 +0.5625,0.78749996,0.11905503,0.11905503 +0.5625,0.7875,0.08418465,0.1683693 +0.5625,0.7875,0.1683693,0.08418465 +0.5625,0.8125,0.07500005,0.07500005 +0.5625,0.8125,0.053032994,0.10606599 +0.5625,0.8125,0.10606599,0.053033054 +0.5625,0.8125,0.094494104,0.094494104 +0.5625,0.8125,0.0668174,0.1336348 +0.5625,0.8125,0.13363484,0.06681746 +0.5625,0.8125,0.11905503,0.11905503 +0.5625,0.8125,0.08418465,0.1683693 +0.5625,0.8125,0.1683693,0.08418465 +0.5625,0.8375,0.07500005,0.07499999 +0.5625,0.8375,0.053032994,0.10606599 +0.5625,0.8375,0.10606599,0.053033054 +0.5625,0.8375,0.094494104,0.094494045 +0.5625,0.8375,0.0668174,0.1336348 +0.5625,0.8375,0.13363484,0.06681746 +0.5625,0.8375,0.11905503,0.11905503 +0.5625,0.8375,0.08418465,0.1683693 +0.5625,0.8375,0.1683693,0.08418465 +0.5625,0.86249995,0.07500005,0.07499999 +0.5625,0.86249995,0.053032994,0.10606593 +0.5625,0.86249995,0.10606599,0.053033054 +0.5625,0.86249995,0.094494104,0.094494045 +0.5625,0.86249995,0.0668174,0.1336348 +0.5625,0.86249995,0.13363484,0.06681746 +0.5625,0.86249995,0.11905503,0.11905497 +0.5625,0.8625,0.08418465,0.1683693 +0.5625,0.8625,0.1683693,0.08418465 +0.5625,0.88750005,0.07500005,0.07499999 +0.5625,0.88750005,0.053032994,0.10606593 +0.5625,0.88750005,0.10606599,0.053033054 +0.5625,0.88750005,0.094494104,0.094494045 +0.5625,0.88750005,0.0668174,0.13363475 +0.5625,0.88750005,0.13363484,0.06681746 +0.5625,0.88750005,0.11905503,0.11905497 +0.5625,0.8875,0.08418465,0.1683693 +0.5625,0.8875,0.1683693,0.08418465 +0.5625,0.9125,0.07500005,0.07499999 +0.5625,0.9125,0.053032994,0.10606593 +0.5625,0.9125,0.10606599,0.053033054 +0.5625,0.9125,0.094494104,0.094494045 +0.5625,0.9125,0.0668174,0.13363475 +0.5625,0.9125,0.13363484,0.06681746 +0.5625,0.9125,0.11905503,0.11905497 +0.5625,0.9125,0.08418465,0.1683693 +0.5625,0.9125,0.1683693,0.08418465 +0.5625,0.9375,0.07500005,0.07500005 +0.5625,0.9375,0.053032994,0.10606599 +0.5625,0.9375,0.10606599,0.053033113 +0.5625,0.9375,0.094494104,0.094494104 +0.5625,0.9375,0.0668174,0.1336348 +0.5625,0.9375,0.13363484,0.06681752 +0.5625,0.9375,0.11905503,0.11905503 +0.5625,0.9375,0.08418465,0.1683693 +0.5625,0.9375,0.1683693,0.08418465 +0.5625,0.9625,0.07500005,0.07499999 +0.5625,0.9625,0.053032994,0.10606593 +0.5625,0.9625,0.10606599,0.053033054 +0.5625,0.9625,0.094494104,0.094494045 +0.5625,0.9625,0.0668174,0.13363475 +0.5625,0.9625,0.13363484,0.06681746 +0.5625,0.9625,0.11905503,0.11905497 +0.5625,0.9625,0.08418465,0.1683693 +0.5625,0.9625,0.1683693,0.08418465 +0.5625,0.98749995,0.07500005,0.07499999 +0.5625,0.98749995,0.053032994,0.10606593 +0.5625,0.98749995,0.10606599,0.053033054 +0.5625,0.98749995,0.094494104,0.094494045 +0.5625,0.98749995,0.0668174,0.13363475 +0.5625,0.98749995,0.13363484,0.06681746 +0.5625,0.98749995,0.11905503,0.11905497 +0.5625,0.98749995,0.08418465,0.16836923 +0.5625,0.98749995,0.1683693,0.08418459 +0.5875,0.0125,0.07499999,0.075 +0.5875,0.012499997,0.053032935,0.10606602 +0.5875,0.012499999,0.10606605,0.05303301 +0.5875,0.012499999,0.094494045,0.09449408 +0.5875,0.012500001,0.06681734,0.1336348 +0.5875,0.012499999,0.13363487,0.0668174 +0.5875,0.012500001,0.11905509,0.11905508 +0.5875,0.012499999,0.08418465,0.1683693 +0.5875,0.012500002,0.1683693,0.084184654 +0.5875,0.0375,0.07499999,0.075 +0.5875,0.037499998,0.053032935,0.10606601 +0.5875,0.0375,0.10606605,0.05303301 +0.5875,0.0375,0.094494045,0.094494075 +0.5875,0.0375,0.06681734,0.1336348 +0.5875,0.0375,0.13363487,0.0668174 +0.5875,0.0375,0.11905509,0.11905508 +0.5875,0.0375,0.08418465,0.16836931 +0.5875,0.0375,0.1683693,0.08418466 +0.5875,0.0625,0.07499999,0.075 +0.5875,0.0625,0.053032935,0.10606602 +0.5875,0.0625,0.10606605,0.05303301 +0.5875,0.0625,0.094494045,0.094494075 +0.5875,0.0625,0.06681734,0.1336348 +0.5875,0.0625,0.13363487,0.0668174 +0.5875,0.0625,0.11905509,0.11905508 +0.5875,0.0625,0.08418465,0.16836932 +0.5875,0.0625,0.1683693,0.08418465 +0.5875,0.0875,0.07499999,0.075 +0.5875,0.08749999,0.053032935,0.10606601 +0.5875,0.087500006,0.10606605,0.053033013 +0.5875,0.087500006,0.094494045,0.09449408 +0.5875,0.087500006,0.06681734,0.1336348 +0.5875,0.0875,0.13363487,0.0668174 +0.5875,0.0875,0.11905509,0.11905508 +0.5875,0.0875,0.08418465,0.16836931 +0.5875,0.087500006,0.1683693,0.084184654 +0.5875,0.112500004,0.07499999,0.075 +0.5875,0.1125,0.053032935,0.10606601 +0.5875,0.112500004,0.10606605,0.05303301 +0.5875,0.1125,0.094494045,0.094494075 +0.5875,0.1125,0.06681734,0.1336348 +0.5875,0.1125,0.13363487,0.0668174 +0.5875,0.1125,0.11905509,0.119055085 +0.5875,0.112500004,0.08418465,0.16836931 +0.5875,0.1125,0.1683693,0.08418465 +0.5875,0.1375,0.07499999,0.074999996 +0.5875,0.1375,0.053032935,0.10606602 +0.5875,0.1375,0.10606605,0.053033024 +0.5875,0.1375,0.094494045,0.09449408 +0.5875,0.1375,0.06681734,0.1336348 +0.5875,0.1375,0.13363487,0.0668174 +0.5875,0.13749999,0.11905509,0.11905508 +0.5875,0.1375,0.08418465,0.1683693 +0.5875,0.1375,0.1683693,0.084184654 +0.5875,0.1625,0.07499999,0.075 +0.5875,0.16250001,0.053032935,0.106066026 +0.5875,0.1625,0.10606605,0.05303301 +0.5875,0.1625,0.094494045,0.094494075 +0.5875,0.1625,0.06681734,0.1336348 +0.5875,0.1625,0.13363487,0.0668174 +0.5875,0.1625,0.11905509,0.11905508 +0.5875,0.1625,0.08418465,0.1683693 +0.5875,0.1625,0.1683693,0.08418464 +0.5875,0.1875,0.07499999,0.07499999 +0.5875,0.1875,0.053032935,0.10606603 +0.5875,0.1875,0.10606605,0.053033024 +0.5875,0.1875,0.094494045,0.09449406 +0.5875,0.1875,0.06681734,0.1336348 +0.5875,0.1875,0.13363487,0.06681742 +0.5875,0.1875,0.11905509,0.11905509 +0.5875,0.1875,0.08418465,0.16836931 +0.5875,0.1875,0.1683693,0.08418465 +0.5875,0.2125,0.07499999,0.075 +0.5875,0.2125,0.053032935,0.10606603 +0.5875,0.2125,0.10606605,0.05303301 +0.5875,0.21249999,0.094494045,0.094494075 +0.5875,0.2125,0.06681734,0.1336348 +0.5875,0.2125,0.13363487,0.0668174 +0.5875,0.2125,0.11905509,0.11905509 +0.5875,0.2125,0.08418465,0.16836931 +0.5875,0.2125,0.1683693,0.08418465 +0.5875,0.23750001,0.07499999,0.075 +0.5875,0.2375,0.053032935,0.10606602 +0.5875,0.2375,0.10606605,0.053033024 +0.5875,0.2375,0.094494045,0.094494075 +0.5875,0.23750001,0.06681734,0.13363482 +0.5875,0.2375,0.13363487,0.06681743 +0.5875,0.2375,0.11905509,0.11905506 +0.5875,0.2375,0.08418465,0.16836932 +0.5875,0.23750001,0.1683693,0.08418466 +0.5875,0.2625,0.07499999,0.07500002 +0.5875,0.2625,0.053032935,0.10606603 +0.5875,0.2625,0.10606605,0.053033024 +0.5875,0.2625,0.094494045,0.094494075 +0.5875,0.2625,0.06681734,0.13363479 +0.5875,0.2625,0.13363487,0.06681743 +0.5875,0.2625,0.11905509,0.11905508 +0.5875,0.2625,0.08418465,0.1683693 +0.5875,0.2625,0.1683693,0.08418463 +0.5875,0.2875,0.07499999,0.07499999 +0.5875,0.2875,0.053032935,0.10606603 +0.5875,0.28750002,0.10606605,0.053033024 +0.5875,0.2875,0.094494045,0.094494045 +0.5875,0.2875,0.06681734,0.1336348 +0.5875,0.28750002,0.13363487,0.06681743 +0.5875,0.2875,0.11905509,0.11905508 +0.5875,0.2875,0.08418465,0.1683693 +0.5875,0.2875,0.1683693,0.08418465 +0.5875,0.3125,0.07499999,0.07499999 +0.5875,0.3125,0.053032935,0.10606605 +0.5875,0.3125,0.10606605,0.053032994 +0.5875,0.3125,0.094494045,0.094494045 +0.5875,0.3125,0.06681734,0.1336348 +0.5875,0.3125,0.13363487,0.0668174 +0.5875,0.3125,0.11905509,0.11905509 +0.5875,0.3125,0.08418465,0.1683693 +0.5875,0.3125,0.1683693,0.08418465 +0.5875,0.3375,0.07499999,0.07499999 +0.5875,0.3375,0.053032935,0.10606605 +0.5875,0.33749998,0.10606605,0.053033024 +0.5875,0.3375,0.094494045,0.094494045 +0.5875,0.33750004,0.06681734,0.13363484 +0.5875,0.33749998,0.13363487,0.06681743 +0.5875,0.3375,0.11905509,0.11905509 +0.5875,0.3375,0.08418465,0.1683693 +0.5875,0.3375,0.1683693,0.08418465 +0.5875,0.3625,0.07499999,0.07500002 +0.5875,0.3625,0.053032935,0.10606602 +0.5875,0.3625,0.10606605,0.053033024 +0.5875,0.3625,0.094494045,0.094494075 +0.5875,0.3625,0.06681734,0.1336348 +0.5875,0.3625,0.13363487,0.06681743 +0.5875,0.3625,0.11905509,0.11905506 +0.5875,0.3625,0.08418465,0.1683693 +0.5875,0.3625,0.1683693,0.08418465 +0.5875,0.3875,0.07499999,0.07500002 +0.5875,0.3875,0.053032935,0.10606602 +0.5875,0.3875,0.10606605,0.053032994 +0.5875,0.3875,0.094494045,0.094494075 +0.5875,0.3875,0.06681734,0.13363484 +0.5875,0.3875,0.13363487,0.0668174 +0.5875,0.3875,0.11905509,0.11905506 +0.5875,0.3875,0.08418465,0.1683693 +0.5875,0.3875,0.1683693,0.08418465 +0.5875,0.4125,0.07499999,0.07499999 +0.5875,0.4125,0.053032935,0.10606605 +0.5875,0.4125,0.10606605,0.053032994 +0.5875,0.4125,0.094494045,0.094494045 +0.5875,0.41250002,0.06681734,0.13363484 +0.5875,0.4125,0.13363487,0.0668174 +0.5875,0.4125,0.11905509,0.11905509 +0.5875,0.4125,0.08418465,0.1683693 +0.5875,0.4125,0.1683693,0.08418465 +0.5875,0.4375,0.07499999,0.07499999 +0.5875,0.4375,0.053032935,0.10606605 +0.5875,0.4375,0.10606605,0.053032994 +0.5875,0.4375,0.094494045,0.094494045 +0.5875,0.4375,0.06681734,0.1336348 +0.5875,0.4375,0.13363487,0.0668174 +0.5875,0.4375,0.11905509,0.11905509 +0.5875,0.4375,0.08418465,0.1683693 +0.5875,0.4375,0.1683693,0.08418465 +0.5875,0.4625,0.07499999,0.07499999 +0.5875,0.4625,0.053032935,0.10606605 +0.5875,0.46249998,0.10606605,0.053032964 +0.5875,0.4625,0.094494045,0.094494045 +0.5875,0.46250004,0.06681734,0.13363484 +0.5875,0.46249998,0.13363487,0.06681737 +0.5875,0.4625,0.11905509,0.11905509 +0.5875,0.46249998,0.08418465,0.16836926 +0.5875,0.46249998,0.1683693,0.08418462 +0.5875,0.48749998,0.07499999,0.07499999 +0.5875,0.4875,0.053032935,0.10606602 +0.5875,0.4875,0.10606605,0.053032994 +0.5875,0.48749998,0.094494045,0.094494045 +0.5875,0.4875,0.06681734,0.13363484 +0.5875,0.4875,0.13363487,0.0668174 +0.5875,0.4875,0.11905509,0.11905506 +0.5875,0.4875,0.08418465,0.1683693 +0.5875,0.4875,0.1683693,0.08418465 +0.5875,0.5125,0.07499999,0.07500002 +0.5875,0.51250005,0.053032935,0.10606605 +0.5875,0.5125,0.10606605,0.053032964 +0.5875,0.5125,0.094494045,0.094494075 +0.5875,0.51250005,0.06681734,0.13363487 +0.5875,0.5125,0.13363487,0.06681737 +0.5875,0.51250005,0.11905509,0.11905509 +0.5875,0.5125,0.08418465,0.1683693 +0.5875,0.5125,0.1683693,0.08418465 +0.5875,0.5375,0.07499999,0.07499999 +0.5875,0.5375,0.053032935,0.10606605 +0.5875,0.5375,0.10606605,0.053032935 +0.5875,0.5375,0.094494045,0.094494045 +0.5875,0.5375,0.06681734,0.13363487 +0.5875,0.5375,0.13363487,0.06681734 +0.5875,0.5375,0.11905509,0.11905509 +0.5875,0.5375,0.08418465,0.16836932 +0.5875,0.5375,0.1683693,0.08418468 +0.5875,0.5625,0.07499999,0.07500005 +0.5875,0.5625,0.053032935,0.10606599 +0.5875,0.5625,0.10606605,0.053032994 +0.5875,0.5625,0.094494045,0.094494104 +0.5875,0.5625,0.06681734,0.13363484 +0.5875,0.5625,0.13363487,0.0668174 +0.5875,0.5625,0.11905509,0.11905503 +0.5875,0.5625,0.08418465,0.1683693 +0.5875,0.5625,0.1683693,0.08418465 +0.5875,0.5875,0.07499999,0.07499999 +0.5875,0.5875,0.053032935,0.10606605 +0.5875,0.5875,0.10606605,0.053032935 +0.5875,0.5875,0.094494045,0.094494045 +0.5875,0.5875,0.06681734,0.13363487 +0.5875,0.5875,0.13363487,0.06681734 +0.5875,0.5875,0.11905509,0.11905509 +0.5875,0.5875,0.08418465,0.1683693 +0.5875,0.5875,0.1683693,0.08418465 +0.5875,0.61249995,0.07499999,0.07499999 +0.5875,0.61249995,0.053032935,0.10606605 +0.5875,0.6125,0.10606605,0.053032994 +0.5875,0.61249995,0.094494045,0.094494045 +0.5875,0.61249995,0.06681734,0.13363487 +0.5875,0.6125,0.13363487,0.0668174 +0.5875,0.61249995,0.11905509,0.11905509 +0.5875,0.6125,0.08418465,0.1683693 +0.5875,0.6125,0.1683693,0.08418465 +0.5875,0.63750005,0.07499999,0.07499999 +0.5875,0.63750005,0.053032935,0.10606605 +0.5875,0.6375,0.10606605,0.053032994 +0.5875,0.63750005,0.094494045,0.094494045 +0.5875,0.63750005,0.06681734,0.13363487 +0.5875,0.6375,0.13363487,0.0668174 +0.5875,0.63750005,0.11905509,0.11905509 +0.5875,0.6375,0.08418465,0.1683693 +0.5875,0.6375,0.1683693,0.08418465 +0.5875,0.6625,0.07499999,0.07499999 +0.5875,0.6625,0.053032935,0.10606605 +0.5875,0.6625,0.10606605,0.053032935 +0.5875,0.6625,0.094494045,0.094494045 +0.5875,0.6625,0.06681734,0.13363487 +0.5875,0.6625,0.13363487,0.06681734 +0.5875,0.6625,0.11905509,0.11905509 +0.5875,0.6625,0.08418465,0.1683693 +0.5875,0.6625,0.1683693,0.08418465 +0.5875,0.6875,0.07499999,0.07500005 +0.5875,0.6875,0.053032935,0.10606599 +0.5875,0.6875,0.10606605,0.053032994 +0.5875,0.6875,0.094494045,0.094494104 +0.5875,0.6875,0.06681734,0.1336348 +0.5875,0.6875,0.13363487,0.0668174 +0.5875,0.6875,0.11905509,0.11905503 +0.5875,0.6875,0.08418465,0.1683693 +0.5875,0.6875,0.1683693,0.08418465 +0.5875,0.7125,0.07499999,0.07499999 +0.5875,0.7125,0.053032935,0.10606605 +0.5875,0.7125,0.10606605,0.053032935 +0.5875,0.7125,0.094494045,0.094494045 +0.5875,0.7125,0.06681734,0.13363487 +0.5875,0.7125,0.13363487,0.06681734 +0.5875,0.7125,0.11905509,0.11905509 +0.5875,0.7125,0.08418465,0.1683693 +0.5875,0.7125,0.1683693,0.08418465 +0.5875,0.73749995,0.07499999,0.07499999 +0.5875,0.73749995,0.053032935,0.10606605 +0.5875,0.7375,0.10606605,0.053032994 +0.5875,0.73749995,0.094494045,0.094494045 +0.5875,0.73749995,0.06681734,0.1336348 +0.5875,0.7375,0.13363487,0.0668174 +0.5875,0.73749995,0.11905509,0.11905509 +0.5875,0.7375,0.08418465,0.1683693 +0.5875,0.7375,0.1683693,0.08418465 +0.5875,0.76250005,0.07499999,0.07499999 +0.5875,0.7625,0.053032935,0.10606599 +0.5875,0.7625,0.10606605,0.053032994 +0.5875,0.76250005,0.094494045,0.094494045 +0.5875,0.7625,0.06681734,0.1336348 +0.5875,0.7625,0.13363487,0.0668174 +0.5875,0.7625,0.11905509,0.11905503 +0.5875,0.7625,0.08418465,0.1683693 +0.5875,0.7625,0.1683693,0.08418465 +0.5875,0.7875,0.07499999,0.07499999 +0.5875,0.78749996,0.053032935,0.10606599 +0.5875,0.7875,0.10606605,0.053032994 +0.5875,0.7875,0.094494045,0.094494045 +0.5875,0.78749996,0.06681734,0.1336348 +0.5875,0.7875,0.13363487,0.0668174 +0.5875,0.78749996,0.11905509,0.11905503 +0.5875,0.7875,0.08418465,0.1683693 +0.5875,0.7875,0.1683693,0.08418465 +0.5875,0.8125,0.07499999,0.07500005 +0.5875,0.8125,0.053032935,0.10606599 +0.5875,0.8125,0.10606605,0.053033054 +0.5875,0.8125,0.094494045,0.094494104 +0.5875,0.8125,0.06681734,0.1336348 +0.5875,0.8125,0.13363487,0.06681746 +0.5875,0.8125,0.11905509,0.11905503 +0.5875,0.8125,0.08418465,0.1683693 +0.5875,0.8125,0.1683693,0.08418465 +0.5875,0.8375,0.07499999,0.07499999 +0.5875,0.8375,0.053032935,0.10606599 +0.5875,0.8375,0.10606605,0.053033054 +0.5875,0.8375,0.094494045,0.094494045 +0.5875,0.8375,0.06681734,0.1336348 +0.5875,0.8375,0.13363487,0.06681746 +0.5875,0.8375,0.11905509,0.11905503 +0.5875,0.8375,0.08418465,0.1683693 +0.5875,0.8375,0.1683693,0.08418465 +0.5875,0.86249995,0.07499999,0.07499999 +0.5875,0.86249995,0.053032935,0.10606593 +0.5875,0.86249995,0.10606605,0.053033054 +0.5875,0.86249995,0.094494045,0.094494045 +0.5875,0.86249995,0.06681734,0.1336348 +0.5875,0.86249995,0.13363487,0.06681746 +0.5875,0.86249995,0.11905509,0.11905497 +0.5875,0.8625,0.08418465,0.1683693 +0.5875,0.8625,0.1683693,0.08418465 +0.5875,0.88750005,0.07499999,0.07499999 +0.5875,0.88750005,0.053032935,0.10606593 +0.5875,0.88750005,0.10606605,0.053033054 +0.5875,0.88750005,0.094494045,0.094494045 +0.5875,0.88750005,0.06681734,0.13363475 +0.5875,0.88750005,0.13363487,0.06681746 +0.5875,0.88750005,0.11905509,0.11905497 +0.5875,0.8875,0.08418465,0.1683693 +0.5875,0.8875,0.1683693,0.08418465 +0.5875,0.9125,0.07499999,0.07499999 +0.5875,0.9125,0.053032935,0.10606593 +0.5875,0.9125,0.10606605,0.053033054 +0.5875,0.9125,0.094494045,0.094494045 +0.5875,0.9125,0.06681734,0.13363475 +0.5875,0.9125,0.13363487,0.06681746 +0.5875,0.9125,0.11905509,0.11905497 +0.5875,0.9125,0.08418465,0.1683693 +0.5875,0.9125,0.1683693,0.08418465 +0.5875,0.9375,0.07499999,0.07500005 +0.5875,0.9375,0.053032935,0.10606599 +0.5875,0.9375,0.10606605,0.053033113 +0.5875,0.9375,0.094494045,0.094494104 +0.5875,0.9375,0.06681734,0.1336348 +0.5875,0.9375,0.13363487,0.06681752 +0.5875,0.9375,0.11905509,0.11905503 +0.5875,0.9375,0.08418465,0.1683693 +0.5875,0.9375,0.1683693,0.08418465 +0.5875,0.9625,0.07499999,0.07499999 +0.5875,0.9625,0.053032935,0.10606593 +0.5875,0.9625,0.10606605,0.053033054 +0.5875,0.9625,0.094494045,0.094494045 +0.5875,0.9625,0.06681734,0.13363475 +0.5875,0.9625,0.13363487,0.06681746 +0.5875,0.9625,0.11905509,0.11905497 +0.5875,0.9625,0.08418465,0.1683693 +0.5875,0.9625,0.1683693,0.08418465 +0.5875,0.98749995,0.07499999,0.07499999 +0.5875,0.98749995,0.053032935,0.10606593 +0.5875,0.98749995,0.10606605,0.053033054 +0.5875,0.98749995,0.094494045,0.094494045 +0.5875,0.98749995,0.06681734,0.13363475 +0.5875,0.98749995,0.13363487,0.06681746 +0.5875,0.98749995,0.11905509,0.11905497 +0.5875,0.98749995,0.08418465,0.16836923 +0.5875,0.98749995,0.1683693,0.08418459 +0.61249995,0.0125,0.07499999,0.075 +0.6125,0.012499997,0.053032994,0.10606602 +0.61249995,0.012499999,0.10606605,0.05303301 +0.61249995,0.012499999,0.094494045,0.09449408 +0.6125,0.012500001,0.0668174,0.1336348 +0.61249995,0.012499999,0.13363487,0.0668174 +0.61249995,0.012500001,0.11905509,0.11905508 +0.6125,0.012499999,0.08418465,0.1683693 +0.6125,0.012500002,0.1683693,0.084184654 +0.61249995,0.0375,0.07499999,0.075 +0.6125,0.037499998,0.053032994,0.10606601 +0.61249995,0.0375,0.10606605,0.05303301 +0.61249995,0.0375,0.094494045,0.094494075 +0.6125,0.0375,0.0668174,0.1336348 +0.61249995,0.0375,0.13363487,0.0668174 +0.61249995,0.0375,0.11905509,0.11905508 +0.6125,0.0375,0.08418465,0.16836931 +0.6125,0.0375,0.1683693,0.08418466 +0.61249995,0.0625,0.07499999,0.075 +0.6125,0.0625,0.053032994,0.10606602 +0.61249995,0.0625,0.10606605,0.05303301 +0.61249995,0.0625,0.094494045,0.094494075 +0.6125,0.0625,0.0668174,0.1336348 +0.61249995,0.0625,0.13363487,0.0668174 +0.61249995,0.0625,0.11905509,0.11905508 +0.6125,0.0625,0.08418465,0.16836932 +0.6125,0.0625,0.1683693,0.08418465 +0.61249995,0.0875,0.07499999,0.075 +0.6125,0.08749999,0.053032994,0.10606601 +0.61249995,0.087500006,0.10606605,0.053033013 +0.61249995,0.087500006,0.094494045,0.09449408 +0.6125,0.087500006,0.0668174,0.1336348 +0.61249995,0.0875,0.13363487,0.0668174 +0.61249995,0.0875,0.11905509,0.11905508 +0.6125,0.0875,0.08418465,0.16836931 +0.6125,0.087500006,0.1683693,0.084184654 +0.61249995,0.112500004,0.07499999,0.075 +0.6125,0.1125,0.053032994,0.10606601 +0.61249995,0.112500004,0.10606605,0.05303301 +0.61249995,0.1125,0.094494045,0.094494075 +0.6125,0.1125,0.0668174,0.1336348 +0.61249995,0.1125,0.13363487,0.0668174 +0.61249995,0.1125,0.11905509,0.119055085 +0.6125,0.112500004,0.08418465,0.16836931 +0.6125,0.1125,0.1683693,0.08418465 +0.61249995,0.1375,0.07499999,0.074999996 +0.6125,0.1375,0.053032994,0.10606602 +0.61249995,0.1375,0.10606605,0.053033024 +0.61249995,0.1375,0.094494045,0.09449408 +0.6125,0.1375,0.0668174,0.1336348 +0.61249995,0.1375,0.13363487,0.0668174 +0.61249995,0.13749999,0.11905509,0.11905508 +0.6125,0.1375,0.08418465,0.1683693 +0.6125,0.1375,0.1683693,0.084184654 +0.61249995,0.1625,0.07499999,0.075 +0.6125,0.16250001,0.053032994,0.106066026 +0.61249995,0.1625,0.10606605,0.05303301 +0.61249995,0.1625,0.094494045,0.094494075 +0.6125,0.1625,0.0668174,0.1336348 +0.61249995,0.1625,0.13363487,0.0668174 +0.61249995,0.1625,0.11905509,0.11905508 +0.6125,0.1625,0.08418465,0.1683693 +0.6125,0.1625,0.1683693,0.08418464 +0.61249995,0.1875,0.07499999,0.07499999 +0.6125,0.1875,0.053032994,0.10606603 +0.61249995,0.1875,0.10606605,0.053033024 +0.61249995,0.1875,0.094494045,0.09449406 +0.6125,0.1875,0.0668174,0.1336348 +0.61249995,0.1875,0.13363487,0.06681742 +0.61249995,0.1875,0.11905509,0.11905509 +0.6125,0.1875,0.08418465,0.16836931 +0.6125,0.1875,0.1683693,0.08418465 +0.61249995,0.2125,0.07499999,0.075 +0.6125,0.2125,0.053032994,0.10606603 +0.61249995,0.2125,0.10606605,0.05303301 +0.61249995,0.21249999,0.094494045,0.094494075 +0.6125,0.2125,0.0668174,0.1336348 +0.61249995,0.2125,0.13363487,0.0668174 +0.61249995,0.2125,0.11905509,0.11905509 +0.6125,0.2125,0.08418465,0.16836931 +0.6125,0.2125,0.1683693,0.08418465 +0.61249995,0.23750001,0.07499999,0.075 +0.6125,0.2375,0.053032994,0.10606602 +0.61249995,0.2375,0.10606605,0.053033024 +0.61249995,0.2375,0.094494045,0.094494075 +0.6125,0.23750001,0.0668174,0.13363482 +0.61249995,0.2375,0.13363487,0.06681743 +0.61249995,0.2375,0.11905509,0.11905506 +0.6125,0.2375,0.08418465,0.16836932 +0.6125,0.23750001,0.1683693,0.08418466 +0.61249995,0.2625,0.07499999,0.07500002 +0.6125,0.2625,0.053032994,0.10606603 +0.61249995,0.2625,0.10606605,0.053033024 +0.61249995,0.2625,0.094494045,0.094494075 +0.6125,0.2625,0.0668174,0.13363479 +0.61249995,0.2625,0.13363487,0.06681743 +0.61249995,0.2625,0.11905509,0.11905508 +0.6125,0.2625,0.08418465,0.1683693 +0.6125,0.2625,0.1683693,0.08418463 +0.61249995,0.2875,0.07499999,0.07499999 +0.6125,0.2875,0.053032994,0.10606603 +0.61249995,0.28750002,0.10606605,0.053033024 +0.61249995,0.2875,0.094494045,0.094494045 +0.6125,0.2875,0.0668174,0.1336348 +0.61249995,0.28750002,0.13363487,0.06681743 +0.61249995,0.2875,0.11905509,0.11905508 +0.6125,0.2875,0.08418465,0.1683693 +0.6125,0.2875,0.1683693,0.08418465 +0.61249995,0.3125,0.07499999,0.07499999 +0.6125,0.3125,0.053032994,0.10606605 +0.61249995,0.3125,0.10606605,0.053032994 +0.61249995,0.3125,0.094494045,0.094494045 +0.6125,0.3125,0.0668174,0.1336348 +0.61249995,0.3125,0.13363487,0.0668174 +0.61249995,0.3125,0.11905509,0.11905509 +0.6125,0.3125,0.08418465,0.1683693 +0.6125,0.3125,0.1683693,0.08418465 +0.61249995,0.3375,0.07499999,0.07499999 +0.6125,0.3375,0.053032994,0.10606605 +0.61249995,0.33749998,0.10606605,0.053033024 +0.61249995,0.3375,0.094494045,0.094494045 +0.6125,0.33750004,0.0668174,0.13363484 +0.61249995,0.33749998,0.13363487,0.06681743 +0.61249995,0.3375,0.11905509,0.11905509 +0.6125,0.3375,0.08418465,0.1683693 +0.6125,0.3375,0.1683693,0.08418465 +0.61249995,0.3625,0.07499999,0.07500002 +0.6125,0.3625,0.053032994,0.10606602 +0.61249995,0.3625,0.10606605,0.053033024 +0.61249995,0.3625,0.094494045,0.094494075 +0.6125,0.3625,0.0668174,0.1336348 +0.61249995,0.3625,0.13363487,0.06681743 +0.61249995,0.3625,0.11905509,0.11905506 +0.6125,0.3625,0.08418465,0.1683693 +0.6125,0.3625,0.1683693,0.08418465 +0.61249995,0.3875,0.07499999,0.07500002 +0.6125,0.3875,0.053032994,0.10606602 +0.61249995,0.3875,0.10606605,0.053032994 +0.61249995,0.3875,0.094494045,0.094494075 +0.6125,0.3875,0.0668174,0.13363484 +0.61249995,0.3875,0.13363487,0.0668174 +0.61249995,0.3875,0.11905509,0.11905506 +0.6125,0.3875,0.08418465,0.1683693 +0.6125,0.3875,0.1683693,0.08418465 +0.61249995,0.4125,0.07499999,0.07499999 +0.6125,0.4125,0.053032994,0.10606605 +0.61249995,0.4125,0.10606605,0.053032994 +0.61249995,0.4125,0.094494045,0.094494045 +0.6125,0.41250002,0.0668174,0.13363484 +0.61249995,0.4125,0.13363487,0.0668174 +0.61249995,0.4125,0.11905509,0.11905509 +0.6125,0.4125,0.08418465,0.1683693 +0.6125,0.4125,0.1683693,0.08418465 +0.61249995,0.4375,0.07499999,0.07499999 +0.6125,0.4375,0.053032994,0.10606605 +0.61249995,0.4375,0.10606605,0.053032994 +0.61249995,0.4375,0.094494045,0.094494045 +0.6125,0.4375,0.0668174,0.1336348 +0.61249995,0.4375,0.13363487,0.0668174 +0.61249995,0.4375,0.11905509,0.11905509 +0.6125,0.4375,0.08418465,0.1683693 +0.6125,0.4375,0.1683693,0.08418465 +0.61249995,0.4625,0.07499999,0.07499999 +0.6125,0.4625,0.053032994,0.10606605 +0.61249995,0.46249998,0.10606605,0.053032964 +0.61249995,0.4625,0.094494045,0.094494045 +0.6125,0.46250004,0.0668174,0.13363484 +0.61249995,0.46249998,0.13363487,0.06681737 +0.61249995,0.4625,0.11905509,0.11905509 +0.6125,0.46249998,0.08418465,0.16836926 +0.6125,0.46249998,0.1683693,0.08418462 +0.61249995,0.48749998,0.07499999,0.07499999 +0.6125,0.4875,0.053032994,0.10606602 +0.61249995,0.4875,0.10606605,0.053032994 +0.61249995,0.48749998,0.094494045,0.094494045 +0.6125,0.4875,0.0668174,0.13363484 +0.61249995,0.4875,0.13363487,0.0668174 +0.61249995,0.4875,0.11905509,0.11905506 +0.6125,0.4875,0.08418465,0.1683693 +0.6125,0.4875,0.1683693,0.08418465 +0.61249995,0.5125,0.07499999,0.07500002 +0.6125,0.51250005,0.053032994,0.10606605 +0.61249995,0.5125,0.10606605,0.053032964 +0.61249995,0.5125,0.094494045,0.094494075 +0.6125,0.51250005,0.0668174,0.13363487 +0.61249995,0.5125,0.13363487,0.06681737 +0.61249995,0.51250005,0.11905509,0.11905509 +0.6125,0.5125,0.08418465,0.1683693 +0.6125,0.5125,0.1683693,0.08418465 +0.61249995,0.5375,0.07499999,0.07499999 +0.6125,0.5375,0.053032994,0.10606605 +0.61249995,0.5375,0.10606605,0.053032935 +0.61249995,0.5375,0.094494045,0.094494045 +0.6125,0.5375,0.0668174,0.13363487 +0.61249995,0.5375,0.13363487,0.06681734 +0.61249995,0.5375,0.11905509,0.11905509 +0.6125,0.5375,0.08418465,0.16836932 +0.6125,0.5375,0.1683693,0.08418468 +0.61249995,0.5625,0.07499999,0.07500005 +0.6125,0.5625,0.053032994,0.10606599 +0.61249995,0.5625,0.10606605,0.053032994 +0.61249995,0.5625,0.094494045,0.094494104 +0.6125,0.5625,0.0668174,0.13363484 +0.61249995,0.5625,0.13363487,0.0668174 +0.61249995,0.5625,0.11905509,0.11905503 +0.6125,0.5625,0.08418465,0.1683693 +0.6125,0.5625,0.1683693,0.08418465 +0.61249995,0.5875,0.07499999,0.07499999 +0.6125,0.5875,0.053032994,0.10606605 +0.61249995,0.5875,0.10606605,0.053032935 +0.61249995,0.5875,0.094494045,0.094494045 +0.6125,0.5875,0.0668174,0.13363487 +0.61249995,0.5875,0.13363487,0.06681734 +0.61249995,0.5875,0.11905509,0.11905509 +0.6125,0.5875,0.08418465,0.1683693 +0.6125,0.5875,0.1683693,0.08418465 +0.61249995,0.61249995,0.07499999,0.07499999 +0.6125,0.61249995,0.053032994,0.10606605 +0.61249995,0.6125,0.10606605,0.053032994 +0.61249995,0.61249995,0.094494045,0.094494045 +0.6125,0.61249995,0.0668174,0.13363487 +0.61249995,0.6125,0.13363487,0.0668174 +0.61249995,0.61249995,0.11905509,0.11905509 +0.6125,0.6125,0.08418465,0.1683693 +0.6125,0.6125,0.1683693,0.08418465 +0.61249995,0.63750005,0.07499999,0.07499999 +0.6125,0.63750005,0.053032994,0.10606605 +0.61249995,0.6375,0.10606605,0.053032994 +0.61249995,0.63750005,0.094494045,0.094494045 +0.6125,0.63750005,0.0668174,0.13363487 +0.61249995,0.6375,0.13363487,0.0668174 +0.61249995,0.63750005,0.11905509,0.11905509 +0.6125,0.6375,0.08418465,0.1683693 +0.6125,0.6375,0.1683693,0.08418465 +0.61249995,0.6625,0.07499999,0.07499999 +0.6125,0.6625,0.053032994,0.10606605 +0.61249995,0.6625,0.10606605,0.053032935 +0.61249995,0.6625,0.094494045,0.094494045 +0.6125,0.6625,0.0668174,0.13363487 +0.61249995,0.6625,0.13363487,0.06681734 +0.61249995,0.6625,0.11905509,0.11905509 +0.6125,0.6625,0.08418465,0.1683693 +0.6125,0.6625,0.1683693,0.08418465 +0.61249995,0.6875,0.07499999,0.07500005 +0.6125,0.6875,0.053032994,0.10606599 +0.61249995,0.6875,0.10606605,0.053032994 +0.61249995,0.6875,0.094494045,0.094494104 +0.6125,0.6875,0.0668174,0.1336348 +0.61249995,0.6875,0.13363487,0.0668174 +0.61249995,0.6875,0.11905509,0.11905503 +0.6125,0.6875,0.08418465,0.1683693 +0.6125,0.6875,0.1683693,0.08418465 +0.61249995,0.7125,0.07499999,0.07499999 +0.6125,0.7125,0.053032994,0.10606605 +0.61249995,0.7125,0.10606605,0.053032935 +0.61249995,0.7125,0.094494045,0.094494045 +0.6125,0.7125,0.0668174,0.13363487 +0.61249995,0.7125,0.13363487,0.06681734 +0.61249995,0.7125,0.11905509,0.11905509 +0.6125,0.7125,0.08418465,0.1683693 +0.6125,0.7125,0.1683693,0.08418465 +0.61249995,0.73749995,0.07499999,0.07499999 +0.6125,0.73749995,0.053032994,0.10606605 +0.61249995,0.7375,0.10606605,0.053032994 +0.61249995,0.73749995,0.094494045,0.094494045 +0.6125,0.73749995,0.0668174,0.1336348 +0.61249995,0.7375,0.13363487,0.0668174 +0.61249995,0.73749995,0.11905509,0.11905509 +0.6125,0.7375,0.08418465,0.1683693 +0.6125,0.7375,0.1683693,0.08418465 +0.61249995,0.76250005,0.07499999,0.07499999 +0.6125,0.7625,0.053032994,0.10606599 +0.61249995,0.7625,0.10606605,0.053032994 +0.61249995,0.76250005,0.094494045,0.094494045 +0.6125,0.7625,0.0668174,0.1336348 +0.61249995,0.7625,0.13363487,0.0668174 +0.61249995,0.7625,0.11905509,0.11905503 +0.6125,0.7625,0.08418465,0.1683693 +0.6125,0.7625,0.1683693,0.08418465 +0.61249995,0.7875,0.07499999,0.07499999 +0.6125,0.78749996,0.053032994,0.10606599 +0.61249995,0.7875,0.10606605,0.053032994 +0.61249995,0.7875,0.094494045,0.094494045 +0.6125,0.78749996,0.0668174,0.1336348 +0.61249995,0.7875,0.13363487,0.0668174 +0.61249995,0.78749996,0.11905509,0.11905503 +0.6125,0.7875,0.08418465,0.1683693 +0.6125,0.7875,0.1683693,0.08418465 +0.61249995,0.8125,0.07499999,0.07500005 +0.6125,0.8125,0.053032994,0.10606599 +0.61249995,0.8125,0.10606605,0.053033054 +0.61249995,0.8125,0.094494045,0.094494104 +0.6125,0.8125,0.0668174,0.1336348 +0.61249995,0.8125,0.13363487,0.06681746 +0.61249995,0.8125,0.11905509,0.11905503 +0.6125,0.8125,0.08418465,0.1683693 +0.6125,0.8125,0.1683693,0.08418465 +0.61249995,0.8375,0.07499999,0.07499999 +0.6125,0.8375,0.053032994,0.10606599 +0.61249995,0.8375,0.10606605,0.053033054 +0.61249995,0.8375,0.094494045,0.094494045 +0.6125,0.8375,0.0668174,0.1336348 +0.61249995,0.8375,0.13363487,0.06681746 +0.61249995,0.8375,0.11905509,0.11905503 +0.6125,0.8375,0.08418465,0.1683693 +0.6125,0.8375,0.1683693,0.08418465 +0.61249995,0.86249995,0.07499999,0.07499999 +0.6125,0.86249995,0.053032994,0.10606593 +0.61249995,0.86249995,0.10606605,0.053033054 +0.61249995,0.86249995,0.094494045,0.094494045 +0.6125,0.86249995,0.0668174,0.1336348 +0.61249995,0.86249995,0.13363487,0.06681746 +0.61249995,0.86249995,0.11905509,0.11905497 +0.6125,0.8625,0.08418465,0.1683693 +0.6125,0.8625,0.1683693,0.08418465 +0.61249995,0.88750005,0.07499999,0.07499999 +0.6125,0.88750005,0.053032994,0.10606593 +0.61249995,0.88750005,0.10606605,0.053033054 +0.61249995,0.88750005,0.094494045,0.094494045 +0.6125,0.88750005,0.0668174,0.13363475 +0.61249995,0.88750005,0.13363487,0.06681746 +0.61249995,0.88750005,0.11905509,0.11905497 +0.6125,0.8875,0.08418465,0.1683693 +0.6125,0.8875,0.1683693,0.08418465 +0.61249995,0.9125,0.07499999,0.07499999 +0.6125,0.9125,0.053032994,0.10606593 +0.61249995,0.9125,0.10606605,0.053033054 +0.61249995,0.9125,0.094494045,0.094494045 +0.6125,0.9125,0.0668174,0.13363475 +0.61249995,0.9125,0.13363487,0.06681746 +0.61249995,0.9125,0.11905509,0.11905497 +0.6125,0.9125,0.08418465,0.1683693 +0.6125,0.9125,0.1683693,0.08418465 +0.61249995,0.9375,0.07499999,0.07500005 +0.6125,0.9375,0.053032994,0.10606599 +0.61249995,0.9375,0.10606605,0.053033113 +0.61249995,0.9375,0.094494045,0.094494104 +0.6125,0.9375,0.0668174,0.1336348 +0.61249995,0.9375,0.13363487,0.06681752 +0.61249995,0.9375,0.11905509,0.11905503 +0.6125,0.9375,0.08418465,0.1683693 +0.6125,0.9375,0.1683693,0.08418465 +0.61249995,0.9625,0.07499999,0.07499999 +0.6125,0.9625,0.053032994,0.10606593 +0.61249995,0.9625,0.10606605,0.053033054 +0.61249995,0.9625,0.094494045,0.094494045 +0.6125,0.9625,0.0668174,0.13363475 +0.61249995,0.9625,0.13363487,0.06681746 +0.61249995,0.9625,0.11905509,0.11905497 +0.6125,0.9625,0.08418465,0.1683693 +0.6125,0.9625,0.1683693,0.08418465 +0.61249995,0.98749995,0.07499999,0.07499999 +0.6125,0.98749995,0.053032994,0.10606593 +0.61249995,0.98749995,0.10606605,0.053033054 +0.61249995,0.98749995,0.094494045,0.094494045 +0.6125,0.98749995,0.0668174,0.13363475 +0.61249995,0.98749995,0.13363487,0.06681746 +0.61249995,0.98749995,0.11905509,0.11905497 +0.6125,0.98749995,0.08418465,0.16836923 +0.6125,0.98749995,0.1683693,0.08418459 +0.63750005,0.0125,0.07499999,0.075 +0.6375,0.012499997,0.053032994,0.10606602 +0.63750005,0.012499999,0.10606605,0.05303301 +0.63750005,0.012499999,0.094494045,0.09449408 +0.6375,0.012500001,0.0668174,0.1336348 +0.63750005,0.012499999,0.13363487,0.0668174 +0.63750005,0.012500001,0.11905509,0.11905508 +0.6375,0.012499999,0.08418465,0.1683693 +0.6375,0.012500002,0.1683693,0.084184654 +0.63750005,0.0375,0.07499999,0.075 +0.6375,0.037499998,0.053032994,0.10606601 +0.63750005,0.0375,0.10606605,0.05303301 +0.63750005,0.0375,0.094494045,0.094494075 +0.6375,0.0375,0.0668174,0.1336348 +0.63750005,0.0375,0.13363487,0.0668174 +0.63750005,0.0375,0.11905509,0.11905508 +0.6375,0.0375,0.08418465,0.16836931 +0.6375,0.0375,0.1683693,0.08418466 +0.63750005,0.0625,0.07499999,0.075 +0.6375,0.0625,0.053032994,0.10606602 +0.63750005,0.0625,0.10606605,0.05303301 +0.63750005,0.0625,0.094494045,0.094494075 +0.6375,0.0625,0.0668174,0.1336348 +0.63750005,0.0625,0.13363487,0.0668174 +0.63750005,0.0625,0.11905509,0.11905508 +0.6375,0.0625,0.08418465,0.16836932 +0.6375,0.0625,0.1683693,0.08418465 +0.63750005,0.0875,0.07499999,0.075 +0.6375,0.08749999,0.053032994,0.10606601 +0.63750005,0.087500006,0.10606605,0.053033013 +0.63750005,0.087500006,0.094494045,0.09449408 +0.6375,0.087500006,0.0668174,0.1336348 +0.63750005,0.0875,0.13363487,0.0668174 +0.63750005,0.0875,0.11905509,0.11905508 +0.6375,0.0875,0.08418465,0.16836931 +0.6375,0.087500006,0.1683693,0.084184654 +0.63750005,0.112500004,0.07499999,0.075 +0.6375,0.1125,0.053032994,0.10606601 +0.63750005,0.112500004,0.10606605,0.05303301 +0.63750005,0.1125,0.094494045,0.094494075 +0.6375,0.1125,0.0668174,0.1336348 +0.63750005,0.1125,0.13363487,0.0668174 +0.63750005,0.1125,0.11905509,0.119055085 +0.6375,0.112500004,0.08418465,0.16836931 +0.6375,0.1125,0.1683693,0.08418465 +0.63750005,0.1375,0.07499999,0.074999996 +0.6375,0.1375,0.053032994,0.10606602 +0.63750005,0.1375,0.10606605,0.053033024 +0.63750005,0.1375,0.094494045,0.09449408 +0.6375,0.1375,0.0668174,0.1336348 +0.63750005,0.1375,0.13363487,0.0668174 +0.63750005,0.13749999,0.11905509,0.11905508 +0.6375,0.1375,0.08418465,0.1683693 +0.6375,0.1375,0.1683693,0.084184654 +0.63750005,0.1625,0.07499999,0.075 +0.6375,0.16250001,0.053032994,0.106066026 +0.63750005,0.1625,0.10606605,0.05303301 +0.63750005,0.1625,0.094494045,0.094494075 +0.6375,0.1625,0.0668174,0.1336348 +0.63750005,0.1625,0.13363487,0.0668174 +0.63750005,0.1625,0.11905509,0.11905508 +0.6375,0.1625,0.08418465,0.1683693 +0.6375,0.1625,0.1683693,0.08418464 +0.63750005,0.1875,0.07499999,0.07499999 +0.6375,0.1875,0.053032994,0.10606603 +0.63750005,0.1875,0.10606605,0.053033024 +0.63750005,0.1875,0.094494045,0.09449406 +0.6375,0.1875,0.0668174,0.1336348 +0.63750005,0.1875,0.13363487,0.06681742 +0.63750005,0.1875,0.11905509,0.11905509 +0.6375,0.1875,0.08418465,0.16836931 +0.6375,0.1875,0.1683693,0.08418465 +0.63750005,0.2125,0.07499999,0.075 +0.6375,0.2125,0.053032994,0.10606603 +0.63750005,0.2125,0.10606605,0.05303301 +0.63750005,0.21249999,0.094494045,0.094494075 +0.6375,0.2125,0.0668174,0.1336348 +0.63750005,0.2125,0.13363487,0.0668174 +0.63750005,0.2125,0.11905509,0.11905509 +0.6375,0.2125,0.08418465,0.16836931 +0.6375,0.2125,0.1683693,0.08418465 +0.63750005,0.23750001,0.07499999,0.075 +0.6375,0.2375,0.053032994,0.10606602 +0.63750005,0.2375,0.10606605,0.053033024 +0.63750005,0.2375,0.094494045,0.094494075 +0.6375,0.23750001,0.0668174,0.13363482 +0.63750005,0.2375,0.13363487,0.06681743 +0.63750005,0.2375,0.11905509,0.11905506 +0.6375,0.2375,0.08418465,0.16836932 +0.6375,0.23750001,0.1683693,0.08418466 +0.63750005,0.2625,0.07499999,0.07500002 +0.6375,0.2625,0.053032994,0.10606603 +0.63750005,0.2625,0.10606605,0.053033024 +0.63750005,0.2625,0.094494045,0.094494075 +0.6375,0.2625,0.0668174,0.13363479 +0.63750005,0.2625,0.13363487,0.06681743 +0.63750005,0.2625,0.11905509,0.11905508 +0.6375,0.2625,0.08418465,0.1683693 +0.6375,0.2625,0.1683693,0.08418463 +0.63750005,0.2875,0.07499999,0.07499999 +0.6375,0.2875,0.053032994,0.10606603 +0.63750005,0.28750002,0.10606605,0.053033024 +0.63750005,0.2875,0.094494045,0.094494045 +0.6375,0.2875,0.0668174,0.1336348 +0.63750005,0.28750002,0.13363487,0.06681743 +0.63750005,0.2875,0.11905509,0.11905508 +0.6375,0.2875,0.08418465,0.1683693 +0.6375,0.2875,0.1683693,0.08418465 +0.63750005,0.3125,0.07499999,0.07499999 +0.6375,0.3125,0.053032994,0.10606605 +0.63750005,0.3125,0.10606605,0.053032994 +0.63750005,0.3125,0.094494045,0.094494045 +0.6375,0.3125,0.0668174,0.1336348 +0.63750005,0.3125,0.13363487,0.0668174 +0.63750005,0.3125,0.11905509,0.11905509 +0.6375,0.3125,0.08418465,0.1683693 +0.6375,0.3125,0.1683693,0.08418465 +0.63750005,0.3375,0.07499999,0.07499999 +0.6375,0.3375,0.053032994,0.10606605 +0.63750005,0.33749998,0.10606605,0.053033024 +0.63750005,0.3375,0.094494045,0.094494045 +0.6375,0.33750004,0.0668174,0.13363484 +0.63750005,0.33749998,0.13363487,0.06681743 +0.63750005,0.3375,0.11905509,0.11905509 +0.6375,0.3375,0.08418465,0.1683693 +0.6375,0.3375,0.1683693,0.08418465 +0.63750005,0.3625,0.07499999,0.07500002 +0.6375,0.3625,0.053032994,0.10606602 +0.63750005,0.3625,0.10606605,0.053033024 +0.63750005,0.3625,0.094494045,0.094494075 +0.6375,0.3625,0.0668174,0.1336348 +0.63750005,0.3625,0.13363487,0.06681743 +0.63750005,0.3625,0.11905509,0.11905506 +0.6375,0.3625,0.08418465,0.1683693 +0.6375,0.3625,0.1683693,0.08418465 +0.63750005,0.3875,0.07499999,0.07500002 +0.6375,0.3875,0.053032994,0.10606602 +0.63750005,0.3875,0.10606605,0.053032994 +0.63750005,0.3875,0.094494045,0.094494075 +0.6375,0.3875,0.0668174,0.13363484 +0.63750005,0.3875,0.13363487,0.0668174 +0.63750005,0.3875,0.11905509,0.11905506 +0.6375,0.3875,0.08418465,0.1683693 +0.6375,0.3875,0.1683693,0.08418465 +0.63750005,0.4125,0.07499999,0.07499999 +0.6375,0.4125,0.053032994,0.10606605 +0.63750005,0.4125,0.10606605,0.053032994 +0.63750005,0.4125,0.094494045,0.094494045 +0.6375,0.41250002,0.0668174,0.13363484 +0.63750005,0.4125,0.13363487,0.0668174 +0.63750005,0.4125,0.11905509,0.11905509 +0.6375,0.4125,0.08418465,0.1683693 +0.6375,0.4125,0.1683693,0.08418465 +0.63750005,0.4375,0.07499999,0.07499999 +0.6375,0.4375,0.053032994,0.10606605 +0.63750005,0.4375,0.10606605,0.053032994 +0.63750005,0.4375,0.094494045,0.094494045 +0.6375,0.4375,0.0668174,0.1336348 +0.63750005,0.4375,0.13363487,0.0668174 +0.63750005,0.4375,0.11905509,0.11905509 +0.6375,0.4375,0.08418465,0.1683693 +0.6375,0.4375,0.1683693,0.08418465 +0.63750005,0.4625,0.07499999,0.07499999 +0.6375,0.4625,0.053032994,0.10606605 +0.63750005,0.46249998,0.10606605,0.053032964 +0.63750005,0.4625,0.094494045,0.094494045 +0.6375,0.46250004,0.0668174,0.13363484 +0.63750005,0.46249998,0.13363487,0.06681737 +0.63750005,0.4625,0.11905509,0.11905509 +0.6375,0.46249998,0.08418465,0.16836926 +0.6375,0.46249998,0.1683693,0.08418462 +0.63750005,0.48749998,0.07499999,0.07499999 +0.6375,0.4875,0.053032994,0.10606602 +0.63750005,0.4875,0.10606605,0.053032994 +0.63750005,0.48749998,0.094494045,0.094494045 +0.6375,0.4875,0.0668174,0.13363484 +0.63750005,0.4875,0.13363487,0.0668174 +0.63750005,0.4875,0.11905509,0.11905506 +0.6375,0.4875,0.08418465,0.1683693 +0.6375,0.4875,0.1683693,0.08418465 +0.63750005,0.5125,0.07499999,0.07500002 +0.6375,0.51250005,0.053032994,0.10606605 +0.63750005,0.5125,0.10606605,0.053032964 +0.63750005,0.5125,0.094494045,0.094494075 +0.6375,0.51250005,0.0668174,0.13363487 +0.63750005,0.5125,0.13363487,0.06681737 +0.63750005,0.51250005,0.11905509,0.11905509 +0.6375,0.5125,0.08418465,0.1683693 +0.6375,0.5125,0.1683693,0.08418465 +0.63750005,0.5375,0.07499999,0.07499999 +0.6375,0.5375,0.053032994,0.10606605 +0.63750005,0.5375,0.10606605,0.053032935 +0.63750005,0.5375,0.094494045,0.094494045 +0.6375,0.5375,0.0668174,0.13363487 +0.63750005,0.5375,0.13363487,0.06681734 +0.63750005,0.5375,0.11905509,0.11905509 +0.6375,0.5375,0.08418465,0.16836932 +0.6375,0.5375,0.1683693,0.08418468 +0.63750005,0.5625,0.07499999,0.07500005 +0.6375,0.5625,0.053032994,0.10606599 +0.63750005,0.5625,0.10606605,0.053032994 +0.63750005,0.5625,0.094494045,0.094494104 +0.6375,0.5625,0.0668174,0.13363484 +0.63750005,0.5625,0.13363487,0.0668174 +0.63750005,0.5625,0.11905509,0.11905503 +0.6375,0.5625,0.08418465,0.1683693 +0.6375,0.5625,0.1683693,0.08418465 +0.63750005,0.5875,0.07499999,0.07499999 +0.6375,0.5875,0.053032994,0.10606605 +0.63750005,0.5875,0.10606605,0.053032935 +0.63750005,0.5875,0.094494045,0.094494045 +0.6375,0.5875,0.0668174,0.13363487 +0.63750005,0.5875,0.13363487,0.06681734 +0.63750005,0.5875,0.11905509,0.11905509 +0.6375,0.5875,0.08418465,0.1683693 +0.6375,0.5875,0.1683693,0.08418465 +0.63750005,0.61249995,0.07499999,0.07499999 +0.6375,0.61249995,0.053032994,0.10606605 +0.63750005,0.6125,0.10606605,0.053032994 +0.63750005,0.61249995,0.094494045,0.094494045 +0.6375,0.61249995,0.0668174,0.13363487 +0.63750005,0.6125,0.13363487,0.0668174 +0.63750005,0.61249995,0.11905509,0.11905509 +0.6375,0.6125,0.08418465,0.1683693 +0.6375,0.6125,0.1683693,0.08418465 +0.63750005,0.63750005,0.07499999,0.07499999 +0.6375,0.63750005,0.053032994,0.10606605 +0.63750005,0.6375,0.10606605,0.053032994 +0.63750005,0.63750005,0.094494045,0.094494045 +0.6375,0.63750005,0.0668174,0.13363487 +0.63750005,0.6375,0.13363487,0.0668174 +0.63750005,0.63750005,0.11905509,0.11905509 +0.6375,0.6375,0.08418465,0.1683693 +0.6375,0.6375,0.1683693,0.08418465 +0.63750005,0.6625,0.07499999,0.07499999 +0.6375,0.6625,0.053032994,0.10606605 +0.63750005,0.6625,0.10606605,0.053032935 +0.63750005,0.6625,0.094494045,0.094494045 +0.6375,0.6625,0.0668174,0.13363487 +0.63750005,0.6625,0.13363487,0.06681734 +0.63750005,0.6625,0.11905509,0.11905509 +0.6375,0.6625,0.08418465,0.1683693 +0.6375,0.6625,0.1683693,0.08418465 +0.63750005,0.6875,0.07499999,0.07500005 +0.6375,0.6875,0.053032994,0.10606599 +0.63750005,0.6875,0.10606605,0.053032994 +0.63750005,0.6875,0.094494045,0.094494104 +0.6375,0.6875,0.0668174,0.1336348 +0.63750005,0.6875,0.13363487,0.0668174 +0.63750005,0.6875,0.11905509,0.11905503 +0.6375,0.6875,0.08418465,0.1683693 +0.6375,0.6875,0.1683693,0.08418465 +0.63750005,0.7125,0.07499999,0.07499999 +0.6375,0.7125,0.053032994,0.10606605 +0.63750005,0.7125,0.10606605,0.053032935 +0.63750005,0.7125,0.094494045,0.094494045 +0.6375,0.7125,0.0668174,0.13363487 +0.63750005,0.7125,0.13363487,0.06681734 +0.63750005,0.7125,0.11905509,0.11905509 +0.6375,0.7125,0.08418465,0.1683693 +0.6375,0.7125,0.1683693,0.08418465 +0.63750005,0.73749995,0.07499999,0.07499999 +0.6375,0.73749995,0.053032994,0.10606605 +0.63750005,0.7375,0.10606605,0.053032994 +0.63750005,0.73749995,0.094494045,0.094494045 +0.6375,0.73749995,0.0668174,0.1336348 +0.63750005,0.7375,0.13363487,0.0668174 +0.63750005,0.73749995,0.11905509,0.11905509 +0.6375,0.7375,0.08418465,0.1683693 +0.6375,0.7375,0.1683693,0.08418465 +0.63750005,0.76250005,0.07499999,0.07499999 +0.6375,0.7625,0.053032994,0.10606599 +0.63750005,0.7625,0.10606605,0.053032994 +0.63750005,0.76250005,0.094494045,0.094494045 +0.6375,0.7625,0.0668174,0.1336348 +0.63750005,0.7625,0.13363487,0.0668174 +0.63750005,0.7625,0.11905509,0.11905503 +0.6375,0.7625,0.08418465,0.1683693 +0.6375,0.7625,0.1683693,0.08418465 +0.63750005,0.7875,0.07499999,0.07499999 +0.6375,0.78749996,0.053032994,0.10606599 +0.63750005,0.7875,0.10606605,0.053032994 +0.63750005,0.7875,0.094494045,0.094494045 +0.6375,0.78749996,0.0668174,0.1336348 +0.63750005,0.7875,0.13363487,0.0668174 +0.63750005,0.78749996,0.11905509,0.11905503 +0.6375,0.7875,0.08418465,0.1683693 +0.6375,0.7875,0.1683693,0.08418465 +0.63750005,0.8125,0.07499999,0.07500005 +0.6375,0.8125,0.053032994,0.10606599 +0.63750005,0.8125,0.10606605,0.053033054 +0.63750005,0.8125,0.094494045,0.094494104 +0.6375,0.8125,0.0668174,0.1336348 +0.63750005,0.8125,0.13363487,0.06681746 +0.63750005,0.8125,0.11905509,0.11905503 +0.6375,0.8125,0.08418465,0.1683693 +0.6375,0.8125,0.1683693,0.08418465 +0.63750005,0.8375,0.07499999,0.07499999 +0.6375,0.8375,0.053032994,0.10606599 +0.63750005,0.8375,0.10606605,0.053033054 +0.63750005,0.8375,0.094494045,0.094494045 +0.6375,0.8375,0.0668174,0.1336348 +0.63750005,0.8375,0.13363487,0.06681746 +0.63750005,0.8375,0.11905509,0.11905503 +0.6375,0.8375,0.08418465,0.1683693 +0.6375,0.8375,0.1683693,0.08418465 +0.63750005,0.86249995,0.07499999,0.07499999 +0.6375,0.86249995,0.053032994,0.10606593 +0.63750005,0.86249995,0.10606605,0.053033054 +0.63750005,0.86249995,0.094494045,0.094494045 +0.6375,0.86249995,0.0668174,0.1336348 +0.63750005,0.86249995,0.13363487,0.06681746 +0.63750005,0.86249995,0.11905509,0.11905497 +0.6375,0.8625,0.08418465,0.1683693 +0.6375,0.8625,0.1683693,0.08418465 +0.63750005,0.88750005,0.07499999,0.07499999 +0.6375,0.88750005,0.053032994,0.10606593 +0.63750005,0.88750005,0.10606605,0.053033054 +0.63750005,0.88750005,0.094494045,0.094494045 +0.6375,0.88750005,0.0668174,0.13363475 +0.63750005,0.88750005,0.13363487,0.06681746 +0.63750005,0.88750005,0.11905509,0.11905497 +0.6375,0.8875,0.08418465,0.1683693 +0.6375,0.8875,0.1683693,0.08418465 +0.63750005,0.9125,0.07499999,0.07499999 +0.6375,0.9125,0.053032994,0.10606593 +0.63750005,0.9125,0.10606605,0.053033054 +0.63750005,0.9125,0.094494045,0.094494045 +0.6375,0.9125,0.0668174,0.13363475 +0.63750005,0.9125,0.13363487,0.06681746 +0.63750005,0.9125,0.11905509,0.11905497 +0.6375,0.9125,0.08418465,0.1683693 +0.6375,0.9125,0.1683693,0.08418465 +0.63750005,0.9375,0.07499999,0.07500005 +0.6375,0.9375,0.053032994,0.10606599 +0.63750005,0.9375,0.10606605,0.053033113 +0.63750005,0.9375,0.094494045,0.094494104 +0.6375,0.9375,0.0668174,0.1336348 +0.63750005,0.9375,0.13363487,0.06681752 +0.63750005,0.9375,0.11905509,0.11905503 +0.6375,0.9375,0.08418465,0.1683693 +0.6375,0.9375,0.1683693,0.08418465 +0.63750005,0.9625,0.07499999,0.07499999 +0.6375,0.9625,0.053032994,0.10606593 +0.63750005,0.9625,0.10606605,0.053033054 +0.63750005,0.9625,0.094494045,0.094494045 +0.6375,0.9625,0.0668174,0.13363475 +0.63750005,0.9625,0.13363487,0.06681746 +0.63750005,0.9625,0.11905509,0.11905497 +0.6375,0.9625,0.08418465,0.1683693 +0.6375,0.9625,0.1683693,0.08418465 +0.63750005,0.98749995,0.07499999,0.07499999 +0.6375,0.98749995,0.053032994,0.10606593 +0.63750005,0.98749995,0.10606605,0.053033054 +0.63750005,0.98749995,0.094494045,0.094494045 +0.6375,0.98749995,0.0668174,0.13363475 +0.63750005,0.98749995,0.13363487,0.06681746 +0.63750005,0.98749995,0.11905509,0.11905497 +0.6375,0.98749995,0.08418465,0.16836923 +0.6375,0.98749995,0.1683693,0.08418459 +0.6625,0.0125,0.07499999,0.075 +0.6625,0.012499997,0.053032935,0.10606602 +0.6625,0.012499999,0.10606605,0.05303301 +0.6625,0.012499999,0.094494045,0.09449408 +0.6625,0.012500001,0.06681734,0.1336348 +0.6625,0.012499999,0.13363487,0.0668174 +0.6625,0.012500001,0.11905509,0.11905508 +0.6625,0.012499999,0.08418465,0.1683693 +0.6625,0.012500002,0.1683693,0.084184654 +0.6625,0.0375,0.07499999,0.075 +0.6625,0.037499998,0.053032935,0.10606601 +0.6625,0.0375,0.10606605,0.05303301 +0.6625,0.0375,0.094494045,0.094494075 +0.6625,0.0375,0.06681734,0.1336348 +0.6625,0.0375,0.13363487,0.0668174 +0.6625,0.0375,0.11905509,0.11905508 +0.6625,0.0375,0.08418465,0.16836931 +0.6625,0.0375,0.1683693,0.08418466 +0.6625,0.0625,0.07499999,0.075 +0.6625,0.0625,0.053032935,0.10606602 +0.6625,0.0625,0.10606605,0.05303301 +0.6625,0.0625,0.094494045,0.094494075 +0.6625,0.0625,0.06681734,0.1336348 +0.6625,0.0625,0.13363487,0.0668174 +0.6625,0.0625,0.11905509,0.11905508 +0.6625,0.0625,0.08418465,0.16836932 +0.6625,0.0625,0.1683693,0.08418465 +0.6625,0.0875,0.07499999,0.075 +0.6625,0.08749999,0.053032935,0.10606601 +0.6625,0.087500006,0.10606605,0.053033013 +0.6625,0.087500006,0.094494045,0.09449408 +0.6625,0.087500006,0.06681734,0.1336348 +0.6625,0.0875,0.13363487,0.0668174 +0.6625,0.0875,0.11905509,0.11905508 +0.6625,0.0875,0.08418465,0.16836931 +0.6625,0.087500006,0.1683693,0.084184654 +0.6625,0.112500004,0.07499999,0.075 +0.6625,0.1125,0.053032935,0.10606601 +0.6625,0.112500004,0.10606605,0.05303301 +0.6625,0.1125,0.094494045,0.094494075 +0.6625,0.1125,0.06681734,0.1336348 +0.6625,0.1125,0.13363487,0.0668174 +0.6625,0.1125,0.11905509,0.119055085 +0.6625,0.112500004,0.08418465,0.16836931 +0.6625,0.1125,0.1683693,0.08418465 +0.6625,0.1375,0.07499999,0.074999996 +0.6625,0.1375,0.053032935,0.10606602 +0.6625,0.1375,0.10606605,0.053033024 +0.6625,0.1375,0.094494045,0.09449408 +0.6625,0.1375,0.06681734,0.1336348 +0.6625,0.1375,0.13363487,0.0668174 +0.6625,0.13749999,0.11905509,0.11905508 +0.6625,0.1375,0.08418465,0.1683693 +0.6625,0.1375,0.1683693,0.084184654 +0.6625,0.1625,0.07499999,0.075 +0.6625,0.16250001,0.053032935,0.106066026 +0.6625,0.1625,0.10606605,0.05303301 +0.6625,0.1625,0.094494045,0.094494075 +0.6625,0.1625,0.06681734,0.1336348 +0.6625,0.1625,0.13363487,0.0668174 +0.6625,0.1625,0.11905509,0.11905508 +0.6625,0.1625,0.08418465,0.1683693 +0.6625,0.1625,0.1683693,0.08418464 +0.6625,0.1875,0.07499999,0.07499999 +0.6625,0.1875,0.053032935,0.10606603 +0.6625,0.1875,0.10606605,0.053033024 +0.6625,0.1875,0.094494045,0.09449406 +0.6625,0.1875,0.06681734,0.1336348 +0.6625,0.1875,0.13363487,0.06681742 +0.6625,0.1875,0.11905509,0.11905509 +0.6625,0.1875,0.08418465,0.16836931 +0.6625,0.1875,0.1683693,0.08418465 +0.6625,0.2125,0.07499999,0.075 +0.6625,0.2125,0.053032935,0.10606603 +0.6625,0.2125,0.10606605,0.05303301 +0.6625,0.21249999,0.094494045,0.094494075 +0.6625,0.2125,0.06681734,0.1336348 +0.6625,0.2125,0.13363487,0.0668174 +0.6625,0.2125,0.11905509,0.11905509 +0.6625,0.2125,0.08418465,0.16836931 +0.6625,0.2125,0.1683693,0.08418465 +0.6625,0.23750001,0.07499999,0.075 +0.6625,0.2375,0.053032935,0.10606602 +0.6625,0.2375,0.10606605,0.053033024 +0.6625,0.2375,0.094494045,0.094494075 +0.6625,0.23750001,0.06681734,0.13363482 +0.6625,0.2375,0.13363487,0.06681743 +0.6625,0.2375,0.11905509,0.11905506 +0.6625,0.2375,0.08418465,0.16836932 +0.6625,0.23750001,0.1683693,0.08418466 +0.6625,0.2625,0.07499999,0.07500002 +0.6625,0.2625,0.053032935,0.10606603 +0.6625,0.2625,0.10606605,0.053033024 +0.6625,0.2625,0.094494045,0.094494075 +0.6625,0.2625,0.06681734,0.13363479 +0.6625,0.2625,0.13363487,0.06681743 +0.6625,0.2625,0.11905509,0.11905508 +0.6625,0.2625,0.08418465,0.1683693 +0.6625,0.2625,0.1683693,0.08418463 +0.6625,0.2875,0.07499999,0.07499999 +0.6625,0.2875,0.053032935,0.10606603 +0.6625,0.28750002,0.10606605,0.053033024 +0.6625,0.2875,0.094494045,0.094494045 +0.6625,0.2875,0.06681734,0.1336348 +0.6625,0.28750002,0.13363487,0.06681743 +0.6625,0.2875,0.11905509,0.11905508 +0.6625,0.2875,0.08418465,0.1683693 +0.6625,0.2875,0.1683693,0.08418465 +0.6625,0.3125,0.07499999,0.07499999 +0.6625,0.3125,0.053032935,0.10606605 +0.6625,0.3125,0.10606605,0.053032994 +0.6625,0.3125,0.094494045,0.094494045 +0.6625,0.3125,0.06681734,0.1336348 +0.6625,0.3125,0.13363487,0.0668174 +0.6625,0.3125,0.11905509,0.11905509 +0.6625,0.3125,0.08418465,0.1683693 +0.6625,0.3125,0.1683693,0.08418465 +0.6625,0.3375,0.07499999,0.07499999 +0.6625,0.3375,0.053032935,0.10606605 +0.6625,0.33749998,0.10606605,0.053033024 +0.6625,0.3375,0.094494045,0.094494045 +0.6625,0.33750004,0.06681734,0.13363484 +0.6625,0.33749998,0.13363487,0.06681743 +0.6625,0.3375,0.11905509,0.11905509 +0.6625,0.3375,0.08418465,0.1683693 +0.6625,0.3375,0.1683693,0.08418465 +0.6625,0.3625,0.07499999,0.07500002 +0.6625,0.3625,0.053032935,0.10606602 +0.6625,0.3625,0.10606605,0.053033024 +0.6625,0.3625,0.094494045,0.094494075 +0.6625,0.3625,0.06681734,0.1336348 +0.6625,0.3625,0.13363487,0.06681743 +0.6625,0.3625,0.11905509,0.11905506 +0.6625,0.3625,0.08418465,0.1683693 +0.6625,0.3625,0.1683693,0.08418465 +0.6625,0.3875,0.07499999,0.07500002 +0.6625,0.3875,0.053032935,0.10606602 +0.6625,0.3875,0.10606605,0.053032994 +0.6625,0.3875,0.094494045,0.094494075 +0.6625,0.3875,0.06681734,0.13363484 +0.6625,0.3875,0.13363487,0.0668174 +0.6625,0.3875,0.11905509,0.11905506 +0.6625,0.3875,0.08418465,0.1683693 +0.6625,0.3875,0.1683693,0.08418465 +0.6625,0.4125,0.07499999,0.07499999 +0.6625,0.4125,0.053032935,0.10606605 +0.6625,0.4125,0.10606605,0.053032994 +0.6625,0.4125,0.094494045,0.094494045 +0.6625,0.41250002,0.06681734,0.13363484 +0.6625,0.4125,0.13363487,0.0668174 +0.6625,0.4125,0.11905509,0.11905509 +0.6625,0.4125,0.08418465,0.1683693 +0.6625,0.4125,0.1683693,0.08418465 +0.6625,0.4375,0.07499999,0.07499999 +0.6625,0.4375,0.053032935,0.10606605 +0.6625,0.4375,0.10606605,0.053032994 +0.6625,0.4375,0.094494045,0.094494045 +0.6625,0.4375,0.06681734,0.1336348 +0.6625,0.4375,0.13363487,0.0668174 +0.6625,0.4375,0.11905509,0.11905509 +0.6625,0.4375,0.08418465,0.1683693 +0.6625,0.4375,0.1683693,0.08418465 +0.6625,0.4625,0.07499999,0.07499999 +0.6625,0.4625,0.053032935,0.10606605 +0.6625,0.46249998,0.10606605,0.053032964 +0.6625,0.4625,0.094494045,0.094494045 +0.6625,0.46250004,0.06681734,0.13363484 +0.6625,0.46249998,0.13363487,0.06681737 +0.6625,0.4625,0.11905509,0.11905509 +0.6625,0.46249998,0.08418465,0.16836926 +0.6625,0.46249998,0.1683693,0.08418462 +0.6625,0.48749998,0.07499999,0.07499999 +0.6625,0.4875,0.053032935,0.10606602 +0.6625,0.4875,0.10606605,0.053032994 +0.6625,0.48749998,0.094494045,0.094494045 +0.6625,0.4875,0.06681734,0.13363484 +0.6625,0.4875,0.13363487,0.0668174 +0.6625,0.4875,0.11905509,0.11905506 +0.6625,0.4875,0.08418465,0.1683693 +0.6625,0.4875,0.1683693,0.08418465 +0.6625,0.5125,0.07499999,0.07500002 +0.6625,0.51250005,0.053032935,0.10606605 +0.6625,0.5125,0.10606605,0.053032964 +0.6625,0.5125,0.094494045,0.094494075 +0.6625,0.51250005,0.06681734,0.13363487 +0.6625,0.5125,0.13363487,0.06681737 +0.6625,0.51250005,0.11905509,0.11905509 +0.6625,0.5125,0.08418465,0.1683693 +0.6625,0.5125,0.1683693,0.08418465 +0.6625,0.5375,0.07499999,0.07499999 +0.6625,0.5375,0.053032935,0.10606605 +0.6625,0.5375,0.10606605,0.053032935 +0.6625,0.5375,0.094494045,0.094494045 +0.6625,0.5375,0.06681734,0.13363487 +0.6625,0.5375,0.13363487,0.06681734 +0.6625,0.5375,0.11905509,0.11905509 +0.6625,0.5375,0.08418465,0.16836932 +0.6625,0.5375,0.1683693,0.08418468 +0.6625,0.5625,0.07499999,0.07500005 +0.6625,0.5625,0.053032935,0.10606599 +0.6625,0.5625,0.10606605,0.053032994 +0.6625,0.5625,0.094494045,0.094494104 +0.6625,0.5625,0.06681734,0.13363484 +0.6625,0.5625,0.13363487,0.0668174 +0.6625,0.5625,0.11905509,0.11905503 +0.6625,0.5625,0.08418465,0.1683693 +0.6625,0.5625,0.1683693,0.08418465 +0.6625,0.5875,0.07499999,0.07499999 +0.6625,0.5875,0.053032935,0.10606605 +0.6625,0.5875,0.10606605,0.053032935 +0.6625,0.5875,0.094494045,0.094494045 +0.6625,0.5875,0.06681734,0.13363487 +0.6625,0.5875,0.13363487,0.06681734 +0.6625,0.5875,0.11905509,0.11905509 +0.6625,0.5875,0.08418465,0.1683693 +0.6625,0.5875,0.1683693,0.08418465 +0.6625,0.61249995,0.07499999,0.07499999 +0.6625,0.61249995,0.053032935,0.10606605 +0.6625,0.6125,0.10606605,0.053032994 +0.6625,0.61249995,0.094494045,0.094494045 +0.6625,0.61249995,0.06681734,0.13363487 +0.6625,0.6125,0.13363487,0.0668174 +0.6625,0.61249995,0.11905509,0.11905509 +0.6625,0.6125,0.08418465,0.1683693 +0.6625,0.6125,0.1683693,0.08418465 +0.6625,0.63750005,0.07499999,0.07499999 +0.6625,0.63750005,0.053032935,0.10606605 +0.6625,0.6375,0.10606605,0.053032994 +0.6625,0.63750005,0.094494045,0.094494045 +0.6625,0.63750005,0.06681734,0.13363487 +0.6625,0.6375,0.13363487,0.0668174 +0.6625,0.63750005,0.11905509,0.11905509 +0.6625,0.6375,0.08418465,0.1683693 +0.6625,0.6375,0.1683693,0.08418465 +0.6625,0.6625,0.07499999,0.07499999 +0.6625,0.6625,0.053032935,0.10606605 +0.6625,0.6625,0.10606605,0.053032935 +0.6625,0.6625,0.094494045,0.094494045 +0.6625,0.6625,0.06681734,0.13363487 +0.6625,0.6625,0.13363487,0.06681734 +0.6625,0.6625,0.11905509,0.11905509 +0.6625,0.6625,0.08418465,0.1683693 +0.6625,0.6625,0.1683693,0.08418465 +0.6625,0.6875,0.07499999,0.07500005 +0.6625,0.6875,0.053032935,0.10606599 +0.6625,0.6875,0.10606605,0.053032994 +0.6625,0.6875,0.094494045,0.094494104 +0.6625,0.6875,0.06681734,0.1336348 +0.6625,0.6875,0.13363487,0.0668174 +0.6625,0.6875,0.11905509,0.11905503 +0.6625,0.6875,0.08418465,0.1683693 +0.6625,0.6875,0.1683693,0.08418465 +0.6625,0.7125,0.07499999,0.07499999 +0.6625,0.7125,0.053032935,0.10606605 +0.6625,0.7125,0.10606605,0.053032935 +0.6625,0.7125,0.094494045,0.094494045 +0.6625,0.7125,0.06681734,0.13363487 +0.6625,0.7125,0.13363487,0.06681734 +0.6625,0.7125,0.11905509,0.11905509 +0.6625,0.7125,0.08418465,0.1683693 +0.6625,0.7125,0.1683693,0.08418465 +0.6625,0.73749995,0.07499999,0.07499999 +0.6625,0.73749995,0.053032935,0.10606605 +0.6625,0.7375,0.10606605,0.053032994 +0.6625,0.73749995,0.094494045,0.094494045 +0.6625,0.73749995,0.06681734,0.1336348 +0.6625,0.7375,0.13363487,0.0668174 +0.6625,0.73749995,0.11905509,0.11905509 +0.6625,0.7375,0.08418465,0.1683693 +0.6625,0.7375,0.1683693,0.08418465 +0.6625,0.76250005,0.07499999,0.07499999 +0.6625,0.7625,0.053032935,0.10606599 +0.6625,0.7625,0.10606605,0.053032994 +0.6625,0.76250005,0.094494045,0.094494045 +0.6625,0.7625,0.06681734,0.1336348 +0.6625,0.7625,0.13363487,0.0668174 +0.6625,0.7625,0.11905509,0.11905503 +0.6625,0.7625,0.08418465,0.1683693 +0.6625,0.7625,0.1683693,0.08418465 +0.6625,0.7875,0.07499999,0.07499999 +0.6625,0.78749996,0.053032935,0.10606599 +0.6625,0.7875,0.10606605,0.053032994 +0.6625,0.7875,0.094494045,0.094494045 +0.6625,0.78749996,0.06681734,0.1336348 +0.6625,0.7875,0.13363487,0.0668174 +0.6625,0.78749996,0.11905509,0.11905503 +0.6625,0.7875,0.08418465,0.1683693 +0.6625,0.7875,0.1683693,0.08418465 +0.6625,0.8125,0.07499999,0.07500005 +0.6625,0.8125,0.053032935,0.10606599 +0.6625,0.8125,0.10606605,0.053033054 +0.6625,0.8125,0.094494045,0.094494104 +0.6625,0.8125,0.06681734,0.1336348 +0.6625,0.8125,0.13363487,0.06681746 +0.6625,0.8125,0.11905509,0.11905503 +0.6625,0.8125,0.08418465,0.1683693 +0.6625,0.8125,0.1683693,0.08418465 +0.6625,0.8375,0.07499999,0.07499999 +0.6625,0.8375,0.053032935,0.10606599 +0.6625,0.8375,0.10606605,0.053033054 +0.6625,0.8375,0.094494045,0.094494045 +0.6625,0.8375,0.06681734,0.1336348 +0.6625,0.8375,0.13363487,0.06681746 +0.6625,0.8375,0.11905509,0.11905503 +0.6625,0.8375,0.08418465,0.1683693 +0.6625,0.8375,0.1683693,0.08418465 +0.6625,0.86249995,0.07499999,0.07499999 +0.6625,0.86249995,0.053032935,0.10606593 +0.6625,0.86249995,0.10606605,0.053033054 +0.6625,0.86249995,0.094494045,0.094494045 +0.6625,0.86249995,0.06681734,0.1336348 +0.6625,0.86249995,0.13363487,0.06681746 +0.6625,0.86249995,0.11905509,0.11905497 +0.6625,0.8625,0.08418465,0.1683693 +0.6625,0.8625,0.1683693,0.08418465 +0.6625,0.88750005,0.07499999,0.07499999 +0.6625,0.88750005,0.053032935,0.10606593 +0.6625,0.88750005,0.10606605,0.053033054 +0.6625,0.88750005,0.094494045,0.094494045 +0.6625,0.88750005,0.06681734,0.13363475 +0.6625,0.88750005,0.13363487,0.06681746 +0.6625,0.88750005,0.11905509,0.11905497 +0.6625,0.8875,0.08418465,0.1683693 +0.6625,0.8875,0.1683693,0.08418465 +0.6625,0.9125,0.07499999,0.07499999 +0.6625,0.9125,0.053032935,0.10606593 +0.6625,0.9125,0.10606605,0.053033054 +0.6625,0.9125,0.094494045,0.094494045 +0.6625,0.9125,0.06681734,0.13363475 +0.6625,0.9125,0.13363487,0.06681746 +0.6625,0.9125,0.11905509,0.11905497 +0.6625,0.9125,0.08418465,0.1683693 +0.6625,0.9125,0.1683693,0.08418465 +0.6625,0.9375,0.07499999,0.07500005 +0.6625,0.9375,0.053032935,0.10606599 +0.6625,0.9375,0.10606605,0.053033113 +0.6625,0.9375,0.094494045,0.094494104 +0.6625,0.9375,0.06681734,0.1336348 +0.6625,0.9375,0.13363487,0.06681752 +0.6625,0.9375,0.11905509,0.11905503 +0.6625,0.9375,0.08418465,0.1683693 +0.6625,0.9375,0.1683693,0.08418465 +0.6625,0.9625,0.07499999,0.07499999 +0.6625,0.9625,0.053032935,0.10606593 +0.6625,0.9625,0.10606605,0.053033054 +0.6625,0.9625,0.094494045,0.094494045 +0.6625,0.9625,0.06681734,0.13363475 +0.6625,0.9625,0.13363487,0.06681746 +0.6625,0.9625,0.11905509,0.11905497 +0.6625,0.9625,0.08418465,0.1683693 +0.6625,0.9625,0.1683693,0.08418465 +0.6625,0.98749995,0.07499999,0.07499999 +0.6625,0.98749995,0.053032935,0.10606593 +0.6625,0.98749995,0.10606605,0.053033054 +0.6625,0.98749995,0.094494045,0.094494045 +0.6625,0.98749995,0.06681734,0.13363475 +0.6625,0.98749995,0.13363487,0.06681746 +0.6625,0.98749995,0.11905509,0.11905497 +0.6625,0.98749995,0.08418465,0.16836923 +0.6625,0.98749995,0.1683693,0.08418459 +0.6875,0.0125,0.07500005,0.075 +0.6875,0.012499997,0.053032994,0.10606602 +0.6875,0.012499999,0.10606599,0.05303301 +0.6875,0.012499999,0.094494104,0.09449408 +0.6875,0.012500001,0.0668174,0.1336348 +0.6875,0.012499999,0.1336348,0.0668174 +0.6875,0.012500001,0.11905503,0.11905508 +0.6875,0.012499999,0.08418465,0.1683693 +0.6875,0.012500002,0.1683693,0.084184654 +0.6875,0.0375,0.07500005,0.075 +0.6875,0.037499998,0.053032994,0.10606601 +0.6875,0.0375,0.10606599,0.05303301 +0.6875,0.0375,0.094494104,0.094494075 +0.6875,0.0375,0.0668174,0.1336348 +0.6875,0.0375,0.1336348,0.0668174 +0.6875,0.0375,0.11905503,0.11905508 +0.6875,0.0375,0.08418465,0.16836931 +0.6875,0.0375,0.1683693,0.08418466 +0.6875,0.0625,0.07500005,0.075 +0.6875,0.0625,0.053032994,0.10606602 +0.6875,0.0625,0.10606599,0.05303301 +0.6875,0.0625,0.094494104,0.094494075 +0.6875,0.0625,0.0668174,0.1336348 +0.6875,0.0625,0.1336348,0.0668174 +0.6875,0.0625,0.11905503,0.11905508 +0.6875,0.0625,0.08418465,0.16836932 +0.6875,0.0625,0.1683693,0.08418465 +0.6875,0.0875,0.07500005,0.075 +0.6875,0.08749999,0.053032994,0.10606601 +0.6875,0.087500006,0.10606599,0.053033013 +0.6875,0.087500006,0.094494104,0.09449408 +0.6875,0.087500006,0.0668174,0.1336348 +0.6875,0.0875,0.1336348,0.0668174 +0.6875,0.0875,0.11905503,0.11905508 +0.6875,0.0875,0.08418465,0.16836931 +0.6875,0.087500006,0.1683693,0.084184654 +0.6875,0.112500004,0.07500005,0.075 +0.6875,0.1125,0.053032994,0.10606601 +0.6875,0.112500004,0.10606599,0.05303301 +0.6875,0.1125,0.094494104,0.094494075 +0.6875,0.1125,0.0668174,0.1336348 +0.6875,0.1125,0.1336348,0.0668174 +0.6875,0.1125,0.11905503,0.119055085 +0.6875,0.112500004,0.08418465,0.16836931 +0.6875,0.1125,0.1683693,0.08418465 +0.6875,0.1375,0.07500005,0.074999996 +0.6875,0.1375,0.053032994,0.10606602 +0.6875,0.1375,0.10606599,0.053033024 +0.6875,0.1375,0.094494104,0.09449408 +0.6875,0.1375,0.0668174,0.1336348 +0.6875,0.1375,0.1336348,0.0668174 +0.6875,0.13749999,0.11905503,0.11905508 +0.6875,0.1375,0.08418465,0.1683693 +0.6875,0.1375,0.1683693,0.084184654 +0.6875,0.1625,0.07500005,0.075 +0.6875,0.16250001,0.053032994,0.106066026 +0.6875,0.1625,0.10606599,0.05303301 +0.6875,0.1625,0.094494104,0.094494075 +0.6875,0.1625,0.0668174,0.1336348 +0.6875,0.1625,0.1336348,0.0668174 +0.6875,0.1625,0.11905503,0.11905508 +0.6875,0.1625,0.08418465,0.1683693 +0.6875,0.1625,0.1683693,0.08418464 +0.6875,0.1875,0.07500005,0.07499999 +0.6875,0.1875,0.053032994,0.10606603 +0.6875,0.1875,0.10606599,0.053033024 +0.6875,0.1875,0.094494104,0.09449406 +0.6875,0.1875,0.0668174,0.1336348 +0.6875,0.1875,0.1336348,0.06681742 +0.6875,0.1875,0.11905503,0.11905509 +0.6875,0.1875,0.08418465,0.16836931 +0.6875,0.1875,0.1683693,0.08418465 +0.6875,0.2125,0.07500005,0.075 +0.6875,0.2125,0.053032994,0.10606603 +0.6875,0.2125,0.10606599,0.05303301 +0.6875,0.21249999,0.094494104,0.094494075 +0.6875,0.2125,0.0668174,0.1336348 +0.6875,0.2125,0.1336348,0.0668174 +0.6875,0.2125,0.11905503,0.11905509 +0.6875,0.2125,0.08418465,0.16836931 +0.6875,0.2125,0.1683693,0.08418465 +0.6875,0.23750001,0.07500005,0.075 +0.6875,0.2375,0.053032994,0.10606602 +0.6875,0.2375,0.10606599,0.053033024 +0.6875,0.2375,0.094494104,0.094494075 +0.6875,0.23750001,0.0668174,0.13363482 +0.6875,0.2375,0.1336348,0.06681743 +0.6875,0.2375,0.11905503,0.11905506 +0.6875,0.2375,0.08418465,0.16836932 +0.6875,0.23750001,0.1683693,0.08418466 +0.6875,0.2625,0.07500005,0.07500002 +0.6875,0.2625,0.053032994,0.10606603 +0.6875,0.2625,0.10606599,0.053033024 +0.6875,0.2625,0.094494104,0.094494075 +0.6875,0.2625,0.0668174,0.13363479 +0.6875,0.2625,0.1336348,0.06681743 +0.6875,0.2625,0.11905503,0.11905508 +0.6875,0.2625,0.08418465,0.1683693 +0.6875,0.2625,0.1683693,0.08418463 +0.6875,0.2875,0.07500005,0.07499999 +0.6875,0.2875,0.053032994,0.10606603 +0.6875,0.28750002,0.10606599,0.053033024 +0.6875,0.2875,0.094494104,0.094494045 +0.6875,0.2875,0.0668174,0.1336348 +0.6875,0.28750002,0.1336348,0.06681743 +0.6875,0.2875,0.11905503,0.11905508 +0.6875,0.2875,0.08418465,0.1683693 +0.6875,0.2875,0.1683693,0.08418465 +0.6875,0.3125,0.07500005,0.07499999 +0.6875,0.3125,0.053032994,0.10606605 +0.6875,0.3125,0.10606599,0.053032994 +0.6875,0.3125,0.094494104,0.094494045 +0.6875,0.3125,0.0668174,0.1336348 +0.6875,0.3125,0.1336348,0.0668174 +0.6875,0.3125,0.11905503,0.11905509 +0.6875,0.3125,0.08418465,0.1683693 +0.6875,0.3125,0.1683693,0.08418465 +0.6875,0.3375,0.07500005,0.07499999 +0.6875,0.3375,0.053032994,0.10606605 +0.6875,0.33749998,0.10606599,0.053033024 +0.6875,0.3375,0.094494104,0.094494045 +0.6875,0.33750004,0.0668174,0.13363484 +0.6875,0.33749998,0.1336348,0.06681743 +0.6875,0.3375,0.11905503,0.11905509 +0.6875,0.3375,0.08418465,0.1683693 +0.6875,0.3375,0.1683693,0.08418465 +0.6875,0.3625,0.07500005,0.07500002 +0.6875,0.3625,0.053032994,0.10606602 +0.6875,0.3625,0.10606599,0.053033024 +0.6875,0.3625,0.094494104,0.094494075 +0.6875,0.3625,0.0668174,0.1336348 +0.6875,0.3625,0.1336348,0.06681743 +0.6875,0.3625,0.11905503,0.11905506 +0.6875,0.3625,0.08418465,0.1683693 +0.6875,0.3625,0.1683693,0.08418465 +0.6875,0.3875,0.07500005,0.07500002 +0.6875,0.3875,0.053032994,0.10606602 +0.6875,0.3875,0.10606599,0.053032994 +0.6875,0.3875,0.094494104,0.094494075 +0.6875,0.3875,0.0668174,0.13363484 +0.6875,0.3875,0.1336348,0.0668174 +0.6875,0.3875,0.11905503,0.11905506 +0.6875,0.3875,0.08418465,0.1683693 +0.6875,0.3875,0.1683693,0.08418465 +0.6875,0.4125,0.07500005,0.07499999 +0.6875,0.4125,0.053032994,0.10606605 +0.6875,0.4125,0.10606599,0.053032994 +0.6875,0.4125,0.094494104,0.094494045 +0.6875,0.41250002,0.0668174,0.13363484 +0.6875,0.4125,0.1336348,0.0668174 +0.6875,0.4125,0.11905503,0.11905509 +0.6875,0.4125,0.08418465,0.1683693 +0.6875,0.4125,0.1683693,0.08418465 +0.6875,0.4375,0.07500005,0.07499999 +0.6875,0.4375,0.053032994,0.10606605 +0.6875,0.4375,0.10606599,0.053032994 +0.6875,0.4375,0.094494104,0.094494045 +0.6875,0.4375,0.0668174,0.1336348 +0.6875,0.4375,0.1336348,0.0668174 +0.6875,0.4375,0.11905503,0.11905509 +0.6875,0.4375,0.08418465,0.1683693 +0.6875,0.4375,0.1683693,0.08418465 +0.6875,0.4625,0.07500005,0.07499999 +0.6875,0.4625,0.053032994,0.10606605 +0.6875,0.46249998,0.10606599,0.053032964 +0.6875,0.4625,0.094494104,0.094494045 +0.6875,0.46250004,0.0668174,0.13363484 +0.6875,0.46249998,0.1336348,0.06681737 +0.6875,0.4625,0.11905503,0.11905509 +0.6875,0.46249998,0.08418465,0.16836926 +0.6875,0.46249998,0.1683693,0.08418462 +0.6875,0.48749998,0.07500005,0.07499999 +0.6875,0.4875,0.053032994,0.10606602 +0.6875,0.4875,0.10606599,0.053032994 +0.6875,0.48749998,0.094494104,0.094494045 +0.6875,0.4875,0.0668174,0.13363484 +0.6875,0.4875,0.1336348,0.0668174 +0.6875,0.4875,0.11905503,0.11905506 +0.6875,0.4875,0.08418465,0.1683693 +0.6875,0.4875,0.1683693,0.08418465 +0.6875,0.5125,0.07500005,0.07500002 +0.6875,0.51250005,0.053032994,0.10606605 +0.6875,0.5125,0.10606599,0.053032964 +0.6875,0.5125,0.094494104,0.094494075 +0.6875,0.51250005,0.0668174,0.13363487 +0.6875,0.5125,0.1336348,0.06681737 +0.6875,0.51250005,0.11905503,0.11905509 +0.6875,0.5125,0.08418465,0.1683693 +0.6875,0.5125,0.1683693,0.08418465 +0.6875,0.5375,0.07500005,0.07499999 +0.6875,0.5375,0.053032994,0.10606605 +0.6875,0.5375,0.10606599,0.053032935 +0.6875,0.5375,0.094494104,0.094494045 +0.6875,0.5375,0.0668174,0.13363487 +0.6875,0.5375,0.1336348,0.06681734 +0.6875,0.5375,0.11905503,0.11905509 +0.6875,0.5375,0.08418465,0.16836932 +0.6875,0.5375,0.1683693,0.08418468 +0.6875,0.5625,0.07500005,0.07500005 +0.6875,0.5625,0.053032994,0.10606599 +0.6875,0.5625,0.10606599,0.053032994 +0.6875,0.5625,0.094494104,0.094494104 +0.6875,0.5625,0.0668174,0.13363484 +0.6875,0.5625,0.1336348,0.0668174 +0.6875,0.5625,0.11905503,0.11905503 +0.6875,0.5625,0.08418465,0.1683693 +0.6875,0.5625,0.1683693,0.08418465 +0.6875,0.5875,0.07500005,0.07499999 +0.6875,0.5875,0.053032994,0.10606605 +0.6875,0.5875,0.10606599,0.053032935 +0.6875,0.5875,0.094494104,0.094494045 +0.6875,0.5875,0.0668174,0.13363487 +0.6875,0.5875,0.1336348,0.06681734 +0.6875,0.5875,0.11905503,0.11905509 +0.6875,0.5875,0.08418465,0.1683693 +0.6875,0.5875,0.1683693,0.08418465 +0.6875,0.61249995,0.07500005,0.07499999 +0.6875,0.61249995,0.053032994,0.10606605 +0.6875,0.6125,0.10606599,0.053032994 +0.6875,0.61249995,0.094494104,0.094494045 +0.6875,0.61249995,0.0668174,0.13363487 +0.6875,0.6125,0.1336348,0.0668174 +0.6875,0.61249995,0.11905503,0.11905509 +0.6875,0.6125,0.08418465,0.1683693 +0.6875,0.6125,0.1683693,0.08418465 +0.6875,0.63750005,0.07500005,0.07499999 +0.6875,0.63750005,0.053032994,0.10606605 +0.6875,0.6375,0.10606599,0.053032994 +0.6875,0.63750005,0.094494104,0.094494045 +0.6875,0.63750005,0.0668174,0.13363487 +0.6875,0.6375,0.1336348,0.0668174 +0.6875,0.63750005,0.11905503,0.11905509 +0.6875,0.6375,0.08418465,0.1683693 +0.6875,0.6375,0.1683693,0.08418465 +0.6875,0.6625,0.07500005,0.07499999 +0.6875,0.6625,0.053032994,0.10606605 +0.6875,0.6625,0.10606599,0.053032935 +0.6875,0.6625,0.094494104,0.094494045 +0.6875,0.6625,0.0668174,0.13363487 +0.6875,0.6625,0.1336348,0.06681734 +0.6875,0.6625,0.11905503,0.11905509 +0.6875,0.6625,0.08418465,0.1683693 +0.6875,0.6625,0.1683693,0.08418465 +0.6875,0.6875,0.07500005,0.07500005 +0.6875,0.6875,0.053032994,0.10606599 +0.6875,0.6875,0.10606599,0.053032994 +0.6875,0.6875,0.094494104,0.094494104 +0.6875,0.6875,0.0668174,0.1336348 +0.6875,0.6875,0.1336348,0.0668174 +0.6875,0.6875,0.11905503,0.11905503 +0.6875,0.6875,0.08418465,0.1683693 +0.6875,0.6875,0.1683693,0.08418465 +0.6875,0.7125,0.07500005,0.07499999 +0.6875,0.7125,0.053032994,0.10606605 +0.6875,0.7125,0.10606599,0.053032935 +0.6875,0.7125,0.094494104,0.094494045 +0.6875,0.7125,0.0668174,0.13363487 +0.6875,0.7125,0.1336348,0.06681734 +0.6875,0.7125,0.11905503,0.11905509 +0.6875,0.7125,0.08418465,0.1683693 +0.6875,0.7125,0.1683693,0.08418465 +0.6875,0.73749995,0.07500005,0.07499999 +0.6875,0.73749995,0.053032994,0.10606605 +0.6875,0.7375,0.10606599,0.053032994 +0.6875,0.73749995,0.094494104,0.094494045 +0.6875,0.73749995,0.0668174,0.1336348 +0.6875,0.7375,0.1336348,0.0668174 +0.6875,0.73749995,0.11905503,0.11905509 +0.6875,0.7375,0.08418465,0.1683693 +0.6875,0.7375,0.1683693,0.08418465 +0.6875,0.76250005,0.07500005,0.07499999 +0.6875,0.7625,0.053032994,0.10606599 +0.6875,0.7625,0.10606599,0.053032994 +0.6875,0.76250005,0.094494104,0.094494045 +0.6875,0.7625,0.0668174,0.1336348 +0.6875,0.7625,0.1336348,0.0668174 +0.6875,0.7625,0.11905503,0.11905503 +0.6875,0.7625,0.08418465,0.1683693 +0.6875,0.7625,0.1683693,0.08418465 +0.6875,0.7875,0.07500005,0.07499999 +0.6875,0.78749996,0.053032994,0.10606599 +0.6875,0.7875,0.10606599,0.053032994 +0.6875,0.7875,0.094494104,0.094494045 +0.6875,0.78749996,0.0668174,0.1336348 +0.6875,0.7875,0.1336348,0.0668174 +0.6875,0.78749996,0.11905503,0.11905503 +0.6875,0.7875,0.08418465,0.1683693 +0.6875,0.7875,0.1683693,0.08418465 +0.6875,0.8125,0.07500005,0.07500005 +0.6875,0.8125,0.053032994,0.10606599 +0.6875,0.8125,0.10606599,0.053033054 +0.6875,0.8125,0.094494104,0.094494104 +0.6875,0.8125,0.0668174,0.1336348 +0.6875,0.8125,0.1336348,0.06681746 +0.6875,0.8125,0.11905503,0.11905503 +0.6875,0.8125,0.08418465,0.1683693 +0.6875,0.8125,0.1683693,0.08418465 +0.6875,0.8375,0.07500005,0.07499999 +0.6875,0.8375,0.053032994,0.10606599 +0.6875,0.8375,0.10606599,0.053033054 +0.6875,0.8375,0.094494104,0.094494045 +0.6875,0.8375,0.0668174,0.1336348 +0.6875,0.8375,0.1336348,0.06681746 +0.6875,0.8375,0.11905503,0.11905503 +0.6875,0.8375,0.08418465,0.1683693 +0.6875,0.8375,0.1683693,0.08418465 +0.6875,0.86249995,0.07500005,0.07499999 +0.6875,0.86249995,0.053032994,0.10606593 +0.6875,0.86249995,0.10606599,0.053033054 +0.6875,0.86249995,0.094494104,0.094494045 +0.6875,0.86249995,0.0668174,0.1336348 +0.6875,0.86249995,0.1336348,0.06681746 +0.6875,0.86249995,0.11905503,0.11905497 +0.6875,0.8625,0.08418465,0.1683693 +0.6875,0.8625,0.1683693,0.08418465 +0.6875,0.88750005,0.07500005,0.07499999 +0.6875,0.88750005,0.053032994,0.10606593 +0.6875,0.88750005,0.10606599,0.053033054 +0.6875,0.88750005,0.094494104,0.094494045 +0.6875,0.88750005,0.0668174,0.13363475 +0.6875,0.88750005,0.1336348,0.06681746 +0.6875,0.88750005,0.11905503,0.11905497 +0.6875,0.8875,0.08418465,0.1683693 +0.6875,0.8875,0.1683693,0.08418465 +0.6875,0.9125,0.07500005,0.07499999 +0.6875,0.9125,0.053032994,0.10606593 +0.6875,0.9125,0.10606599,0.053033054 +0.6875,0.9125,0.094494104,0.094494045 +0.6875,0.9125,0.0668174,0.13363475 +0.6875,0.9125,0.1336348,0.06681746 +0.6875,0.9125,0.11905503,0.11905497 +0.6875,0.9125,0.08418465,0.1683693 +0.6875,0.9125,0.1683693,0.08418465 +0.6875,0.9375,0.07500005,0.07500005 +0.6875,0.9375,0.053032994,0.10606599 +0.6875,0.9375,0.10606599,0.053033113 +0.6875,0.9375,0.094494104,0.094494104 +0.6875,0.9375,0.0668174,0.1336348 +0.6875,0.9375,0.1336348,0.06681752 +0.6875,0.9375,0.11905503,0.11905503 +0.6875,0.9375,0.08418465,0.1683693 +0.6875,0.9375,0.1683693,0.08418465 +0.6875,0.9625,0.07500005,0.07499999 +0.6875,0.9625,0.053032994,0.10606593 +0.6875,0.9625,0.10606599,0.053033054 +0.6875,0.9625,0.094494104,0.094494045 +0.6875,0.9625,0.0668174,0.13363475 +0.6875,0.9625,0.1336348,0.06681746 +0.6875,0.9625,0.11905503,0.11905497 +0.6875,0.9625,0.08418465,0.1683693 +0.6875,0.9625,0.1683693,0.08418465 +0.6875,0.98749995,0.07500005,0.07499999 +0.6875,0.98749995,0.053032994,0.10606593 +0.6875,0.98749995,0.10606599,0.053033054 +0.6875,0.98749995,0.094494104,0.094494045 +0.6875,0.98749995,0.0668174,0.13363475 +0.6875,0.98749995,0.1336348,0.06681746 +0.6875,0.98749995,0.11905503,0.11905497 +0.6875,0.98749995,0.08418465,0.16836923 +0.6875,0.98749995,0.1683693,0.08418459 +0.7125,0.0125,0.07499999,0.075 +0.7125,0.012499997,0.053032935,0.10606602 +0.7125,0.012499999,0.10606605,0.05303301 +0.7125,0.012499999,0.094494045,0.09449408 +0.7125,0.012500001,0.06681734,0.1336348 +0.7125,0.012499999,0.13363487,0.0668174 +0.7125,0.012500001,0.11905509,0.11905508 +0.7125,0.012499999,0.08418465,0.1683693 +0.7125,0.012500002,0.1683693,0.084184654 +0.7125,0.0375,0.07499999,0.075 +0.7125,0.037499998,0.053032935,0.10606601 +0.7125,0.0375,0.10606605,0.05303301 +0.7125,0.0375,0.094494045,0.094494075 +0.7125,0.0375,0.06681734,0.1336348 +0.7125,0.0375,0.13363487,0.0668174 +0.7125,0.0375,0.11905509,0.11905508 +0.7125,0.0375,0.08418465,0.16836931 +0.7125,0.0375,0.1683693,0.08418466 +0.7125,0.0625,0.07499999,0.075 +0.7125,0.0625,0.053032935,0.10606602 +0.7125,0.0625,0.10606605,0.05303301 +0.7125,0.0625,0.094494045,0.094494075 +0.7125,0.0625,0.06681734,0.1336348 +0.7125,0.0625,0.13363487,0.0668174 +0.7125,0.0625,0.11905509,0.11905508 +0.7125,0.0625,0.08418465,0.16836932 +0.7125,0.0625,0.1683693,0.08418465 +0.7125,0.0875,0.07499999,0.075 +0.7125,0.08749999,0.053032935,0.10606601 +0.7125,0.087500006,0.10606605,0.053033013 +0.7125,0.087500006,0.094494045,0.09449408 +0.7125,0.087500006,0.06681734,0.1336348 +0.7125,0.0875,0.13363487,0.0668174 +0.7125,0.0875,0.11905509,0.11905508 +0.7125,0.0875,0.08418465,0.16836931 +0.7125,0.087500006,0.1683693,0.084184654 +0.7125,0.112500004,0.07499999,0.075 +0.7125,0.1125,0.053032935,0.10606601 +0.7125,0.112500004,0.10606605,0.05303301 +0.7125,0.1125,0.094494045,0.094494075 +0.7125,0.1125,0.06681734,0.1336348 +0.7125,0.1125,0.13363487,0.0668174 +0.7125,0.1125,0.11905509,0.119055085 +0.7125,0.112500004,0.08418465,0.16836931 +0.7125,0.1125,0.1683693,0.08418465 +0.7125,0.1375,0.07499999,0.074999996 +0.7125,0.1375,0.053032935,0.10606602 +0.7125,0.1375,0.10606605,0.053033024 +0.7125,0.1375,0.094494045,0.09449408 +0.7125,0.1375,0.06681734,0.1336348 +0.7125,0.1375,0.13363487,0.0668174 +0.7125,0.13749999,0.11905509,0.11905508 +0.7125,0.1375,0.08418465,0.1683693 +0.7125,0.1375,0.1683693,0.084184654 +0.7125,0.1625,0.07499999,0.075 +0.7125,0.16250001,0.053032935,0.106066026 +0.7125,0.1625,0.10606605,0.05303301 +0.7125,0.1625,0.094494045,0.094494075 +0.7125,0.1625,0.06681734,0.1336348 +0.7125,0.1625,0.13363487,0.0668174 +0.7125,0.1625,0.11905509,0.11905508 +0.7125,0.1625,0.08418465,0.1683693 +0.7125,0.1625,0.1683693,0.08418464 +0.7125,0.1875,0.07499999,0.07499999 +0.7125,0.1875,0.053032935,0.10606603 +0.7125,0.1875,0.10606605,0.053033024 +0.7125,0.1875,0.094494045,0.09449406 +0.7125,0.1875,0.06681734,0.1336348 +0.7125,0.1875,0.13363487,0.06681742 +0.7125,0.1875,0.11905509,0.11905509 +0.7125,0.1875,0.08418465,0.16836931 +0.7125,0.1875,0.1683693,0.08418465 +0.7125,0.2125,0.07499999,0.075 +0.7125,0.2125,0.053032935,0.10606603 +0.7125,0.2125,0.10606605,0.05303301 +0.7125,0.21249999,0.094494045,0.094494075 +0.7125,0.2125,0.06681734,0.1336348 +0.7125,0.2125,0.13363487,0.0668174 +0.7125,0.2125,0.11905509,0.11905509 +0.7125,0.2125,0.08418465,0.16836931 +0.7125,0.2125,0.1683693,0.08418465 +0.7125,0.23750001,0.07499999,0.075 +0.7125,0.2375,0.053032935,0.10606602 +0.7125,0.2375,0.10606605,0.053033024 +0.7125,0.2375,0.094494045,0.094494075 +0.7125,0.23750001,0.06681734,0.13363482 +0.7125,0.2375,0.13363487,0.06681743 +0.7125,0.2375,0.11905509,0.11905506 +0.7125,0.2375,0.08418465,0.16836932 +0.7125,0.23750001,0.1683693,0.08418466 +0.7125,0.2625,0.07499999,0.07500002 +0.7125,0.2625,0.053032935,0.10606603 +0.7125,0.2625,0.10606605,0.053033024 +0.7125,0.2625,0.094494045,0.094494075 +0.7125,0.2625,0.06681734,0.13363479 +0.7125,0.2625,0.13363487,0.06681743 +0.7125,0.2625,0.11905509,0.11905508 +0.7125,0.2625,0.08418465,0.1683693 +0.7125,0.2625,0.1683693,0.08418463 +0.7125,0.2875,0.07499999,0.07499999 +0.7125,0.2875,0.053032935,0.10606603 +0.7125,0.28750002,0.10606605,0.053033024 +0.7125,0.2875,0.094494045,0.094494045 +0.7125,0.2875,0.06681734,0.1336348 +0.7125,0.28750002,0.13363487,0.06681743 +0.7125,0.2875,0.11905509,0.11905508 +0.7125,0.2875,0.08418465,0.1683693 +0.7125,0.2875,0.1683693,0.08418465 +0.7125,0.3125,0.07499999,0.07499999 +0.7125,0.3125,0.053032935,0.10606605 +0.7125,0.3125,0.10606605,0.053032994 +0.7125,0.3125,0.094494045,0.094494045 +0.7125,0.3125,0.06681734,0.1336348 +0.7125,0.3125,0.13363487,0.0668174 +0.7125,0.3125,0.11905509,0.11905509 +0.7125,0.3125,0.08418465,0.1683693 +0.7125,0.3125,0.1683693,0.08418465 +0.7125,0.3375,0.07499999,0.07499999 +0.7125,0.3375,0.053032935,0.10606605 +0.7125,0.33749998,0.10606605,0.053033024 +0.7125,0.3375,0.094494045,0.094494045 +0.7125,0.33750004,0.06681734,0.13363484 +0.7125,0.33749998,0.13363487,0.06681743 +0.7125,0.3375,0.11905509,0.11905509 +0.7125,0.3375,0.08418465,0.1683693 +0.7125,0.3375,0.1683693,0.08418465 +0.7125,0.3625,0.07499999,0.07500002 +0.7125,0.3625,0.053032935,0.10606602 +0.7125,0.3625,0.10606605,0.053033024 +0.7125,0.3625,0.094494045,0.094494075 +0.7125,0.3625,0.06681734,0.1336348 +0.7125,0.3625,0.13363487,0.06681743 +0.7125,0.3625,0.11905509,0.11905506 +0.7125,0.3625,0.08418465,0.1683693 +0.7125,0.3625,0.1683693,0.08418465 +0.7125,0.3875,0.07499999,0.07500002 +0.7125,0.3875,0.053032935,0.10606602 +0.7125,0.3875,0.10606605,0.053032994 +0.7125,0.3875,0.094494045,0.094494075 +0.7125,0.3875,0.06681734,0.13363484 +0.7125,0.3875,0.13363487,0.0668174 +0.7125,0.3875,0.11905509,0.11905506 +0.7125,0.3875,0.08418465,0.1683693 +0.7125,0.3875,0.1683693,0.08418465 +0.7125,0.4125,0.07499999,0.07499999 +0.7125,0.4125,0.053032935,0.10606605 +0.7125,0.4125,0.10606605,0.053032994 +0.7125,0.4125,0.094494045,0.094494045 +0.7125,0.41250002,0.06681734,0.13363484 +0.7125,0.4125,0.13363487,0.0668174 +0.7125,0.4125,0.11905509,0.11905509 +0.7125,0.4125,0.08418465,0.1683693 +0.7125,0.4125,0.1683693,0.08418465 +0.7125,0.4375,0.07499999,0.07499999 +0.7125,0.4375,0.053032935,0.10606605 +0.7125,0.4375,0.10606605,0.053032994 +0.7125,0.4375,0.094494045,0.094494045 +0.7125,0.4375,0.06681734,0.1336348 +0.7125,0.4375,0.13363487,0.0668174 +0.7125,0.4375,0.11905509,0.11905509 +0.7125,0.4375,0.08418465,0.1683693 +0.7125,0.4375,0.1683693,0.08418465 +0.7125,0.4625,0.07499999,0.07499999 +0.7125,0.4625,0.053032935,0.10606605 +0.7125,0.46249998,0.10606605,0.053032964 +0.7125,0.4625,0.094494045,0.094494045 +0.7125,0.46250004,0.06681734,0.13363484 +0.7125,0.46249998,0.13363487,0.06681737 +0.7125,0.4625,0.11905509,0.11905509 +0.7125,0.46249998,0.08418465,0.16836926 +0.7125,0.46249998,0.1683693,0.08418462 +0.7125,0.48749998,0.07499999,0.07499999 +0.7125,0.4875,0.053032935,0.10606602 +0.7125,0.4875,0.10606605,0.053032994 +0.7125,0.48749998,0.094494045,0.094494045 +0.7125,0.4875,0.06681734,0.13363484 +0.7125,0.4875,0.13363487,0.0668174 +0.7125,0.4875,0.11905509,0.11905506 +0.7125,0.4875,0.08418465,0.1683693 +0.7125,0.4875,0.1683693,0.08418465 +0.7125,0.5125,0.07499999,0.07500002 +0.7125,0.51250005,0.053032935,0.10606605 +0.7125,0.5125,0.10606605,0.053032964 +0.7125,0.5125,0.094494045,0.094494075 +0.7125,0.51250005,0.06681734,0.13363487 +0.7125,0.5125,0.13363487,0.06681737 +0.7125,0.51250005,0.11905509,0.11905509 +0.7125,0.5125,0.08418465,0.1683693 +0.7125,0.5125,0.1683693,0.08418465 +0.7125,0.5375,0.07499999,0.07499999 +0.7125,0.5375,0.053032935,0.10606605 +0.7125,0.5375,0.10606605,0.053032935 +0.7125,0.5375,0.094494045,0.094494045 +0.7125,0.5375,0.06681734,0.13363487 +0.7125,0.5375,0.13363487,0.06681734 +0.7125,0.5375,0.11905509,0.11905509 +0.7125,0.5375,0.08418465,0.16836932 +0.7125,0.5375,0.1683693,0.08418468 +0.7125,0.5625,0.07499999,0.07500005 +0.7125,0.5625,0.053032935,0.10606599 +0.7125,0.5625,0.10606605,0.053032994 +0.7125,0.5625,0.094494045,0.094494104 +0.7125,0.5625,0.06681734,0.13363484 +0.7125,0.5625,0.13363487,0.0668174 +0.7125,0.5625,0.11905509,0.11905503 +0.7125,0.5625,0.08418465,0.1683693 +0.7125,0.5625,0.1683693,0.08418465 +0.7125,0.5875,0.07499999,0.07499999 +0.7125,0.5875,0.053032935,0.10606605 +0.7125,0.5875,0.10606605,0.053032935 +0.7125,0.5875,0.094494045,0.094494045 +0.7125,0.5875,0.06681734,0.13363487 +0.7125,0.5875,0.13363487,0.06681734 +0.7125,0.5875,0.11905509,0.11905509 +0.7125,0.5875,0.08418465,0.1683693 +0.7125,0.5875,0.1683693,0.08418465 +0.7125,0.61249995,0.07499999,0.07499999 +0.7125,0.61249995,0.053032935,0.10606605 +0.7125,0.6125,0.10606605,0.053032994 +0.7125,0.61249995,0.094494045,0.094494045 +0.7125,0.61249995,0.06681734,0.13363487 +0.7125,0.6125,0.13363487,0.0668174 +0.7125,0.61249995,0.11905509,0.11905509 +0.7125,0.6125,0.08418465,0.1683693 +0.7125,0.6125,0.1683693,0.08418465 +0.7125,0.63750005,0.07499999,0.07499999 +0.7125,0.63750005,0.053032935,0.10606605 +0.7125,0.6375,0.10606605,0.053032994 +0.7125,0.63750005,0.094494045,0.094494045 +0.7125,0.63750005,0.06681734,0.13363487 +0.7125,0.6375,0.13363487,0.0668174 +0.7125,0.63750005,0.11905509,0.11905509 +0.7125,0.6375,0.08418465,0.1683693 +0.7125,0.6375,0.1683693,0.08418465 +0.7125,0.6625,0.07499999,0.07499999 +0.7125,0.6625,0.053032935,0.10606605 +0.7125,0.6625,0.10606605,0.053032935 +0.7125,0.6625,0.094494045,0.094494045 +0.7125,0.6625,0.06681734,0.13363487 +0.7125,0.6625,0.13363487,0.06681734 +0.7125,0.6625,0.11905509,0.11905509 +0.7125,0.6625,0.08418465,0.1683693 +0.7125,0.6625,0.1683693,0.08418465 +0.7125,0.6875,0.07499999,0.07500005 +0.7125,0.6875,0.053032935,0.10606599 +0.7125,0.6875,0.10606605,0.053032994 +0.7125,0.6875,0.094494045,0.094494104 +0.7125,0.6875,0.06681734,0.1336348 +0.7125,0.6875,0.13363487,0.0668174 +0.7125,0.6875,0.11905509,0.11905503 +0.7125,0.6875,0.08418465,0.1683693 +0.7125,0.6875,0.1683693,0.08418465 +0.7125,0.7125,0.07499999,0.07499999 +0.7125,0.7125,0.053032935,0.10606605 +0.7125,0.7125,0.10606605,0.053032935 +0.7125,0.7125,0.094494045,0.094494045 +0.7125,0.7125,0.06681734,0.13363487 +0.7125,0.7125,0.13363487,0.06681734 +0.7125,0.7125,0.11905509,0.11905509 +0.7125,0.7125,0.08418465,0.1683693 +0.7125,0.7125,0.1683693,0.08418465 +0.7125,0.73749995,0.07499999,0.07499999 +0.7125,0.73749995,0.053032935,0.10606605 +0.7125,0.7375,0.10606605,0.053032994 +0.7125,0.73749995,0.094494045,0.094494045 +0.7125,0.73749995,0.06681734,0.1336348 +0.7125,0.7375,0.13363487,0.0668174 +0.7125,0.73749995,0.11905509,0.11905509 +0.7125,0.7375,0.08418465,0.1683693 +0.7125,0.7375,0.1683693,0.08418465 +0.7125,0.76250005,0.07499999,0.07499999 +0.7125,0.7625,0.053032935,0.10606599 +0.7125,0.7625,0.10606605,0.053032994 +0.7125,0.76250005,0.094494045,0.094494045 +0.7125,0.7625,0.06681734,0.1336348 +0.7125,0.7625,0.13363487,0.0668174 +0.7125,0.7625,0.11905509,0.11905503 +0.7125,0.7625,0.08418465,0.1683693 +0.7125,0.7625,0.1683693,0.08418465 +0.7125,0.7875,0.07499999,0.07499999 +0.7125,0.78749996,0.053032935,0.10606599 +0.7125,0.7875,0.10606605,0.053032994 +0.7125,0.7875,0.094494045,0.094494045 +0.7125,0.78749996,0.06681734,0.1336348 +0.7125,0.7875,0.13363487,0.0668174 +0.7125,0.78749996,0.11905509,0.11905503 +0.7125,0.7875,0.08418465,0.1683693 +0.7125,0.7875,0.1683693,0.08418465 +0.7125,0.8125,0.07499999,0.07500005 +0.7125,0.8125,0.053032935,0.10606599 +0.7125,0.8125,0.10606605,0.053033054 +0.7125,0.8125,0.094494045,0.094494104 +0.7125,0.8125,0.06681734,0.1336348 +0.7125,0.8125,0.13363487,0.06681746 +0.7125,0.8125,0.11905509,0.11905503 +0.7125,0.8125,0.08418465,0.1683693 +0.7125,0.8125,0.1683693,0.08418465 +0.7125,0.8375,0.07499999,0.07499999 +0.7125,0.8375,0.053032935,0.10606599 +0.7125,0.8375,0.10606605,0.053033054 +0.7125,0.8375,0.094494045,0.094494045 +0.7125,0.8375,0.06681734,0.1336348 +0.7125,0.8375,0.13363487,0.06681746 +0.7125,0.8375,0.11905509,0.11905503 +0.7125,0.8375,0.08418465,0.1683693 +0.7125,0.8375,0.1683693,0.08418465 +0.7125,0.86249995,0.07499999,0.07499999 +0.7125,0.86249995,0.053032935,0.10606593 +0.7125,0.86249995,0.10606605,0.053033054 +0.7125,0.86249995,0.094494045,0.094494045 +0.7125,0.86249995,0.06681734,0.1336348 +0.7125,0.86249995,0.13363487,0.06681746 +0.7125,0.86249995,0.11905509,0.11905497 +0.7125,0.8625,0.08418465,0.1683693 +0.7125,0.8625,0.1683693,0.08418465 +0.7125,0.88750005,0.07499999,0.07499999 +0.7125,0.88750005,0.053032935,0.10606593 +0.7125,0.88750005,0.10606605,0.053033054 +0.7125,0.88750005,0.094494045,0.094494045 +0.7125,0.88750005,0.06681734,0.13363475 +0.7125,0.88750005,0.13363487,0.06681746 +0.7125,0.88750005,0.11905509,0.11905497 +0.7125,0.8875,0.08418465,0.1683693 +0.7125,0.8875,0.1683693,0.08418465 +0.7125,0.9125,0.07499999,0.07499999 +0.7125,0.9125,0.053032935,0.10606593 +0.7125,0.9125,0.10606605,0.053033054 +0.7125,0.9125,0.094494045,0.094494045 +0.7125,0.9125,0.06681734,0.13363475 +0.7125,0.9125,0.13363487,0.06681746 +0.7125,0.9125,0.11905509,0.11905497 +0.7125,0.9125,0.08418465,0.1683693 +0.7125,0.9125,0.1683693,0.08418465 +0.7125,0.9375,0.07499999,0.07500005 +0.7125,0.9375,0.053032935,0.10606599 +0.7125,0.9375,0.10606605,0.053033113 +0.7125,0.9375,0.094494045,0.094494104 +0.7125,0.9375,0.06681734,0.1336348 +0.7125,0.9375,0.13363487,0.06681752 +0.7125,0.9375,0.11905509,0.11905503 +0.7125,0.9375,0.08418465,0.1683693 +0.7125,0.9375,0.1683693,0.08418465 +0.7125,0.9625,0.07499999,0.07499999 +0.7125,0.9625,0.053032935,0.10606593 +0.7125,0.9625,0.10606605,0.053033054 +0.7125,0.9625,0.094494045,0.094494045 +0.7125,0.9625,0.06681734,0.13363475 +0.7125,0.9625,0.13363487,0.06681746 +0.7125,0.9625,0.11905509,0.11905497 +0.7125,0.9625,0.08418465,0.1683693 +0.7125,0.9625,0.1683693,0.08418465 +0.7125,0.98749995,0.07499999,0.07499999 +0.7125,0.98749995,0.053032935,0.10606593 +0.7125,0.98749995,0.10606605,0.053033054 +0.7125,0.98749995,0.094494045,0.094494045 +0.7125,0.98749995,0.06681734,0.13363475 +0.7125,0.98749995,0.13363487,0.06681746 +0.7125,0.98749995,0.11905509,0.11905497 +0.7125,0.98749995,0.08418465,0.16836923 +0.7125,0.98749995,0.1683693,0.08418459 +0.73749995,0.0125,0.07499999,0.075 +0.7375,0.012499997,0.053032994,0.10606602 +0.73749995,0.012499999,0.10606605,0.05303301 +0.73749995,0.012499999,0.094494045,0.09449408 +0.7375,0.012500001,0.0668174,0.1336348 +0.73749995,0.012499999,0.1336348,0.0668174 +0.73749995,0.012500001,0.11905509,0.11905508 +0.7375,0.012499999,0.08418465,0.1683693 +0.7375,0.012500002,0.1683693,0.084184654 +0.73749995,0.0375,0.07499999,0.075 +0.7375,0.037499998,0.053032994,0.10606601 +0.73749995,0.0375,0.10606605,0.05303301 +0.73749995,0.0375,0.094494045,0.094494075 +0.7375,0.0375,0.0668174,0.1336348 +0.73749995,0.0375,0.1336348,0.0668174 +0.73749995,0.0375,0.11905509,0.11905508 +0.7375,0.0375,0.08418465,0.16836931 +0.7375,0.0375,0.1683693,0.08418466 +0.73749995,0.0625,0.07499999,0.075 +0.7375,0.0625,0.053032994,0.10606602 +0.73749995,0.0625,0.10606605,0.05303301 +0.73749995,0.0625,0.094494045,0.094494075 +0.7375,0.0625,0.0668174,0.1336348 +0.73749995,0.0625,0.1336348,0.0668174 +0.73749995,0.0625,0.11905509,0.11905508 +0.7375,0.0625,0.08418465,0.16836932 +0.7375,0.0625,0.1683693,0.08418465 +0.73749995,0.0875,0.07499999,0.075 +0.7375,0.08749999,0.053032994,0.10606601 +0.73749995,0.087500006,0.10606605,0.053033013 +0.73749995,0.087500006,0.094494045,0.09449408 +0.7375,0.087500006,0.0668174,0.1336348 +0.73749995,0.0875,0.1336348,0.0668174 +0.73749995,0.0875,0.11905509,0.11905508 +0.7375,0.0875,0.08418465,0.16836931 +0.7375,0.087500006,0.1683693,0.084184654 +0.73749995,0.112500004,0.07499999,0.075 +0.7375,0.1125,0.053032994,0.10606601 +0.73749995,0.112500004,0.10606605,0.05303301 +0.73749995,0.1125,0.094494045,0.094494075 +0.7375,0.1125,0.0668174,0.1336348 +0.73749995,0.1125,0.1336348,0.0668174 +0.73749995,0.1125,0.11905509,0.119055085 +0.7375,0.112500004,0.08418465,0.16836931 +0.7375,0.1125,0.1683693,0.08418465 +0.73749995,0.1375,0.07499999,0.074999996 +0.7375,0.1375,0.053032994,0.10606602 +0.73749995,0.1375,0.10606605,0.053033024 +0.73749995,0.1375,0.094494045,0.09449408 +0.7375,0.1375,0.0668174,0.1336348 +0.73749995,0.1375,0.1336348,0.0668174 +0.73749995,0.13749999,0.11905509,0.11905508 +0.7375,0.1375,0.08418465,0.1683693 +0.7375,0.1375,0.1683693,0.084184654 +0.73749995,0.1625,0.07499999,0.075 +0.7375,0.16250001,0.053032994,0.106066026 +0.73749995,0.1625,0.10606605,0.05303301 +0.73749995,0.1625,0.094494045,0.094494075 +0.7375,0.1625,0.0668174,0.1336348 +0.73749995,0.1625,0.1336348,0.0668174 +0.73749995,0.1625,0.11905509,0.11905508 +0.7375,0.1625,0.08418465,0.1683693 +0.7375,0.1625,0.1683693,0.08418464 +0.73749995,0.1875,0.07499999,0.07499999 +0.7375,0.1875,0.053032994,0.10606603 +0.73749995,0.1875,0.10606605,0.053033024 +0.73749995,0.1875,0.094494045,0.09449406 +0.7375,0.1875,0.0668174,0.1336348 +0.73749995,0.1875,0.1336348,0.06681742 +0.73749995,0.1875,0.11905509,0.11905509 +0.7375,0.1875,0.08418465,0.16836931 +0.7375,0.1875,0.1683693,0.08418465 +0.73749995,0.2125,0.07499999,0.075 +0.7375,0.2125,0.053032994,0.10606603 +0.73749995,0.2125,0.10606605,0.05303301 +0.73749995,0.21249999,0.094494045,0.094494075 +0.7375,0.2125,0.0668174,0.1336348 +0.73749995,0.2125,0.1336348,0.0668174 +0.73749995,0.2125,0.11905509,0.11905509 +0.7375,0.2125,0.08418465,0.16836931 +0.7375,0.2125,0.1683693,0.08418465 +0.73749995,0.23750001,0.07499999,0.075 +0.7375,0.2375,0.053032994,0.10606602 +0.73749995,0.2375,0.10606605,0.053033024 +0.73749995,0.2375,0.094494045,0.094494075 +0.7375,0.23750001,0.0668174,0.13363482 +0.73749995,0.2375,0.1336348,0.06681743 +0.73749995,0.2375,0.11905509,0.11905506 +0.7375,0.2375,0.08418465,0.16836932 +0.7375,0.23750001,0.1683693,0.08418466 +0.73749995,0.2625,0.07499999,0.07500002 +0.7375,0.2625,0.053032994,0.10606603 +0.73749995,0.2625,0.10606605,0.053033024 +0.73749995,0.2625,0.094494045,0.094494075 +0.7375,0.2625,0.0668174,0.13363479 +0.73749995,0.2625,0.1336348,0.06681743 +0.73749995,0.2625,0.11905509,0.11905508 +0.7375,0.2625,0.08418465,0.1683693 +0.7375,0.2625,0.1683693,0.08418463 +0.73749995,0.2875,0.07499999,0.07499999 +0.7375,0.2875,0.053032994,0.10606603 +0.73749995,0.28750002,0.10606605,0.053033024 +0.73749995,0.2875,0.094494045,0.094494045 +0.7375,0.2875,0.0668174,0.1336348 +0.73749995,0.28750002,0.1336348,0.06681743 +0.73749995,0.2875,0.11905509,0.11905508 +0.7375,0.2875,0.08418465,0.1683693 +0.7375,0.2875,0.1683693,0.08418465 +0.73749995,0.3125,0.07499999,0.07499999 +0.7375,0.3125,0.053032994,0.10606605 +0.73749995,0.3125,0.10606605,0.053032994 +0.73749995,0.3125,0.094494045,0.094494045 +0.7375,0.3125,0.0668174,0.1336348 +0.73749995,0.3125,0.1336348,0.0668174 +0.73749995,0.3125,0.11905509,0.11905509 +0.7375,0.3125,0.08418465,0.1683693 +0.7375,0.3125,0.1683693,0.08418465 +0.73749995,0.3375,0.07499999,0.07499999 +0.7375,0.3375,0.053032994,0.10606605 +0.73749995,0.33749998,0.10606605,0.053033024 +0.73749995,0.3375,0.094494045,0.094494045 +0.7375,0.33750004,0.0668174,0.13363484 +0.73749995,0.33749998,0.1336348,0.06681743 +0.73749995,0.3375,0.11905509,0.11905509 +0.7375,0.3375,0.08418465,0.1683693 +0.7375,0.3375,0.1683693,0.08418465 +0.73749995,0.3625,0.07499999,0.07500002 +0.7375,0.3625,0.053032994,0.10606602 +0.73749995,0.3625,0.10606605,0.053033024 +0.73749995,0.3625,0.094494045,0.094494075 +0.7375,0.3625,0.0668174,0.1336348 +0.73749995,0.3625,0.1336348,0.06681743 +0.73749995,0.3625,0.11905509,0.11905506 +0.7375,0.3625,0.08418465,0.1683693 +0.7375,0.3625,0.1683693,0.08418465 +0.73749995,0.3875,0.07499999,0.07500002 +0.7375,0.3875,0.053032994,0.10606602 +0.73749995,0.3875,0.10606605,0.053032994 +0.73749995,0.3875,0.094494045,0.094494075 +0.7375,0.3875,0.0668174,0.13363484 +0.73749995,0.3875,0.1336348,0.0668174 +0.73749995,0.3875,0.11905509,0.11905506 +0.7375,0.3875,0.08418465,0.1683693 +0.7375,0.3875,0.1683693,0.08418465 +0.73749995,0.4125,0.07499999,0.07499999 +0.7375,0.4125,0.053032994,0.10606605 +0.73749995,0.4125,0.10606605,0.053032994 +0.73749995,0.4125,0.094494045,0.094494045 +0.7375,0.41250002,0.0668174,0.13363484 +0.73749995,0.4125,0.1336348,0.0668174 +0.73749995,0.4125,0.11905509,0.11905509 +0.7375,0.4125,0.08418465,0.1683693 +0.7375,0.4125,0.1683693,0.08418465 +0.73749995,0.4375,0.07499999,0.07499999 +0.7375,0.4375,0.053032994,0.10606605 +0.73749995,0.4375,0.10606605,0.053032994 +0.73749995,0.4375,0.094494045,0.094494045 +0.7375,0.4375,0.0668174,0.1336348 +0.73749995,0.4375,0.1336348,0.0668174 +0.73749995,0.4375,0.11905509,0.11905509 +0.7375,0.4375,0.08418465,0.1683693 +0.7375,0.4375,0.1683693,0.08418465 +0.73749995,0.4625,0.07499999,0.07499999 +0.7375,0.4625,0.053032994,0.10606605 +0.73749995,0.46249998,0.10606605,0.053032964 +0.73749995,0.4625,0.094494045,0.094494045 +0.7375,0.46250004,0.0668174,0.13363484 +0.73749995,0.46249998,0.1336348,0.06681737 +0.73749995,0.4625,0.11905509,0.11905509 +0.7375,0.46249998,0.08418465,0.16836926 +0.7375,0.46249998,0.1683693,0.08418462 +0.73749995,0.48749998,0.07499999,0.07499999 +0.7375,0.4875,0.053032994,0.10606602 +0.73749995,0.4875,0.10606605,0.053032994 +0.73749995,0.48749998,0.094494045,0.094494045 +0.7375,0.4875,0.0668174,0.13363484 +0.73749995,0.4875,0.1336348,0.0668174 +0.73749995,0.4875,0.11905509,0.11905506 +0.7375,0.4875,0.08418465,0.1683693 +0.7375,0.4875,0.1683693,0.08418465 +0.73749995,0.5125,0.07499999,0.07500002 +0.7375,0.51250005,0.053032994,0.10606605 +0.73749995,0.5125,0.10606605,0.053032964 +0.73749995,0.5125,0.094494045,0.094494075 +0.7375,0.51250005,0.0668174,0.13363487 +0.73749995,0.5125,0.1336348,0.06681737 +0.73749995,0.51250005,0.11905509,0.11905509 +0.7375,0.5125,0.08418465,0.1683693 +0.7375,0.5125,0.1683693,0.08418465 +0.73749995,0.5375,0.07499999,0.07499999 +0.7375,0.5375,0.053032994,0.10606605 +0.73749995,0.5375,0.10606605,0.053032935 +0.73749995,0.5375,0.094494045,0.094494045 +0.7375,0.5375,0.0668174,0.13363487 +0.73749995,0.5375,0.1336348,0.06681734 +0.73749995,0.5375,0.11905509,0.11905509 +0.7375,0.5375,0.08418465,0.16836932 +0.7375,0.5375,0.1683693,0.08418468 +0.73749995,0.5625,0.07499999,0.07500005 +0.7375,0.5625,0.053032994,0.10606599 +0.73749995,0.5625,0.10606605,0.053032994 +0.73749995,0.5625,0.094494045,0.094494104 +0.7375,0.5625,0.0668174,0.13363484 +0.73749995,0.5625,0.1336348,0.0668174 +0.73749995,0.5625,0.11905509,0.11905503 +0.7375,0.5625,0.08418465,0.1683693 +0.7375,0.5625,0.1683693,0.08418465 +0.73749995,0.5875,0.07499999,0.07499999 +0.7375,0.5875,0.053032994,0.10606605 +0.73749995,0.5875,0.10606605,0.053032935 +0.73749995,0.5875,0.094494045,0.094494045 +0.7375,0.5875,0.0668174,0.13363487 +0.73749995,0.5875,0.1336348,0.06681734 +0.73749995,0.5875,0.11905509,0.11905509 +0.7375,0.5875,0.08418465,0.1683693 +0.7375,0.5875,0.1683693,0.08418465 +0.73749995,0.61249995,0.07499999,0.07499999 +0.7375,0.61249995,0.053032994,0.10606605 +0.73749995,0.6125,0.10606605,0.053032994 +0.73749995,0.61249995,0.094494045,0.094494045 +0.7375,0.61249995,0.0668174,0.13363487 +0.73749995,0.6125,0.1336348,0.0668174 +0.73749995,0.61249995,0.11905509,0.11905509 +0.7375,0.6125,0.08418465,0.1683693 +0.7375,0.6125,0.1683693,0.08418465 +0.73749995,0.63750005,0.07499999,0.07499999 +0.7375,0.63750005,0.053032994,0.10606605 +0.73749995,0.6375,0.10606605,0.053032994 +0.73749995,0.63750005,0.094494045,0.094494045 +0.7375,0.63750005,0.0668174,0.13363487 +0.73749995,0.6375,0.1336348,0.0668174 +0.73749995,0.63750005,0.11905509,0.11905509 +0.7375,0.6375,0.08418465,0.1683693 +0.7375,0.6375,0.1683693,0.08418465 +0.73749995,0.6625,0.07499999,0.07499999 +0.7375,0.6625,0.053032994,0.10606605 +0.73749995,0.6625,0.10606605,0.053032935 +0.73749995,0.6625,0.094494045,0.094494045 +0.7375,0.6625,0.0668174,0.13363487 +0.73749995,0.6625,0.1336348,0.06681734 +0.73749995,0.6625,0.11905509,0.11905509 +0.7375,0.6625,0.08418465,0.1683693 +0.7375,0.6625,0.1683693,0.08418465 +0.73749995,0.6875,0.07499999,0.07500005 +0.7375,0.6875,0.053032994,0.10606599 +0.73749995,0.6875,0.10606605,0.053032994 +0.73749995,0.6875,0.094494045,0.094494104 +0.7375,0.6875,0.0668174,0.1336348 +0.73749995,0.6875,0.1336348,0.0668174 +0.73749995,0.6875,0.11905509,0.11905503 +0.7375,0.6875,0.08418465,0.1683693 +0.7375,0.6875,0.1683693,0.08418465 +0.73749995,0.7125,0.07499999,0.07499999 +0.7375,0.7125,0.053032994,0.10606605 +0.73749995,0.7125,0.10606605,0.053032935 +0.73749995,0.7125,0.094494045,0.094494045 +0.7375,0.7125,0.0668174,0.13363487 +0.73749995,0.7125,0.1336348,0.06681734 +0.73749995,0.7125,0.11905509,0.11905509 +0.7375,0.7125,0.08418465,0.1683693 +0.7375,0.7125,0.1683693,0.08418465 +0.73749995,0.73749995,0.07499999,0.07499999 +0.7375,0.73749995,0.053032994,0.10606605 +0.73749995,0.7375,0.10606605,0.053032994 +0.73749995,0.73749995,0.094494045,0.094494045 +0.7375,0.73749995,0.0668174,0.1336348 +0.73749995,0.7375,0.1336348,0.0668174 +0.73749995,0.73749995,0.11905509,0.11905509 +0.7375,0.7375,0.08418465,0.1683693 +0.7375,0.7375,0.1683693,0.08418465 +0.73749995,0.76250005,0.07499999,0.07499999 +0.7375,0.7625,0.053032994,0.10606599 +0.73749995,0.7625,0.10606605,0.053032994 +0.73749995,0.76250005,0.094494045,0.094494045 +0.7375,0.7625,0.0668174,0.1336348 +0.73749995,0.7625,0.1336348,0.0668174 +0.73749995,0.7625,0.11905509,0.11905503 +0.7375,0.7625,0.08418465,0.1683693 +0.7375,0.7625,0.1683693,0.08418465 +0.73749995,0.7875,0.07499999,0.07499999 +0.7375,0.78749996,0.053032994,0.10606599 +0.73749995,0.7875,0.10606605,0.053032994 +0.73749995,0.7875,0.094494045,0.094494045 +0.7375,0.78749996,0.0668174,0.1336348 +0.73749995,0.7875,0.1336348,0.0668174 +0.73749995,0.78749996,0.11905509,0.11905503 +0.7375,0.7875,0.08418465,0.1683693 +0.7375,0.7875,0.1683693,0.08418465 +0.73749995,0.8125,0.07499999,0.07500005 +0.7375,0.8125,0.053032994,0.10606599 +0.73749995,0.8125,0.10606605,0.053033054 +0.73749995,0.8125,0.094494045,0.094494104 +0.7375,0.8125,0.0668174,0.1336348 +0.73749995,0.8125,0.1336348,0.06681746 +0.73749995,0.8125,0.11905509,0.11905503 +0.7375,0.8125,0.08418465,0.1683693 +0.7375,0.8125,0.1683693,0.08418465 +0.73749995,0.8375,0.07499999,0.07499999 +0.7375,0.8375,0.053032994,0.10606599 +0.73749995,0.8375,0.10606605,0.053033054 +0.73749995,0.8375,0.094494045,0.094494045 +0.7375,0.8375,0.0668174,0.1336348 +0.73749995,0.8375,0.1336348,0.06681746 +0.73749995,0.8375,0.11905509,0.11905503 +0.7375,0.8375,0.08418465,0.1683693 +0.7375,0.8375,0.1683693,0.08418465 +0.73749995,0.86249995,0.07499999,0.07499999 +0.7375,0.86249995,0.053032994,0.10606593 +0.73749995,0.86249995,0.10606605,0.053033054 +0.73749995,0.86249995,0.094494045,0.094494045 +0.7375,0.86249995,0.0668174,0.1336348 +0.73749995,0.86249995,0.1336348,0.06681746 +0.73749995,0.86249995,0.11905509,0.11905497 +0.7375,0.8625,0.08418465,0.1683693 +0.7375,0.8625,0.1683693,0.08418465 +0.73749995,0.88750005,0.07499999,0.07499999 +0.7375,0.88750005,0.053032994,0.10606593 +0.73749995,0.88750005,0.10606605,0.053033054 +0.73749995,0.88750005,0.094494045,0.094494045 +0.7375,0.88750005,0.0668174,0.13363475 +0.73749995,0.88750005,0.1336348,0.06681746 +0.73749995,0.88750005,0.11905509,0.11905497 +0.7375,0.8875,0.08418465,0.1683693 +0.7375,0.8875,0.1683693,0.08418465 +0.73749995,0.9125,0.07499999,0.07499999 +0.7375,0.9125,0.053032994,0.10606593 +0.73749995,0.9125,0.10606605,0.053033054 +0.73749995,0.9125,0.094494045,0.094494045 +0.7375,0.9125,0.0668174,0.13363475 +0.73749995,0.9125,0.1336348,0.06681746 +0.73749995,0.9125,0.11905509,0.11905497 +0.7375,0.9125,0.08418465,0.1683693 +0.7375,0.9125,0.1683693,0.08418465 +0.73749995,0.9375,0.07499999,0.07500005 +0.7375,0.9375,0.053032994,0.10606599 +0.73749995,0.9375,0.10606605,0.053033113 +0.73749995,0.9375,0.094494045,0.094494104 +0.7375,0.9375,0.0668174,0.1336348 +0.73749995,0.9375,0.1336348,0.06681752 +0.73749995,0.9375,0.11905509,0.11905503 +0.7375,0.9375,0.08418465,0.1683693 +0.7375,0.9375,0.1683693,0.08418465 +0.73749995,0.9625,0.07499999,0.07499999 +0.7375,0.9625,0.053032994,0.10606593 +0.73749995,0.9625,0.10606605,0.053033054 +0.73749995,0.9625,0.094494045,0.094494045 +0.7375,0.9625,0.0668174,0.13363475 +0.73749995,0.9625,0.1336348,0.06681746 +0.73749995,0.9625,0.11905509,0.11905497 +0.7375,0.9625,0.08418465,0.1683693 +0.7375,0.9625,0.1683693,0.08418465 +0.73749995,0.98749995,0.07499999,0.07499999 +0.7375,0.98749995,0.053032994,0.10606593 +0.73749995,0.98749995,0.10606605,0.053033054 +0.73749995,0.98749995,0.094494045,0.094494045 +0.7375,0.98749995,0.0668174,0.13363475 +0.73749995,0.98749995,0.1336348,0.06681746 +0.73749995,0.98749995,0.11905509,0.11905497 +0.7375,0.98749995,0.08418465,0.16836923 +0.7375,0.98749995,0.1683693,0.08418459 +0.76250005,0.0125,0.07499999,0.075 +0.7625,0.012499997,0.053032994,0.10606602 +0.7625,0.012499999,0.10606599,0.05303301 +0.76250005,0.012499999,0.094494045,0.09449408 +0.7625,0.012500001,0.0668174,0.1336348 +0.7625,0.012499999,0.1336348,0.0668174 +0.7625,0.012500001,0.11905503,0.11905508 +0.7625,0.012499999,0.08418465,0.1683693 +0.7625,0.012500002,0.1683693,0.084184654 +0.76250005,0.0375,0.07499999,0.075 +0.7625,0.037499998,0.053032994,0.10606601 +0.7625,0.0375,0.10606599,0.05303301 +0.76250005,0.0375,0.094494045,0.094494075 +0.7625,0.0375,0.0668174,0.1336348 +0.7625,0.0375,0.1336348,0.0668174 +0.7625,0.0375,0.11905503,0.11905508 +0.7625,0.0375,0.08418465,0.16836931 +0.7625,0.0375,0.1683693,0.08418466 +0.76250005,0.0625,0.07499999,0.075 +0.7625,0.0625,0.053032994,0.10606602 +0.7625,0.0625,0.10606599,0.05303301 +0.76250005,0.0625,0.094494045,0.094494075 +0.7625,0.0625,0.0668174,0.1336348 +0.7625,0.0625,0.1336348,0.0668174 +0.7625,0.0625,0.11905503,0.11905508 +0.7625,0.0625,0.08418465,0.16836932 +0.7625,0.0625,0.1683693,0.08418465 +0.76250005,0.0875,0.07499999,0.075 +0.7625,0.08749999,0.053032994,0.10606601 +0.7625,0.087500006,0.10606599,0.053033013 +0.76250005,0.087500006,0.094494045,0.09449408 +0.7625,0.087500006,0.0668174,0.1336348 +0.7625,0.0875,0.1336348,0.0668174 +0.7625,0.0875,0.11905503,0.11905508 +0.7625,0.0875,0.08418465,0.16836931 +0.7625,0.087500006,0.1683693,0.084184654 +0.76250005,0.112500004,0.07499999,0.075 +0.7625,0.1125,0.053032994,0.10606601 +0.7625,0.112500004,0.10606599,0.05303301 +0.76250005,0.1125,0.094494045,0.094494075 +0.7625,0.1125,0.0668174,0.1336348 +0.7625,0.1125,0.1336348,0.0668174 +0.7625,0.1125,0.11905503,0.119055085 +0.7625,0.112500004,0.08418465,0.16836931 +0.7625,0.1125,0.1683693,0.08418465 +0.76250005,0.1375,0.07499999,0.074999996 +0.7625,0.1375,0.053032994,0.10606602 +0.7625,0.1375,0.10606599,0.053033024 +0.76250005,0.1375,0.094494045,0.09449408 +0.7625,0.1375,0.0668174,0.1336348 +0.7625,0.1375,0.1336348,0.0668174 +0.7625,0.13749999,0.11905503,0.11905508 +0.7625,0.1375,0.08418465,0.1683693 +0.7625,0.1375,0.1683693,0.084184654 +0.76250005,0.1625,0.07499999,0.075 +0.7625,0.16250001,0.053032994,0.106066026 +0.7625,0.1625,0.10606599,0.05303301 +0.76250005,0.1625,0.094494045,0.094494075 +0.7625,0.1625,0.0668174,0.1336348 +0.7625,0.1625,0.1336348,0.0668174 +0.7625,0.1625,0.11905503,0.11905508 +0.7625,0.1625,0.08418465,0.1683693 +0.7625,0.1625,0.1683693,0.08418464 +0.76250005,0.1875,0.07499999,0.07499999 +0.7625,0.1875,0.053032994,0.10606603 +0.7625,0.1875,0.10606599,0.053033024 +0.76250005,0.1875,0.094494045,0.09449406 +0.7625,0.1875,0.0668174,0.1336348 +0.7625,0.1875,0.1336348,0.06681742 +0.7625,0.1875,0.11905503,0.11905509 +0.7625,0.1875,0.08418465,0.16836931 +0.7625,0.1875,0.1683693,0.08418465 +0.76250005,0.2125,0.07499999,0.075 +0.7625,0.2125,0.053032994,0.10606603 +0.7625,0.2125,0.10606599,0.05303301 +0.76250005,0.21249999,0.094494045,0.094494075 +0.7625,0.2125,0.0668174,0.1336348 +0.7625,0.2125,0.1336348,0.0668174 +0.7625,0.2125,0.11905503,0.11905509 +0.7625,0.2125,0.08418465,0.16836931 +0.7625,0.2125,0.1683693,0.08418465 +0.76250005,0.23750001,0.07499999,0.075 +0.7625,0.2375,0.053032994,0.10606602 +0.7625,0.2375,0.10606599,0.053033024 +0.76250005,0.2375,0.094494045,0.094494075 +0.7625,0.23750001,0.0668174,0.13363482 +0.7625,0.2375,0.1336348,0.06681743 +0.7625,0.2375,0.11905503,0.11905506 +0.7625,0.2375,0.08418465,0.16836932 +0.7625,0.23750001,0.1683693,0.08418466 +0.76250005,0.2625,0.07499999,0.07500002 +0.7625,0.2625,0.053032994,0.10606603 +0.7625,0.2625,0.10606599,0.053033024 +0.76250005,0.2625,0.094494045,0.094494075 +0.7625,0.2625,0.0668174,0.13363479 +0.7625,0.2625,0.1336348,0.06681743 +0.7625,0.2625,0.11905503,0.11905508 +0.7625,0.2625,0.08418465,0.1683693 +0.7625,0.2625,0.1683693,0.08418463 +0.76250005,0.2875,0.07499999,0.07499999 +0.7625,0.2875,0.053032994,0.10606603 +0.7625,0.28750002,0.10606599,0.053033024 +0.76250005,0.2875,0.094494045,0.094494045 +0.7625,0.2875,0.0668174,0.1336348 +0.7625,0.28750002,0.1336348,0.06681743 +0.7625,0.2875,0.11905503,0.11905508 +0.7625,0.2875,0.08418465,0.1683693 +0.7625,0.2875,0.1683693,0.08418465 +0.76250005,0.3125,0.07499999,0.07499999 +0.7625,0.3125,0.053032994,0.10606605 +0.7625,0.3125,0.10606599,0.053032994 +0.76250005,0.3125,0.094494045,0.094494045 +0.7625,0.3125,0.0668174,0.1336348 +0.7625,0.3125,0.1336348,0.0668174 +0.7625,0.3125,0.11905503,0.11905509 +0.7625,0.3125,0.08418465,0.1683693 +0.7625,0.3125,0.1683693,0.08418465 +0.76250005,0.3375,0.07499999,0.07499999 +0.7625,0.3375,0.053032994,0.10606605 +0.7625,0.33749998,0.10606599,0.053033024 +0.76250005,0.3375,0.094494045,0.094494045 +0.7625,0.33750004,0.0668174,0.13363484 +0.7625,0.33749998,0.1336348,0.06681743 +0.7625,0.3375,0.11905503,0.11905509 +0.7625,0.3375,0.08418465,0.1683693 +0.7625,0.3375,0.1683693,0.08418465 +0.76250005,0.3625,0.07499999,0.07500002 +0.7625,0.3625,0.053032994,0.10606602 +0.7625,0.3625,0.10606599,0.053033024 +0.76250005,0.3625,0.094494045,0.094494075 +0.7625,0.3625,0.0668174,0.1336348 +0.7625,0.3625,0.1336348,0.06681743 +0.7625,0.3625,0.11905503,0.11905506 +0.7625,0.3625,0.08418465,0.1683693 +0.7625,0.3625,0.1683693,0.08418465 +0.76250005,0.3875,0.07499999,0.07500002 +0.7625,0.3875,0.053032994,0.10606602 +0.7625,0.3875,0.10606599,0.053032994 +0.76250005,0.3875,0.094494045,0.094494075 +0.7625,0.3875,0.0668174,0.13363484 +0.7625,0.3875,0.1336348,0.0668174 +0.7625,0.3875,0.11905503,0.11905506 +0.7625,0.3875,0.08418465,0.1683693 +0.7625,0.3875,0.1683693,0.08418465 +0.76250005,0.4125,0.07499999,0.07499999 +0.7625,0.4125,0.053032994,0.10606605 +0.7625,0.4125,0.10606599,0.053032994 +0.76250005,0.4125,0.094494045,0.094494045 +0.7625,0.41250002,0.0668174,0.13363484 +0.7625,0.4125,0.1336348,0.0668174 +0.7625,0.4125,0.11905503,0.11905509 +0.7625,0.4125,0.08418465,0.1683693 +0.7625,0.4125,0.1683693,0.08418465 +0.76250005,0.4375,0.07499999,0.07499999 +0.7625,0.4375,0.053032994,0.10606605 +0.7625,0.4375,0.10606599,0.053032994 +0.76250005,0.4375,0.094494045,0.094494045 +0.7625,0.4375,0.0668174,0.1336348 +0.7625,0.4375,0.1336348,0.0668174 +0.7625,0.4375,0.11905503,0.11905509 +0.7625,0.4375,0.08418465,0.1683693 +0.7625,0.4375,0.1683693,0.08418465 +0.76250005,0.4625,0.07499999,0.07499999 +0.7625,0.4625,0.053032994,0.10606605 +0.7625,0.46249998,0.10606599,0.053032964 +0.76250005,0.4625,0.094494045,0.094494045 +0.7625,0.46250004,0.0668174,0.13363484 +0.7625,0.46249998,0.1336348,0.06681737 +0.7625,0.4625,0.11905503,0.11905509 +0.7625,0.46249998,0.08418465,0.16836926 +0.7625,0.46249998,0.1683693,0.08418462 +0.76250005,0.48749998,0.07499999,0.07499999 +0.7625,0.4875,0.053032994,0.10606602 +0.7625,0.4875,0.10606599,0.053032994 +0.76250005,0.48749998,0.094494045,0.094494045 +0.7625,0.4875,0.0668174,0.13363484 +0.7625,0.4875,0.1336348,0.0668174 +0.7625,0.4875,0.11905503,0.11905506 +0.7625,0.4875,0.08418465,0.1683693 +0.7625,0.4875,0.1683693,0.08418465 +0.76250005,0.5125,0.07499999,0.07500002 +0.7625,0.51250005,0.053032994,0.10606605 +0.7625,0.5125,0.10606599,0.053032964 +0.76250005,0.5125,0.094494045,0.094494075 +0.7625,0.51250005,0.0668174,0.13363487 +0.7625,0.5125,0.1336348,0.06681737 +0.7625,0.51250005,0.11905503,0.11905509 +0.7625,0.5125,0.08418465,0.1683693 +0.7625,0.5125,0.1683693,0.08418465 +0.76250005,0.5375,0.07499999,0.07499999 +0.7625,0.5375,0.053032994,0.10606605 +0.7625,0.5375,0.10606599,0.053032935 +0.76250005,0.5375,0.094494045,0.094494045 +0.7625,0.5375,0.0668174,0.13363487 +0.7625,0.5375,0.1336348,0.06681734 +0.7625,0.5375,0.11905503,0.11905509 +0.7625,0.5375,0.08418465,0.16836932 +0.7625,0.5375,0.1683693,0.08418468 +0.76250005,0.5625,0.07499999,0.07500005 +0.7625,0.5625,0.053032994,0.10606599 +0.7625,0.5625,0.10606599,0.053032994 +0.76250005,0.5625,0.094494045,0.094494104 +0.7625,0.5625,0.0668174,0.13363484 +0.7625,0.5625,0.1336348,0.0668174 +0.7625,0.5625,0.11905503,0.11905503 +0.7625,0.5625,0.08418465,0.1683693 +0.7625,0.5625,0.1683693,0.08418465 +0.76250005,0.5875,0.07499999,0.07499999 +0.7625,0.5875,0.053032994,0.10606605 +0.7625,0.5875,0.10606599,0.053032935 +0.76250005,0.5875,0.094494045,0.094494045 +0.7625,0.5875,0.0668174,0.13363487 +0.7625,0.5875,0.1336348,0.06681734 +0.7625,0.5875,0.11905503,0.11905509 +0.7625,0.5875,0.08418465,0.1683693 +0.7625,0.5875,0.1683693,0.08418465 +0.76250005,0.61249995,0.07499999,0.07499999 +0.7625,0.61249995,0.053032994,0.10606605 +0.7625,0.6125,0.10606599,0.053032994 +0.76250005,0.61249995,0.094494045,0.094494045 +0.7625,0.61249995,0.0668174,0.13363487 +0.7625,0.6125,0.1336348,0.0668174 +0.7625,0.61249995,0.11905503,0.11905509 +0.7625,0.6125,0.08418465,0.1683693 +0.7625,0.6125,0.1683693,0.08418465 +0.76250005,0.63750005,0.07499999,0.07499999 +0.7625,0.63750005,0.053032994,0.10606605 +0.7625,0.6375,0.10606599,0.053032994 +0.76250005,0.63750005,0.094494045,0.094494045 +0.7625,0.63750005,0.0668174,0.13363487 +0.7625,0.6375,0.1336348,0.0668174 +0.7625,0.63750005,0.11905503,0.11905509 +0.7625,0.6375,0.08418465,0.1683693 +0.7625,0.6375,0.1683693,0.08418465 +0.76250005,0.6625,0.07499999,0.07499999 +0.7625,0.6625,0.053032994,0.10606605 +0.7625,0.6625,0.10606599,0.053032935 +0.76250005,0.6625,0.094494045,0.094494045 +0.7625,0.6625,0.0668174,0.13363487 +0.7625,0.6625,0.1336348,0.06681734 +0.7625,0.6625,0.11905503,0.11905509 +0.7625,0.6625,0.08418465,0.1683693 +0.7625,0.6625,0.1683693,0.08418465 +0.76250005,0.6875,0.07499999,0.07500005 +0.7625,0.6875,0.053032994,0.10606599 +0.7625,0.6875,0.10606599,0.053032994 +0.76250005,0.6875,0.094494045,0.094494104 +0.7625,0.6875,0.0668174,0.1336348 +0.7625,0.6875,0.1336348,0.0668174 +0.7625,0.6875,0.11905503,0.11905503 +0.7625,0.6875,0.08418465,0.1683693 +0.7625,0.6875,0.1683693,0.08418465 +0.76250005,0.7125,0.07499999,0.07499999 +0.7625,0.7125,0.053032994,0.10606605 +0.7625,0.7125,0.10606599,0.053032935 +0.76250005,0.7125,0.094494045,0.094494045 +0.7625,0.7125,0.0668174,0.13363487 +0.7625,0.7125,0.1336348,0.06681734 +0.7625,0.7125,0.11905503,0.11905509 +0.7625,0.7125,0.08418465,0.1683693 +0.7625,0.7125,0.1683693,0.08418465 +0.76250005,0.73749995,0.07499999,0.07499999 +0.7625,0.73749995,0.053032994,0.10606605 +0.7625,0.7375,0.10606599,0.053032994 +0.76250005,0.73749995,0.094494045,0.094494045 +0.7625,0.73749995,0.0668174,0.1336348 +0.7625,0.7375,0.1336348,0.0668174 +0.7625,0.73749995,0.11905503,0.11905509 +0.7625,0.7375,0.08418465,0.1683693 +0.7625,0.7375,0.1683693,0.08418465 +0.76250005,0.76250005,0.07499999,0.07499999 +0.7625,0.7625,0.053032994,0.10606599 +0.7625,0.7625,0.10606599,0.053032994 +0.76250005,0.76250005,0.094494045,0.094494045 +0.7625,0.7625,0.0668174,0.1336348 +0.7625,0.7625,0.1336348,0.0668174 +0.7625,0.7625,0.11905503,0.11905503 +0.7625,0.7625,0.08418465,0.1683693 +0.7625,0.7625,0.1683693,0.08418465 +0.76250005,0.7875,0.07499999,0.07499999 +0.7625,0.78749996,0.053032994,0.10606599 +0.7625,0.7875,0.10606599,0.053032994 +0.76250005,0.7875,0.094494045,0.094494045 +0.7625,0.78749996,0.0668174,0.1336348 +0.7625,0.7875,0.1336348,0.0668174 +0.7625,0.78749996,0.11905503,0.11905503 +0.7625,0.7875,0.08418465,0.1683693 +0.7625,0.7875,0.1683693,0.08418465 +0.76250005,0.8125,0.07499999,0.07500005 +0.7625,0.8125,0.053032994,0.10606599 +0.7625,0.8125,0.10606599,0.053033054 +0.76250005,0.8125,0.094494045,0.094494104 +0.7625,0.8125,0.0668174,0.1336348 +0.7625,0.8125,0.1336348,0.06681746 +0.7625,0.8125,0.11905503,0.11905503 +0.7625,0.8125,0.08418465,0.1683693 +0.7625,0.8125,0.1683693,0.08418465 +0.76250005,0.8375,0.07499999,0.07499999 +0.7625,0.8375,0.053032994,0.10606599 +0.7625,0.8375,0.10606599,0.053033054 +0.76250005,0.8375,0.094494045,0.094494045 +0.7625,0.8375,0.0668174,0.1336348 +0.7625,0.8375,0.1336348,0.06681746 +0.7625,0.8375,0.11905503,0.11905503 +0.7625,0.8375,0.08418465,0.1683693 +0.7625,0.8375,0.1683693,0.08418465 +0.76250005,0.86249995,0.07499999,0.07499999 +0.7625,0.86249995,0.053032994,0.10606593 +0.7625,0.86249995,0.10606599,0.053033054 +0.76250005,0.86249995,0.094494045,0.094494045 +0.7625,0.86249995,0.0668174,0.1336348 +0.7625,0.86249995,0.1336348,0.06681746 +0.7625,0.86249995,0.11905503,0.11905497 +0.7625,0.8625,0.08418465,0.1683693 +0.7625,0.8625,0.1683693,0.08418465 +0.76250005,0.88750005,0.07499999,0.07499999 +0.7625,0.88750005,0.053032994,0.10606593 +0.7625,0.88750005,0.10606599,0.053033054 +0.76250005,0.88750005,0.094494045,0.094494045 +0.7625,0.88750005,0.0668174,0.13363475 +0.7625,0.88750005,0.1336348,0.06681746 +0.7625,0.88750005,0.11905503,0.11905497 +0.7625,0.8875,0.08418465,0.1683693 +0.7625,0.8875,0.1683693,0.08418465 +0.76250005,0.9125,0.07499999,0.07499999 +0.7625,0.9125,0.053032994,0.10606593 +0.7625,0.9125,0.10606599,0.053033054 +0.76250005,0.9125,0.094494045,0.094494045 +0.7625,0.9125,0.0668174,0.13363475 +0.7625,0.9125,0.1336348,0.06681746 +0.7625,0.9125,0.11905503,0.11905497 +0.7625,0.9125,0.08418465,0.1683693 +0.7625,0.9125,0.1683693,0.08418465 +0.76250005,0.9375,0.07499999,0.07500005 +0.7625,0.9375,0.053032994,0.10606599 +0.7625,0.9375,0.10606599,0.053033113 +0.76250005,0.9375,0.094494045,0.094494104 +0.7625,0.9375,0.0668174,0.1336348 +0.7625,0.9375,0.1336348,0.06681752 +0.7625,0.9375,0.11905503,0.11905503 +0.7625,0.9375,0.08418465,0.1683693 +0.7625,0.9375,0.1683693,0.08418465 +0.76250005,0.9625,0.07499999,0.07499999 +0.7625,0.9625,0.053032994,0.10606593 +0.7625,0.9625,0.10606599,0.053033054 +0.76250005,0.9625,0.094494045,0.094494045 +0.7625,0.9625,0.0668174,0.13363475 +0.7625,0.9625,0.1336348,0.06681746 +0.7625,0.9625,0.11905503,0.11905497 +0.7625,0.9625,0.08418465,0.1683693 +0.7625,0.9625,0.1683693,0.08418465 +0.76250005,0.98749995,0.07499999,0.07499999 +0.7625,0.98749995,0.053032994,0.10606593 +0.7625,0.98749995,0.10606599,0.053033054 +0.76250005,0.98749995,0.094494045,0.094494045 +0.7625,0.98749995,0.0668174,0.13363475 +0.7625,0.98749995,0.1336348,0.06681746 +0.7625,0.98749995,0.11905503,0.11905497 +0.7625,0.98749995,0.08418465,0.16836923 +0.7625,0.98749995,0.1683693,0.08418459 +0.7875,0.0125,0.07499999,0.075 +0.7875,0.012499997,0.053032994,0.10606602 +0.78749996,0.012499999,0.10606599,0.05303301 +0.7875,0.012499999,0.094494045,0.09449408 +0.7875,0.012500001,0.0668174,0.1336348 +0.78749996,0.012499999,0.1336348,0.0668174 +0.78749996,0.012500001,0.11905503,0.11905508 +0.7875,0.012499999,0.08418465,0.1683693 +0.7875,0.012500002,0.1683693,0.084184654 +0.7875,0.0375,0.07499999,0.075 +0.7875,0.037499998,0.053032994,0.10606601 +0.78749996,0.0375,0.10606599,0.05303301 +0.7875,0.0375,0.094494045,0.094494075 +0.7875,0.0375,0.0668174,0.1336348 +0.78749996,0.0375,0.1336348,0.0668174 +0.78749996,0.0375,0.11905503,0.11905508 +0.7875,0.0375,0.08418465,0.16836931 +0.7875,0.0375,0.1683693,0.08418466 +0.7875,0.0625,0.07499999,0.075 +0.7875,0.0625,0.053032994,0.10606602 +0.78749996,0.0625,0.10606599,0.05303301 +0.7875,0.0625,0.094494045,0.094494075 +0.7875,0.0625,0.0668174,0.1336348 +0.78749996,0.0625,0.1336348,0.0668174 +0.78749996,0.0625,0.11905503,0.11905508 +0.7875,0.0625,0.08418465,0.16836932 +0.7875,0.0625,0.1683693,0.08418465 +0.7875,0.0875,0.07499999,0.075 +0.7875,0.08749999,0.053032994,0.10606601 +0.78749996,0.087500006,0.10606599,0.053033013 +0.7875,0.087500006,0.094494045,0.09449408 +0.7875,0.087500006,0.0668174,0.1336348 +0.78749996,0.0875,0.1336348,0.0668174 +0.78749996,0.0875,0.11905503,0.11905508 +0.7875,0.0875,0.08418465,0.16836931 +0.7875,0.087500006,0.1683693,0.084184654 +0.7875,0.112500004,0.07499999,0.075 +0.7875,0.1125,0.053032994,0.10606601 +0.78749996,0.112500004,0.10606599,0.05303301 +0.7875,0.1125,0.094494045,0.094494075 +0.7875,0.1125,0.0668174,0.1336348 +0.78749996,0.1125,0.1336348,0.0668174 +0.78749996,0.1125,0.11905503,0.119055085 +0.7875,0.112500004,0.08418465,0.16836931 +0.7875,0.1125,0.1683693,0.08418465 +0.7875,0.1375,0.07499999,0.074999996 +0.7875,0.1375,0.053032994,0.10606602 +0.78749996,0.1375,0.10606599,0.053033024 +0.7875,0.1375,0.094494045,0.09449408 +0.7875,0.1375,0.0668174,0.1336348 +0.78749996,0.1375,0.1336348,0.0668174 +0.78749996,0.13749999,0.11905503,0.11905508 +0.7875,0.1375,0.08418465,0.1683693 +0.7875,0.1375,0.1683693,0.084184654 +0.7875,0.1625,0.07499999,0.075 +0.7875,0.16250001,0.053032994,0.106066026 +0.78749996,0.1625,0.10606599,0.05303301 +0.7875,0.1625,0.094494045,0.094494075 +0.7875,0.1625,0.0668174,0.1336348 +0.78749996,0.1625,0.1336348,0.0668174 +0.78749996,0.1625,0.11905503,0.11905508 +0.7875,0.1625,0.08418465,0.1683693 +0.7875,0.1625,0.1683693,0.08418464 +0.7875,0.1875,0.07499999,0.07499999 +0.7875,0.1875,0.053032994,0.10606603 +0.78749996,0.1875,0.10606599,0.053033024 +0.7875,0.1875,0.094494045,0.09449406 +0.7875,0.1875,0.0668174,0.1336348 +0.78749996,0.1875,0.1336348,0.06681742 +0.78749996,0.1875,0.11905503,0.11905509 +0.7875,0.1875,0.08418465,0.16836931 +0.7875,0.1875,0.1683693,0.08418465 +0.7875,0.2125,0.07499999,0.075 +0.7875,0.2125,0.053032994,0.10606603 +0.78749996,0.2125,0.10606599,0.05303301 +0.7875,0.21249999,0.094494045,0.094494075 +0.7875,0.2125,0.0668174,0.1336348 +0.78749996,0.2125,0.1336348,0.0668174 +0.78749996,0.2125,0.11905503,0.11905509 +0.7875,0.2125,0.08418465,0.16836931 +0.7875,0.2125,0.1683693,0.08418465 +0.7875,0.23750001,0.07499999,0.075 +0.7875,0.2375,0.053032994,0.10606602 +0.78749996,0.2375,0.10606599,0.053033024 +0.7875,0.2375,0.094494045,0.094494075 +0.7875,0.23750001,0.0668174,0.13363482 +0.78749996,0.2375,0.1336348,0.06681743 +0.78749996,0.2375,0.11905503,0.11905506 +0.7875,0.2375,0.08418465,0.16836932 +0.7875,0.23750001,0.1683693,0.08418466 +0.7875,0.2625,0.07499999,0.07500002 +0.7875,0.2625,0.053032994,0.10606603 +0.78749996,0.2625,0.10606599,0.053033024 +0.7875,0.2625,0.094494045,0.094494075 +0.7875,0.2625,0.0668174,0.13363479 +0.78749996,0.2625,0.1336348,0.06681743 +0.78749996,0.2625,0.11905503,0.11905508 +0.7875,0.2625,0.08418465,0.1683693 +0.7875,0.2625,0.1683693,0.08418463 +0.7875,0.2875,0.07499999,0.07499999 +0.7875,0.2875,0.053032994,0.10606603 +0.78749996,0.28750002,0.10606599,0.053033024 +0.7875,0.2875,0.094494045,0.094494045 +0.7875,0.2875,0.0668174,0.1336348 +0.78749996,0.28750002,0.1336348,0.06681743 +0.78749996,0.2875,0.11905503,0.11905508 +0.7875,0.2875,0.08418465,0.1683693 +0.7875,0.2875,0.1683693,0.08418465 +0.7875,0.3125,0.07499999,0.07499999 +0.7875,0.3125,0.053032994,0.10606605 +0.78749996,0.3125,0.10606599,0.053032994 +0.7875,0.3125,0.094494045,0.094494045 +0.7875,0.3125,0.0668174,0.1336348 +0.78749996,0.3125,0.1336348,0.0668174 +0.78749996,0.3125,0.11905503,0.11905509 +0.7875,0.3125,0.08418465,0.1683693 +0.7875,0.3125,0.1683693,0.08418465 +0.7875,0.3375,0.07499999,0.07499999 +0.7875,0.3375,0.053032994,0.10606605 +0.78749996,0.33749998,0.10606599,0.053033024 +0.7875,0.3375,0.094494045,0.094494045 +0.7875,0.33750004,0.0668174,0.13363484 +0.78749996,0.33749998,0.1336348,0.06681743 +0.78749996,0.3375,0.11905503,0.11905509 +0.7875,0.3375,0.08418465,0.1683693 +0.7875,0.3375,0.1683693,0.08418465 +0.7875,0.3625,0.07499999,0.07500002 +0.7875,0.3625,0.053032994,0.10606602 +0.78749996,0.3625,0.10606599,0.053033024 +0.7875,0.3625,0.094494045,0.094494075 +0.7875,0.3625,0.0668174,0.1336348 +0.78749996,0.3625,0.1336348,0.06681743 +0.78749996,0.3625,0.11905503,0.11905506 +0.7875,0.3625,0.08418465,0.1683693 +0.7875,0.3625,0.1683693,0.08418465 +0.7875,0.3875,0.07499999,0.07500002 +0.7875,0.3875,0.053032994,0.10606602 +0.78749996,0.3875,0.10606599,0.053032994 +0.7875,0.3875,0.094494045,0.094494075 +0.7875,0.3875,0.0668174,0.13363484 +0.78749996,0.3875,0.1336348,0.0668174 +0.78749996,0.3875,0.11905503,0.11905506 +0.7875,0.3875,0.08418465,0.1683693 +0.7875,0.3875,0.1683693,0.08418465 +0.7875,0.4125,0.07499999,0.07499999 +0.7875,0.4125,0.053032994,0.10606605 +0.78749996,0.4125,0.10606599,0.053032994 +0.7875,0.4125,0.094494045,0.094494045 +0.7875,0.41250002,0.0668174,0.13363484 +0.78749996,0.4125,0.1336348,0.0668174 +0.78749996,0.4125,0.11905503,0.11905509 +0.7875,0.4125,0.08418465,0.1683693 +0.7875,0.4125,0.1683693,0.08418465 +0.7875,0.4375,0.07499999,0.07499999 +0.7875,0.4375,0.053032994,0.10606605 +0.78749996,0.4375,0.10606599,0.053032994 +0.7875,0.4375,0.094494045,0.094494045 +0.7875,0.4375,0.0668174,0.1336348 +0.78749996,0.4375,0.1336348,0.0668174 +0.78749996,0.4375,0.11905503,0.11905509 +0.7875,0.4375,0.08418465,0.1683693 +0.7875,0.4375,0.1683693,0.08418465 +0.7875,0.4625,0.07499999,0.07499999 +0.7875,0.4625,0.053032994,0.10606605 +0.78749996,0.46249998,0.10606599,0.053032964 +0.7875,0.4625,0.094494045,0.094494045 +0.7875,0.46250004,0.0668174,0.13363484 +0.78749996,0.46249998,0.1336348,0.06681737 +0.78749996,0.4625,0.11905503,0.11905509 +0.7875,0.46249998,0.08418465,0.16836926 +0.7875,0.46249998,0.1683693,0.08418462 +0.7875,0.48749998,0.07499999,0.07499999 +0.7875,0.4875,0.053032994,0.10606602 +0.78749996,0.4875,0.10606599,0.053032994 +0.7875,0.48749998,0.094494045,0.094494045 +0.7875,0.4875,0.0668174,0.13363484 +0.78749996,0.4875,0.1336348,0.0668174 +0.78749996,0.4875,0.11905503,0.11905506 +0.7875,0.4875,0.08418465,0.1683693 +0.7875,0.4875,0.1683693,0.08418465 +0.7875,0.5125,0.07499999,0.07500002 +0.7875,0.51250005,0.053032994,0.10606605 +0.78749996,0.5125,0.10606599,0.053032964 +0.7875,0.5125,0.094494045,0.094494075 +0.7875,0.51250005,0.0668174,0.13363487 +0.78749996,0.5125,0.1336348,0.06681737 +0.78749996,0.51250005,0.11905503,0.11905509 +0.7875,0.5125,0.08418465,0.1683693 +0.7875,0.5125,0.1683693,0.08418465 +0.7875,0.5375,0.07499999,0.07499999 +0.7875,0.5375,0.053032994,0.10606605 +0.78749996,0.5375,0.10606599,0.053032935 +0.7875,0.5375,0.094494045,0.094494045 +0.7875,0.5375,0.0668174,0.13363487 +0.78749996,0.5375,0.1336348,0.06681734 +0.78749996,0.5375,0.11905503,0.11905509 +0.7875,0.5375,0.08418465,0.16836932 +0.7875,0.5375,0.1683693,0.08418468 +0.7875,0.5625,0.07499999,0.07500005 +0.7875,0.5625,0.053032994,0.10606599 +0.78749996,0.5625,0.10606599,0.053032994 +0.7875,0.5625,0.094494045,0.094494104 +0.7875,0.5625,0.0668174,0.13363484 +0.78749996,0.5625,0.1336348,0.0668174 +0.78749996,0.5625,0.11905503,0.11905503 +0.7875,0.5625,0.08418465,0.1683693 +0.7875,0.5625,0.1683693,0.08418465 +0.7875,0.5875,0.07499999,0.07499999 +0.7875,0.5875,0.053032994,0.10606605 +0.78749996,0.5875,0.10606599,0.053032935 +0.7875,0.5875,0.094494045,0.094494045 +0.7875,0.5875,0.0668174,0.13363487 +0.78749996,0.5875,0.1336348,0.06681734 +0.78749996,0.5875,0.11905503,0.11905509 +0.7875,0.5875,0.08418465,0.1683693 +0.7875,0.5875,0.1683693,0.08418465 +0.7875,0.61249995,0.07499999,0.07499999 +0.7875,0.61249995,0.053032994,0.10606605 +0.78749996,0.6125,0.10606599,0.053032994 +0.7875,0.61249995,0.094494045,0.094494045 +0.7875,0.61249995,0.0668174,0.13363487 +0.78749996,0.6125,0.1336348,0.0668174 +0.78749996,0.61249995,0.11905503,0.11905509 +0.7875,0.6125,0.08418465,0.1683693 +0.7875,0.6125,0.1683693,0.08418465 +0.7875,0.63750005,0.07499999,0.07499999 +0.7875,0.63750005,0.053032994,0.10606605 +0.78749996,0.6375,0.10606599,0.053032994 +0.7875,0.63750005,0.094494045,0.094494045 +0.7875,0.63750005,0.0668174,0.13363487 +0.78749996,0.6375,0.1336348,0.0668174 +0.78749996,0.63750005,0.11905503,0.11905509 +0.7875,0.6375,0.08418465,0.1683693 +0.7875,0.6375,0.1683693,0.08418465 +0.7875,0.6625,0.07499999,0.07499999 +0.7875,0.6625,0.053032994,0.10606605 +0.78749996,0.6625,0.10606599,0.053032935 +0.7875,0.6625,0.094494045,0.094494045 +0.7875,0.6625,0.0668174,0.13363487 +0.78749996,0.6625,0.1336348,0.06681734 +0.78749996,0.6625,0.11905503,0.11905509 +0.7875,0.6625,0.08418465,0.1683693 +0.7875,0.6625,0.1683693,0.08418465 +0.7875,0.6875,0.07499999,0.07500005 +0.7875,0.6875,0.053032994,0.10606599 +0.78749996,0.6875,0.10606599,0.053032994 +0.7875,0.6875,0.094494045,0.094494104 +0.7875,0.6875,0.0668174,0.1336348 +0.78749996,0.6875,0.1336348,0.0668174 +0.78749996,0.6875,0.11905503,0.11905503 +0.7875,0.6875,0.08418465,0.1683693 +0.7875,0.6875,0.1683693,0.08418465 +0.7875,0.7125,0.07499999,0.07499999 +0.7875,0.7125,0.053032994,0.10606605 +0.78749996,0.7125,0.10606599,0.053032935 +0.7875,0.7125,0.094494045,0.094494045 +0.7875,0.7125,0.0668174,0.13363487 +0.78749996,0.7125,0.1336348,0.06681734 +0.78749996,0.7125,0.11905503,0.11905509 +0.7875,0.7125,0.08418465,0.1683693 +0.7875,0.7125,0.1683693,0.08418465 +0.7875,0.73749995,0.07499999,0.07499999 +0.7875,0.73749995,0.053032994,0.10606605 +0.78749996,0.7375,0.10606599,0.053032994 +0.7875,0.73749995,0.094494045,0.094494045 +0.7875,0.73749995,0.0668174,0.1336348 +0.78749996,0.7375,0.1336348,0.0668174 +0.78749996,0.73749995,0.11905503,0.11905509 +0.7875,0.7375,0.08418465,0.1683693 +0.7875,0.7375,0.1683693,0.08418465 +0.7875,0.76250005,0.07499999,0.07499999 +0.7875,0.7625,0.053032994,0.10606599 +0.78749996,0.7625,0.10606599,0.053032994 +0.7875,0.76250005,0.094494045,0.094494045 +0.7875,0.7625,0.0668174,0.1336348 +0.78749996,0.7625,0.1336348,0.0668174 +0.78749996,0.7625,0.11905503,0.11905503 +0.7875,0.7625,0.08418465,0.1683693 +0.7875,0.7625,0.1683693,0.08418465 +0.7875,0.7875,0.07499999,0.07499999 +0.7875,0.78749996,0.053032994,0.10606599 +0.78749996,0.7875,0.10606599,0.053032994 +0.7875,0.7875,0.094494045,0.094494045 +0.7875,0.78749996,0.0668174,0.1336348 +0.78749996,0.7875,0.1336348,0.0668174 +0.78749996,0.78749996,0.11905503,0.11905503 +0.7875,0.7875,0.08418465,0.1683693 +0.7875,0.7875,0.1683693,0.08418465 +0.7875,0.8125,0.07499999,0.07500005 +0.7875,0.8125,0.053032994,0.10606599 +0.78749996,0.8125,0.10606599,0.053033054 +0.7875,0.8125,0.094494045,0.094494104 +0.7875,0.8125,0.0668174,0.1336348 +0.78749996,0.8125,0.1336348,0.06681746 +0.78749996,0.8125,0.11905503,0.11905503 +0.7875,0.8125,0.08418465,0.1683693 +0.7875,0.8125,0.1683693,0.08418465 +0.7875,0.8375,0.07499999,0.07499999 +0.7875,0.8375,0.053032994,0.10606599 +0.78749996,0.8375,0.10606599,0.053033054 +0.7875,0.8375,0.094494045,0.094494045 +0.7875,0.8375,0.0668174,0.1336348 +0.78749996,0.8375,0.1336348,0.06681746 +0.78749996,0.8375,0.11905503,0.11905503 +0.7875,0.8375,0.08418465,0.1683693 +0.7875,0.8375,0.1683693,0.08418465 +0.7875,0.86249995,0.07499999,0.07499999 +0.7875,0.86249995,0.053032994,0.10606593 +0.78749996,0.86249995,0.10606599,0.053033054 +0.7875,0.86249995,0.094494045,0.094494045 +0.7875,0.86249995,0.0668174,0.1336348 +0.78749996,0.86249995,0.1336348,0.06681746 +0.78749996,0.86249995,0.11905503,0.11905497 +0.7875,0.8625,0.08418465,0.1683693 +0.7875,0.8625,0.1683693,0.08418465 +0.7875,0.88750005,0.07499999,0.07499999 +0.7875,0.88750005,0.053032994,0.10606593 +0.78749996,0.88750005,0.10606599,0.053033054 +0.7875,0.88750005,0.094494045,0.094494045 +0.7875,0.88750005,0.0668174,0.13363475 +0.78749996,0.88750005,0.1336348,0.06681746 +0.78749996,0.88750005,0.11905503,0.11905497 +0.7875,0.8875,0.08418465,0.1683693 +0.7875,0.8875,0.1683693,0.08418465 +0.7875,0.9125,0.07499999,0.07499999 +0.7875,0.9125,0.053032994,0.10606593 +0.78749996,0.9125,0.10606599,0.053033054 +0.7875,0.9125,0.094494045,0.094494045 +0.7875,0.9125,0.0668174,0.13363475 +0.78749996,0.9125,0.1336348,0.06681746 +0.78749996,0.9125,0.11905503,0.11905497 +0.7875,0.9125,0.08418465,0.1683693 +0.7875,0.9125,0.1683693,0.08418465 +0.7875,0.9375,0.07499999,0.07500005 +0.7875,0.9375,0.053032994,0.10606599 +0.78749996,0.9375,0.10606599,0.053033113 +0.7875,0.9375,0.094494045,0.094494104 +0.7875,0.9375,0.0668174,0.1336348 +0.78749996,0.9375,0.1336348,0.06681752 +0.78749996,0.9375,0.11905503,0.11905503 +0.7875,0.9375,0.08418465,0.1683693 +0.7875,0.9375,0.1683693,0.08418465 +0.7875,0.9625,0.07499999,0.07499999 +0.7875,0.9625,0.053032994,0.10606593 +0.78749996,0.9625,0.10606599,0.053033054 +0.7875,0.9625,0.094494045,0.094494045 +0.7875,0.9625,0.0668174,0.13363475 +0.78749996,0.9625,0.1336348,0.06681746 +0.78749996,0.9625,0.11905503,0.11905497 +0.7875,0.9625,0.08418465,0.1683693 +0.7875,0.9625,0.1683693,0.08418465 +0.7875,0.98749995,0.07499999,0.07499999 +0.7875,0.98749995,0.053032994,0.10606593 +0.78749996,0.98749995,0.10606599,0.053033054 +0.7875,0.98749995,0.094494045,0.094494045 +0.7875,0.98749995,0.0668174,0.13363475 +0.78749996,0.98749995,0.1336348,0.06681746 +0.78749996,0.98749995,0.11905503,0.11905497 +0.7875,0.98749995,0.08418465,0.16836923 +0.7875,0.98749995,0.1683693,0.08418459 +0.8125,0.0125,0.07500005,0.075 +0.8125,0.012499997,0.053033054,0.10606602 +0.8125,0.012499999,0.10606599,0.05303301 +0.8125,0.012499999,0.094494104,0.09449408 +0.8125,0.012500001,0.06681746,0.1336348 +0.8125,0.012499999,0.1336348,0.0668174 +0.8125,0.012500001,0.11905503,0.11905508 +0.8125,0.012499999,0.08418465,0.1683693 +0.8125,0.012500002,0.1683693,0.084184654 +0.8125,0.0375,0.07500005,0.075 +0.8125,0.037499998,0.053033054,0.10606601 +0.8125,0.0375,0.10606599,0.05303301 +0.8125,0.0375,0.094494104,0.094494075 +0.8125,0.0375,0.06681746,0.1336348 +0.8125,0.0375,0.1336348,0.0668174 +0.8125,0.0375,0.11905503,0.11905508 +0.8125,0.0375,0.08418465,0.16836931 +0.8125,0.0375,0.1683693,0.08418466 +0.8125,0.0625,0.07500005,0.075 +0.8125,0.0625,0.053033054,0.10606602 +0.8125,0.0625,0.10606599,0.05303301 +0.8125,0.0625,0.094494104,0.094494075 +0.8125,0.0625,0.06681746,0.1336348 +0.8125,0.0625,0.1336348,0.0668174 +0.8125,0.0625,0.11905503,0.11905508 +0.8125,0.0625,0.08418465,0.16836932 +0.8125,0.0625,0.1683693,0.08418465 +0.8125,0.0875,0.07500005,0.075 +0.8125,0.08749999,0.053033054,0.10606601 +0.8125,0.087500006,0.10606599,0.053033013 +0.8125,0.087500006,0.094494104,0.09449408 +0.8125,0.087500006,0.06681746,0.1336348 +0.8125,0.0875,0.1336348,0.0668174 +0.8125,0.0875,0.11905503,0.11905508 +0.8125,0.0875,0.08418465,0.16836931 +0.8125,0.087500006,0.1683693,0.084184654 +0.8125,0.112500004,0.07500005,0.075 +0.8125,0.1125,0.053033054,0.10606601 +0.8125,0.112500004,0.10606599,0.05303301 +0.8125,0.1125,0.094494104,0.094494075 +0.8125,0.1125,0.06681746,0.1336348 +0.8125,0.1125,0.1336348,0.0668174 +0.8125,0.1125,0.11905503,0.119055085 +0.8125,0.112500004,0.08418465,0.16836931 +0.8125,0.1125,0.1683693,0.08418465 +0.8125,0.1375,0.07500005,0.074999996 +0.8125,0.1375,0.053033054,0.10606602 +0.8125,0.1375,0.10606599,0.053033024 +0.8125,0.1375,0.094494104,0.09449408 +0.8125,0.1375,0.06681746,0.1336348 +0.8125,0.1375,0.1336348,0.0668174 +0.8125,0.13749999,0.11905503,0.11905508 +0.8125,0.1375,0.08418465,0.1683693 +0.8125,0.1375,0.1683693,0.084184654 +0.8125,0.1625,0.07500005,0.075 +0.8125,0.16250001,0.053033054,0.106066026 +0.8125,0.1625,0.10606599,0.05303301 +0.8125,0.1625,0.094494104,0.094494075 +0.8125,0.1625,0.06681746,0.1336348 +0.8125,0.1625,0.1336348,0.0668174 +0.8125,0.1625,0.11905503,0.11905508 +0.8125,0.1625,0.08418465,0.1683693 +0.8125,0.1625,0.1683693,0.08418464 +0.8125,0.1875,0.07500005,0.07499999 +0.8125,0.1875,0.053033054,0.10606603 +0.8125,0.1875,0.10606599,0.053033024 +0.8125,0.1875,0.094494104,0.09449406 +0.8125,0.1875,0.06681746,0.1336348 +0.8125,0.1875,0.1336348,0.06681742 +0.8125,0.1875,0.11905503,0.11905509 +0.8125,0.1875,0.08418465,0.16836931 +0.8125,0.1875,0.1683693,0.08418465 +0.8125,0.2125,0.07500005,0.075 +0.8125,0.2125,0.053033054,0.10606603 +0.8125,0.2125,0.10606599,0.05303301 +0.8125,0.21249999,0.094494104,0.094494075 +0.8125,0.2125,0.06681746,0.1336348 +0.8125,0.2125,0.1336348,0.0668174 +0.8125,0.2125,0.11905503,0.11905509 +0.8125,0.2125,0.08418465,0.16836931 +0.8125,0.2125,0.1683693,0.08418465 +0.8125,0.23750001,0.07500005,0.075 +0.8125,0.2375,0.053033054,0.10606602 +0.8125,0.2375,0.10606599,0.053033024 +0.8125,0.2375,0.094494104,0.094494075 +0.8125,0.23750001,0.06681746,0.13363482 +0.8125,0.2375,0.1336348,0.06681743 +0.8125,0.2375,0.11905503,0.11905506 +0.8125,0.2375,0.08418465,0.16836932 +0.8125,0.23750001,0.1683693,0.08418466 +0.8125,0.2625,0.07500005,0.07500002 +0.8125,0.2625,0.053033054,0.10606603 +0.8125,0.2625,0.10606599,0.053033024 +0.8125,0.2625,0.094494104,0.094494075 +0.8125,0.2625,0.06681746,0.13363479 +0.8125,0.2625,0.1336348,0.06681743 +0.8125,0.2625,0.11905503,0.11905508 +0.8125,0.2625,0.08418465,0.1683693 +0.8125,0.2625,0.1683693,0.08418463 +0.8125,0.2875,0.07500005,0.07499999 +0.8125,0.2875,0.053033054,0.10606603 +0.8125,0.28750002,0.10606599,0.053033024 +0.8125,0.2875,0.094494104,0.094494045 +0.8125,0.2875,0.06681746,0.1336348 +0.8125,0.28750002,0.1336348,0.06681743 +0.8125,0.2875,0.11905503,0.11905508 +0.8125,0.2875,0.08418465,0.1683693 +0.8125,0.2875,0.1683693,0.08418465 +0.8125,0.3125,0.07500005,0.07499999 +0.8125,0.3125,0.053033054,0.10606605 +0.8125,0.3125,0.10606599,0.053032994 +0.8125,0.3125,0.094494104,0.094494045 +0.8125,0.3125,0.06681746,0.1336348 +0.8125,0.3125,0.1336348,0.0668174 +0.8125,0.3125,0.11905503,0.11905509 +0.8125,0.3125,0.08418465,0.1683693 +0.8125,0.3125,0.1683693,0.08418465 +0.8125,0.3375,0.07500005,0.07499999 +0.8125,0.3375,0.053033054,0.10606605 +0.8125,0.33749998,0.10606599,0.053033024 +0.8125,0.3375,0.094494104,0.094494045 +0.8125,0.33750004,0.06681746,0.13363484 +0.8125,0.33749998,0.1336348,0.06681743 +0.8125,0.3375,0.11905503,0.11905509 +0.8125,0.3375,0.08418465,0.1683693 +0.8125,0.3375,0.1683693,0.08418465 +0.8125,0.3625,0.07500005,0.07500002 +0.8125,0.3625,0.053033054,0.10606602 +0.8125,0.3625,0.10606599,0.053033024 +0.8125,0.3625,0.094494104,0.094494075 +0.8125,0.3625,0.06681746,0.1336348 +0.8125,0.3625,0.1336348,0.06681743 +0.8125,0.3625,0.11905503,0.11905506 +0.8125,0.3625,0.08418465,0.1683693 +0.8125,0.3625,0.1683693,0.08418465 +0.8125,0.3875,0.07500005,0.07500002 +0.8125,0.3875,0.053033054,0.10606602 +0.8125,0.3875,0.10606599,0.053032994 +0.8125,0.3875,0.094494104,0.094494075 +0.8125,0.3875,0.06681746,0.13363484 +0.8125,0.3875,0.1336348,0.0668174 +0.8125,0.3875,0.11905503,0.11905506 +0.8125,0.3875,0.08418465,0.1683693 +0.8125,0.3875,0.1683693,0.08418465 +0.8125,0.4125,0.07500005,0.07499999 +0.8125,0.4125,0.053033054,0.10606605 +0.8125,0.4125,0.10606599,0.053032994 +0.8125,0.4125,0.094494104,0.094494045 +0.8125,0.41250002,0.06681746,0.13363484 +0.8125,0.4125,0.1336348,0.0668174 +0.8125,0.4125,0.11905503,0.11905509 +0.8125,0.4125,0.08418465,0.1683693 +0.8125,0.4125,0.1683693,0.08418465 +0.8125,0.4375,0.07500005,0.07499999 +0.8125,0.4375,0.053033054,0.10606605 +0.8125,0.4375,0.10606599,0.053032994 +0.8125,0.4375,0.094494104,0.094494045 +0.8125,0.4375,0.06681746,0.1336348 +0.8125,0.4375,0.1336348,0.0668174 +0.8125,0.4375,0.11905503,0.11905509 +0.8125,0.4375,0.08418465,0.1683693 +0.8125,0.4375,0.1683693,0.08418465 +0.8125,0.4625,0.07500005,0.07499999 +0.8125,0.4625,0.053033054,0.10606605 +0.8125,0.46249998,0.10606599,0.053032964 +0.8125,0.4625,0.094494104,0.094494045 +0.8125,0.46250004,0.06681746,0.13363484 +0.8125,0.46249998,0.1336348,0.06681737 +0.8125,0.4625,0.11905503,0.11905509 +0.8125,0.46249998,0.08418465,0.16836926 +0.8125,0.46249998,0.1683693,0.08418462 +0.8125,0.48749998,0.07500005,0.07499999 +0.8125,0.4875,0.053033054,0.10606602 +0.8125,0.4875,0.10606599,0.053032994 +0.8125,0.48749998,0.094494104,0.094494045 +0.8125,0.4875,0.06681746,0.13363484 +0.8125,0.4875,0.1336348,0.0668174 +0.8125,0.4875,0.11905503,0.11905506 +0.8125,0.4875,0.08418465,0.1683693 +0.8125,0.4875,0.1683693,0.08418465 +0.8125,0.5125,0.07500005,0.07500002 +0.8125,0.51250005,0.053033054,0.10606605 +0.8125,0.5125,0.10606599,0.053032964 +0.8125,0.5125,0.094494104,0.094494075 +0.8125,0.51250005,0.06681746,0.13363487 +0.8125,0.5125,0.1336348,0.06681737 +0.8125,0.51250005,0.11905503,0.11905509 +0.8125,0.5125,0.08418465,0.1683693 +0.8125,0.5125,0.1683693,0.08418465 +0.8125,0.5375,0.07500005,0.07499999 +0.8125,0.5375,0.053033054,0.10606605 +0.8125,0.5375,0.10606599,0.053032935 +0.8125,0.5375,0.094494104,0.094494045 +0.8125,0.5375,0.06681746,0.13363487 +0.8125,0.5375,0.1336348,0.06681734 +0.8125,0.5375,0.11905503,0.11905509 +0.8125,0.5375,0.08418465,0.16836932 +0.8125,0.5375,0.1683693,0.08418468 +0.8125,0.5625,0.07500005,0.07500005 +0.8125,0.5625,0.053033054,0.10606599 +0.8125,0.5625,0.10606599,0.053032994 +0.8125,0.5625,0.094494104,0.094494104 +0.8125,0.5625,0.06681746,0.13363484 +0.8125,0.5625,0.1336348,0.0668174 +0.8125,0.5625,0.11905503,0.11905503 +0.8125,0.5625,0.08418465,0.1683693 +0.8125,0.5625,0.1683693,0.08418465 +0.8125,0.5875,0.07500005,0.07499999 +0.8125,0.5875,0.053033054,0.10606605 +0.8125,0.5875,0.10606599,0.053032935 +0.8125,0.5875,0.094494104,0.094494045 +0.8125,0.5875,0.06681746,0.13363487 +0.8125,0.5875,0.1336348,0.06681734 +0.8125,0.5875,0.11905503,0.11905509 +0.8125,0.5875,0.08418465,0.1683693 +0.8125,0.5875,0.1683693,0.08418465 +0.8125,0.61249995,0.07500005,0.07499999 +0.8125,0.61249995,0.053033054,0.10606605 +0.8125,0.6125,0.10606599,0.053032994 +0.8125,0.61249995,0.094494104,0.094494045 +0.8125,0.61249995,0.06681746,0.13363487 +0.8125,0.6125,0.1336348,0.0668174 +0.8125,0.61249995,0.11905503,0.11905509 +0.8125,0.6125,0.08418465,0.1683693 +0.8125,0.6125,0.1683693,0.08418465 +0.8125,0.63750005,0.07500005,0.07499999 +0.8125,0.63750005,0.053033054,0.10606605 +0.8125,0.6375,0.10606599,0.053032994 +0.8125,0.63750005,0.094494104,0.094494045 +0.8125,0.63750005,0.06681746,0.13363487 +0.8125,0.6375,0.1336348,0.0668174 +0.8125,0.63750005,0.11905503,0.11905509 +0.8125,0.6375,0.08418465,0.1683693 +0.8125,0.6375,0.1683693,0.08418465 +0.8125,0.6625,0.07500005,0.07499999 +0.8125,0.6625,0.053033054,0.10606605 +0.8125,0.6625,0.10606599,0.053032935 +0.8125,0.6625,0.094494104,0.094494045 +0.8125,0.6625,0.06681746,0.13363487 +0.8125,0.6625,0.1336348,0.06681734 +0.8125,0.6625,0.11905503,0.11905509 +0.8125,0.6625,0.08418465,0.1683693 +0.8125,0.6625,0.1683693,0.08418465 +0.8125,0.6875,0.07500005,0.07500005 +0.8125,0.6875,0.053033054,0.10606599 +0.8125,0.6875,0.10606599,0.053032994 +0.8125,0.6875,0.094494104,0.094494104 +0.8125,0.6875,0.06681746,0.1336348 +0.8125,0.6875,0.1336348,0.0668174 +0.8125,0.6875,0.11905503,0.11905503 +0.8125,0.6875,0.08418465,0.1683693 +0.8125,0.6875,0.1683693,0.08418465 +0.8125,0.7125,0.07500005,0.07499999 +0.8125,0.7125,0.053033054,0.10606605 +0.8125,0.7125,0.10606599,0.053032935 +0.8125,0.7125,0.094494104,0.094494045 +0.8125,0.7125,0.06681746,0.13363487 +0.8125,0.7125,0.1336348,0.06681734 +0.8125,0.7125,0.11905503,0.11905509 +0.8125,0.7125,0.08418465,0.1683693 +0.8125,0.7125,0.1683693,0.08418465 +0.8125,0.73749995,0.07500005,0.07499999 +0.8125,0.73749995,0.053033054,0.10606605 +0.8125,0.7375,0.10606599,0.053032994 +0.8125,0.73749995,0.094494104,0.094494045 +0.8125,0.73749995,0.06681746,0.1336348 +0.8125,0.7375,0.1336348,0.0668174 +0.8125,0.73749995,0.11905503,0.11905509 +0.8125,0.7375,0.08418465,0.1683693 +0.8125,0.7375,0.1683693,0.08418465 +0.8125,0.76250005,0.07500005,0.07499999 +0.8125,0.7625,0.053033054,0.10606599 +0.8125,0.7625,0.10606599,0.053032994 +0.8125,0.76250005,0.094494104,0.094494045 +0.8125,0.7625,0.06681746,0.1336348 +0.8125,0.7625,0.1336348,0.0668174 +0.8125,0.7625,0.11905503,0.11905503 +0.8125,0.7625,0.08418465,0.1683693 +0.8125,0.7625,0.1683693,0.08418465 +0.8125,0.7875,0.07500005,0.07499999 +0.8125,0.78749996,0.053033054,0.10606599 +0.8125,0.7875,0.10606599,0.053032994 +0.8125,0.7875,0.094494104,0.094494045 +0.8125,0.78749996,0.06681746,0.1336348 +0.8125,0.7875,0.1336348,0.0668174 +0.8125,0.78749996,0.11905503,0.11905503 +0.8125,0.7875,0.08418465,0.1683693 +0.8125,0.7875,0.1683693,0.08418465 +0.8125,0.8125,0.07500005,0.07500005 +0.8125,0.8125,0.053033054,0.10606599 +0.8125,0.8125,0.10606599,0.053033054 +0.8125,0.8125,0.094494104,0.094494104 +0.8125,0.8125,0.06681746,0.1336348 +0.8125,0.8125,0.1336348,0.06681746 +0.8125,0.8125,0.11905503,0.11905503 +0.8125,0.8125,0.08418465,0.1683693 +0.8125,0.8125,0.1683693,0.08418465 +0.8125,0.8375,0.07500005,0.07499999 +0.8125,0.8375,0.053033054,0.10606599 +0.8125,0.8375,0.10606599,0.053033054 +0.8125,0.8375,0.094494104,0.094494045 +0.8125,0.8375,0.06681746,0.1336348 +0.8125,0.8375,0.1336348,0.06681746 +0.8125,0.8375,0.11905503,0.11905503 +0.8125,0.8375,0.08418465,0.1683693 +0.8125,0.8375,0.1683693,0.08418465 +0.8125,0.86249995,0.07500005,0.07499999 +0.8125,0.86249995,0.053033054,0.10606593 +0.8125,0.86249995,0.10606599,0.053033054 +0.8125,0.86249995,0.094494104,0.094494045 +0.8125,0.86249995,0.06681746,0.1336348 +0.8125,0.86249995,0.1336348,0.06681746 +0.8125,0.86249995,0.11905503,0.11905497 +0.8125,0.8625,0.08418465,0.1683693 +0.8125,0.8625,0.1683693,0.08418465 +0.8125,0.88750005,0.07500005,0.07499999 +0.8125,0.88750005,0.053033054,0.10606593 +0.8125,0.88750005,0.10606599,0.053033054 +0.8125,0.88750005,0.094494104,0.094494045 +0.8125,0.88750005,0.06681746,0.13363475 +0.8125,0.88750005,0.1336348,0.06681746 +0.8125,0.88750005,0.11905503,0.11905497 +0.8125,0.8875,0.08418465,0.1683693 +0.8125,0.8875,0.1683693,0.08418465 +0.8125,0.9125,0.07500005,0.07499999 +0.8125,0.9125,0.053033054,0.10606593 +0.8125,0.9125,0.10606599,0.053033054 +0.8125,0.9125,0.094494104,0.094494045 +0.8125,0.9125,0.06681746,0.13363475 +0.8125,0.9125,0.1336348,0.06681746 +0.8125,0.9125,0.11905503,0.11905497 +0.8125,0.9125,0.08418465,0.1683693 +0.8125,0.9125,0.1683693,0.08418465 +0.8125,0.9375,0.07500005,0.07500005 +0.8125,0.9375,0.053033054,0.10606599 +0.8125,0.9375,0.10606599,0.053033113 +0.8125,0.9375,0.094494104,0.094494104 +0.8125,0.9375,0.06681746,0.1336348 +0.8125,0.9375,0.1336348,0.06681752 +0.8125,0.9375,0.11905503,0.11905503 +0.8125,0.9375,0.08418465,0.1683693 +0.8125,0.9375,0.1683693,0.08418465 +0.8125,0.9625,0.07500005,0.07499999 +0.8125,0.9625,0.053033054,0.10606593 +0.8125,0.9625,0.10606599,0.053033054 +0.8125,0.9625,0.094494104,0.094494045 +0.8125,0.9625,0.06681746,0.13363475 +0.8125,0.9625,0.1336348,0.06681746 +0.8125,0.9625,0.11905503,0.11905497 +0.8125,0.9625,0.08418465,0.1683693 +0.8125,0.9625,0.1683693,0.08418465 +0.8125,0.98749995,0.07500005,0.07499999 +0.8125,0.98749995,0.053033054,0.10606593 +0.8125,0.98749995,0.10606599,0.053033054 +0.8125,0.98749995,0.094494104,0.094494045 +0.8125,0.98749995,0.06681746,0.13363475 +0.8125,0.98749995,0.1336348,0.06681746 +0.8125,0.98749995,0.11905503,0.11905497 +0.8125,0.98749995,0.08418465,0.16836923 +0.8125,0.98749995,0.1683693,0.08418459 +0.8375,0.0125,0.07499999,0.075 +0.8375,0.012499997,0.053033054,0.10606602 +0.8375,0.012499999,0.10606599,0.05303301 +0.8375,0.012499999,0.094494045,0.09449408 +0.8375,0.012500001,0.06681746,0.1336348 +0.8375,0.012499999,0.1336348,0.0668174 +0.8375,0.012500001,0.11905503,0.11905508 +0.8375,0.012499999,0.08418465,0.1683693 +0.8375,0.012500002,0.1683693,0.084184654 +0.8375,0.0375,0.07499999,0.075 +0.8375,0.037499998,0.053033054,0.10606601 +0.8375,0.0375,0.10606599,0.05303301 +0.8375,0.0375,0.094494045,0.094494075 +0.8375,0.0375,0.06681746,0.1336348 +0.8375,0.0375,0.1336348,0.0668174 +0.8375,0.0375,0.11905503,0.11905508 +0.8375,0.0375,0.08418465,0.16836931 +0.8375,0.0375,0.1683693,0.08418466 +0.8375,0.0625,0.07499999,0.075 +0.8375,0.0625,0.053033054,0.10606602 +0.8375,0.0625,0.10606599,0.05303301 +0.8375,0.0625,0.094494045,0.094494075 +0.8375,0.0625,0.06681746,0.1336348 +0.8375,0.0625,0.1336348,0.0668174 +0.8375,0.0625,0.11905503,0.11905508 +0.8375,0.0625,0.08418465,0.16836932 +0.8375,0.0625,0.1683693,0.08418465 +0.8375,0.0875,0.07499999,0.075 +0.8375,0.08749999,0.053033054,0.10606601 +0.8375,0.087500006,0.10606599,0.053033013 +0.8375,0.087500006,0.094494045,0.09449408 +0.8375,0.087500006,0.06681746,0.1336348 +0.8375,0.0875,0.1336348,0.0668174 +0.8375,0.0875,0.11905503,0.11905508 +0.8375,0.0875,0.08418465,0.16836931 +0.8375,0.087500006,0.1683693,0.084184654 +0.8375,0.112500004,0.07499999,0.075 +0.8375,0.1125,0.053033054,0.10606601 +0.8375,0.112500004,0.10606599,0.05303301 +0.8375,0.1125,0.094494045,0.094494075 +0.8375,0.1125,0.06681746,0.1336348 +0.8375,0.1125,0.1336348,0.0668174 +0.8375,0.1125,0.11905503,0.119055085 +0.8375,0.112500004,0.08418465,0.16836931 +0.8375,0.1125,0.1683693,0.08418465 +0.8375,0.1375,0.07499999,0.074999996 +0.8375,0.1375,0.053033054,0.10606602 +0.8375,0.1375,0.10606599,0.053033024 +0.8375,0.1375,0.094494045,0.09449408 +0.8375,0.1375,0.06681746,0.1336348 +0.8375,0.1375,0.1336348,0.0668174 +0.8375,0.13749999,0.11905503,0.11905508 +0.8375,0.1375,0.08418465,0.1683693 +0.8375,0.1375,0.1683693,0.084184654 +0.8375,0.1625,0.07499999,0.075 +0.8375,0.16250001,0.053033054,0.106066026 +0.8375,0.1625,0.10606599,0.05303301 +0.8375,0.1625,0.094494045,0.094494075 +0.8375,0.1625,0.06681746,0.1336348 +0.8375,0.1625,0.1336348,0.0668174 +0.8375,0.1625,0.11905503,0.11905508 +0.8375,0.1625,0.08418465,0.1683693 +0.8375,0.1625,0.1683693,0.08418464 +0.8375,0.1875,0.07499999,0.07499999 +0.8375,0.1875,0.053033054,0.10606603 +0.8375,0.1875,0.10606599,0.053033024 +0.8375,0.1875,0.094494045,0.09449406 +0.8375,0.1875,0.06681746,0.1336348 +0.8375,0.1875,0.1336348,0.06681742 +0.8375,0.1875,0.11905503,0.11905509 +0.8375,0.1875,0.08418465,0.16836931 +0.8375,0.1875,0.1683693,0.08418465 +0.8375,0.2125,0.07499999,0.075 +0.8375,0.2125,0.053033054,0.10606603 +0.8375,0.2125,0.10606599,0.05303301 +0.8375,0.21249999,0.094494045,0.094494075 +0.8375,0.2125,0.06681746,0.1336348 +0.8375,0.2125,0.1336348,0.0668174 +0.8375,0.2125,0.11905503,0.11905509 +0.8375,0.2125,0.08418465,0.16836931 +0.8375,0.2125,0.1683693,0.08418465 +0.8375,0.23750001,0.07499999,0.075 +0.8375,0.2375,0.053033054,0.10606602 +0.8375,0.2375,0.10606599,0.053033024 +0.8375,0.2375,0.094494045,0.094494075 +0.8375,0.23750001,0.06681746,0.13363482 +0.8375,0.2375,0.1336348,0.06681743 +0.8375,0.2375,0.11905503,0.11905506 +0.8375,0.2375,0.08418465,0.16836932 +0.8375,0.23750001,0.1683693,0.08418466 +0.8375,0.2625,0.07499999,0.07500002 +0.8375,0.2625,0.053033054,0.10606603 +0.8375,0.2625,0.10606599,0.053033024 +0.8375,0.2625,0.094494045,0.094494075 +0.8375,0.2625,0.06681746,0.13363479 +0.8375,0.2625,0.1336348,0.06681743 +0.8375,0.2625,0.11905503,0.11905508 +0.8375,0.2625,0.08418465,0.1683693 +0.8375,0.2625,0.1683693,0.08418463 +0.8375,0.2875,0.07499999,0.07499999 +0.8375,0.2875,0.053033054,0.10606603 +0.8375,0.28750002,0.10606599,0.053033024 +0.8375,0.2875,0.094494045,0.094494045 +0.8375,0.2875,0.06681746,0.1336348 +0.8375,0.28750002,0.1336348,0.06681743 +0.8375,0.2875,0.11905503,0.11905508 +0.8375,0.2875,0.08418465,0.1683693 +0.8375,0.2875,0.1683693,0.08418465 +0.8375,0.3125,0.07499999,0.07499999 +0.8375,0.3125,0.053033054,0.10606605 +0.8375,0.3125,0.10606599,0.053032994 +0.8375,0.3125,0.094494045,0.094494045 +0.8375,0.3125,0.06681746,0.1336348 +0.8375,0.3125,0.1336348,0.0668174 +0.8375,0.3125,0.11905503,0.11905509 +0.8375,0.3125,0.08418465,0.1683693 +0.8375,0.3125,0.1683693,0.08418465 +0.8375,0.3375,0.07499999,0.07499999 +0.8375,0.3375,0.053033054,0.10606605 +0.8375,0.33749998,0.10606599,0.053033024 +0.8375,0.3375,0.094494045,0.094494045 +0.8375,0.33750004,0.06681746,0.13363484 +0.8375,0.33749998,0.1336348,0.06681743 +0.8375,0.3375,0.11905503,0.11905509 +0.8375,0.3375,0.08418465,0.1683693 +0.8375,0.3375,0.1683693,0.08418465 +0.8375,0.3625,0.07499999,0.07500002 +0.8375,0.3625,0.053033054,0.10606602 +0.8375,0.3625,0.10606599,0.053033024 +0.8375,0.3625,0.094494045,0.094494075 +0.8375,0.3625,0.06681746,0.1336348 +0.8375,0.3625,0.1336348,0.06681743 +0.8375,0.3625,0.11905503,0.11905506 +0.8375,0.3625,0.08418465,0.1683693 +0.8375,0.3625,0.1683693,0.08418465 +0.8375,0.3875,0.07499999,0.07500002 +0.8375,0.3875,0.053033054,0.10606602 +0.8375,0.3875,0.10606599,0.053032994 +0.8375,0.3875,0.094494045,0.094494075 +0.8375,0.3875,0.06681746,0.13363484 +0.8375,0.3875,0.1336348,0.0668174 +0.8375,0.3875,0.11905503,0.11905506 +0.8375,0.3875,0.08418465,0.1683693 +0.8375,0.3875,0.1683693,0.08418465 +0.8375,0.4125,0.07499999,0.07499999 +0.8375,0.4125,0.053033054,0.10606605 +0.8375,0.4125,0.10606599,0.053032994 +0.8375,0.4125,0.094494045,0.094494045 +0.8375,0.41250002,0.06681746,0.13363484 +0.8375,0.4125,0.1336348,0.0668174 +0.8375,0.4125,0.11905503,0.11905509 +0.8375,0.4125,0.08418465,0.1683693 +0.8375,0.4125,0.1683693,0.08418465 +0.8375,0.4375,0.07499999,0.07499999 +0.8375,0.4375,0.053033054,0.10606605 +0.8375,0.4375,0.10606599,0.053032994 +0.8375,0.4375,0.094494045,0.094494045 +0.8375,0.4375,0.06681746,0.1336348 +0.8375,0.4375,0.1336348,0.0668174 +0.8375,0.4375,0.11905503,0.11905509 +0.8375,0.4375,0.08418465,0.1683693 +0.8375,0.4375,0.1683693,0.08418465 +0.8375,0.4625,0.07499999,0.07499999 +0.8375,0.4625,0.053033054,0.10606605 +0.8375,0.46249998,0.10606599,0.053032964 +0.8375,0.4625,0.094494045,0.094494045 +0.8375,0.46250004,0.06681746,0.13363484 +0.8375,0.46249998,0.1336348,0.06681737 +0.8375,0.4625,0.11905503,0.11905509 +0.8375,0.46249998,0.08418465,0.16836926 +0.8375,0.46249998,0.1683693,0.08418462 +0.8375,0.48749998,0.07499999,0.07499999 +0.8375,0.4875,0.053033054,0.10606602 +0.8375,0.4875,0.10606599,0.053032994 +0.8375,0.48749998,0.094494045,0.094494045 +0.8375,0.4875,0.06681746,0.13363484 +0.8375,0.4875,0.1336348,0.0668174 +0.8375,0.4875,0.11905503,0.11905506 +0.8375,0.4875,0.08418465,0.1683693 +0.8375,0.4875,0.1683693,0.08418465 +0.8375,0.5125,0.07499999,0.07500002 +0.8375,0.51250005,0.053033054,0.10606605 +0.8375,0.5125,0.10606599,0.053032964 +0.8375,0.5125,0.094494045,0.094494075 +0.8375,0.51250005,0.06681746,0.13363487 +0.8375,0.5125,0.1336348,0.06681737 +0.8375,0.51250005,0.11905503,0.11905509 +0.8375,0.5125,0.08418465,0.1683693 +0.8375,0.5125,0.1683693,0.08418465 +0.8375,0.5375,0.07499999,0.07499999 +0.8375,0.5375,0.053033054,0.10606605 +0.8375,0.5375,0.10606599,0.053032935 +0.8375,0.5375,0.094494045,0.094494045 +0.8375,0.5375,0.06681746,0.13363487 +0.8375,0.5375,0.1336348,0.06681734 +0.8375,0.5375,0.11905503,0.11905509 +0.8375,0.5375,0.08418465,0.16836932 +0.8375,0.5375,0.1683693,0.08418468 +0.8375,0.5625,0.07499999,0.07500005 +0.8375,0.5625,0.053033054,0.10606599 +0.8375,0.5625,0.10606599,0.053032994 +0.8375,0.5625,0.094494045,0.094494104 +0.8375,0.5625,0.06681746,0.13363484 +0.8375,0.5625,0.1336348,0.0668174 +0.8375,0.5625,0.11905503,0.11905503 +0.8375,0.5625,0.08418465,0.1683693 +0.8375,0.5625,0.1683693,0.08418465 +0.8375,0.5875,0.07499999,0.07499999 +0.8375,0.5875,0.053033054,0.10606605 +0.8375,0.5875,0.10606599,0.053032935 +0.8375,0.5875,0.094494045,0.094494045 +0.8375,0.5875,0.06681746,0.13363487 +0.8375,0.5875,0.1336348,0.06681734 +0.8375,0.5875,0.11905503,0.11905509 +0.8375,0.5875,0.08418465,0.1683693 +0.8375,0.5875,0.1683693,0.08418465 +0.8375,0.61249995,0.07499999,0.07499999 +0.8375,0.61249995,0.053033054,0.10606605 +0.8375,0.6125,0.10606599,0.053032994 +0.8375,0.61249995,0.094494045,0.094494045 +0.8375,0.61249995,0.06681746,0.13363487 +0.8375,0.6125,0.1336348,0.0668174 +0.8375,0.61249995,0.11905503,0.11905509 +0.8375,0.6125,0.08418465,0.1683693 +0.8375,0.6125,0.1683693,0.08418465 +0.8375,0.63750005,0.07499999,0.07499999 +0.8375,0.63750005,0.053033054,0.10606605 +0.8375,0.6375,0.10606599,0.053032994 +0.8375,0.63750005,0.094494045,0.094494045 +0.8375,0.63750005,0.06681746,0.13363487 +0.8375,0.6375,0.1336348,0.0668174 +0.8375,0.63750005,0.11905503,0.11905509 +0.8375,0.6375,0.08418465,0.1683693 +0.8375,0.6375,0.1683693,0.08418465 +0.8375,0.6625,0.07499999,0.07499999 +0.8375,0.6625,0.053033054,0.10606605 +0.8375,0.6625,0.10606599,0.053032935 +0.8375,0.6625,0.094494045,0.094494045 +0.8375,0.6625,0.06681746,0.13363487 +0.8375,0.6625,0.1336348,0.06681734 +0.8375,0.6625,0.11905503,0.11905509 +0.8375,0.6625,0.08418465,0.1683693 +0.8375,0.6625,0.1683693,0.08418465 +0.8375,0.6875,0.07499999,0.07500005 +0.8375,0.6875,0.053033054,0.10606599 +0.8375,0.6875,0.10606599,0.053032994 +0.8375,0.6875,0.094494045,0.094494104 +0.8375,0.6875,0.06681746,0.1336348 +0.8375,0.6875,0.1336348,0.0668174 +0.8375,0.6875,0.11905503,0.11905503 +0.8375,0.6875,0.08418465,0.1683693 +0.8375,0.6875,0.1683693,0.08418465 +0.8375,0.7125,0.07499999,0.07499999 +0.8375,0.7125,0.053033054,0.10606605 +0.8375,0.7125,0.10606599,0.053032935 +0.8375,0.7125,0.094494045,0.094494045 +0.8375,0.7125,0.06681746,0.13363487 +0.8375,0.7125,0.1336348,0.06681734 +0.8375,0.7125,0.11905503,0.11905509 +0.8375,0.7125,0.08418465,0.1683693 +0.8375,0.7125,0.1683693,0.08418465 +0.8375,0.73749995,0.07499999,0.07499999 +0.8375,0.73749995,0.053033054,0.10606605 +0.8375,0.7375,0.10606599,0.053032994 +0.8375,0.73749995,0.094494045,0.094494045 +0.8375,0.73749995,0.06681746,0.1336348 +0.8375,0.7375,0.1336348,0.0668174 +0.8375,0.73749995,0.11905503,0.11905509 +0.8375,0.7375,0.08418465,0.1683693 +0.8375,0.7375,0.1683693,0.08418465 +0.8375,0.76250005,0.07499999,0.07499999 +0.8375,0.7625,0.053033054,0.10606599 +0.8375,0.7625,0.10606599,0.053032994 +0.8375,0.76250005,0.094494045,0.094494045 +0.8375,0.7625,0.06681746,0.1336348 +0.8375,0.7625,0.1336348,0.0668174 +0.8375,0.7625,0.11905503,0.11905503 +0.8375,0.7625,0.08418465,0.1683693 +0.8375,0.7625,0.1683693,0.08418465 +0.8375,0.7875,0.07499999,0.07499999 +0.8375,0.78749996,0.053033054,0.10606599 +0.8375,0.7875,0.10606599,0.053032994 +0.8375,0.7875,0.094494045,0.094494045 +0.8375,0.78749996,0.06681746,0.1336348 +0.8375,0.7875,0.1336348,0.0668174 +0.8375,0.78749996,0.11905503,0.11905503 +0.8375,0.7875,0.08418465,0.1683693 +0.8375,0.7875,0.1683693,0.08418465 +0.8375,0.8125,0.07499999,0.07500005 +0.8375,0.8125,0.053033054,0.10606599 +0.8375,0.8125,0.10606599,0.053033054 +0.8375,0.8125,0.094494045,0.094494104 +0.8375,0.8125,0.06681746,0.1336348 +0.8375,0.8125,0.1336348,0.06681746 +0.8375,0.8125,0.11905503,0.11905503 +0.8375,0.8125,0.08418465,0.1683693 +0.8375,0.8125,0.1683693,0.08418465 +0.8375,0.8375,0.07499999,0.07499999 +0.8375,0.8375,0.053033054,0.10606599 +0.8375,0.8375,0.10606599,0.053033054 +0.8375,0.8375,0.094494045,0.094494045 +0.8375,0.8375,0.06681746,0.1336348 +0.8375,0.8375,0.1336348,0.06681746 +0.8375,0.8375,0.11905503,0.11905503 +0.8375,0.8375,0.08418465,0.1683693 +0.8375,0.8375,0.1683693,0.08418465 +0.8375,0.86249995,0.07499999,0.07499999 +0.8375,0.86249995,0.053033054,0.10606593 +0.8375,0.86249995,0.10606599,0.053033054 +0.8375,0.86249995,0.094494045,0.094494045 +0.8375,0.86249995,0.06681746,0.1336348 +0.8375,0.86249995,0.1336348,0.06681746 +0.8375,0.86249995,0.11905503,0.11905497 +0.8375,0.8625,0.08418465,0.1683693 +0.8375,0.8625,0.1683693,0.08418465 +0.8375,0.88750005,0.07499999,0.07499999 +0.8375,0.88750005,0.053033054,0.10606593 +0.8375,0.88750005,0.10606599,0.053033054 +0.8375,0.88750005,0.094494045,0.094494045 +0.8375,0.88750005,0.06681746,0.13363475 +0.8375,0.88750005,0.1336348,0.06681746 +0.8375,0.88750005,0.11905503,0.11905497 +0.8375,0.8875,0.08418465,0.1683693 +0.8375,0.8875,0.1683693,0.08418465 +0.8375,0.9125,0.07499999,0.07499999 +0.8375,0.9125,0.053033054,0.10606593 +0.8375,0.9125,0.10606599,0.053033054 +0.8375,0.9125,0.094494045,0.094494045 +0.8375,0.9125,0.06681746,0.13363475 +0.8375,0.9125,0.1336348,0.06681746 +0.8375,0.9125,0.11905503,0.11905497 +0.8375,0.9125,0.08418465,0.1683693 +0.8375,0.9125,0.1683693,0.08418465 +0.8375,0.9375,0.07499999,0.07500005 +0.8375,0.9375,0.053033054,0.10606599 +0.8375,0.9375,0.10606599,0.053033113 +0.8375,0.9375,0.094494045,0.094494104 +0.8375,0.9375,0.06681746,0.1336348 +0.8375,0.9375,0.1336348,0.06681752 +0.8375,0.9375,0.11905503,0.11905503 +0.8375,0.9375,0.08418465,0.1683693 +0.8375,0.9375,0.1683693,0.08418465 +0.8375,0.9625,0.07499999,0.07499999 +0.8375,0.9625,0.053033054,0.10606593 +0.8375,0.9625,0.10606599,0.053033054 +0.8375,0.9625,0.094494045,0.094494045 +0.8375,0.9625,0.06681746,0.13363475 +0.8375,0.9625,0.1336348,0.06681746 +0.8375,0.9625,0.11905503,0.11905497 +0.8375,0.9625,0.08418465,0.1683693 +0.8375,0.9625,0.1683693,0.08418465 +0.8375,0.98749995,0.07499999,0.07499999 +0.8375,0.98749995,0.053033054,0.10606593 +0.8375,0.98749995,0.10606599,0.053033054 +0.8375,0.98749995,0.094494045,0.094494045 +0.8375,0.98749995,0.06681746,0.13363475 +0.8375,0.98749995,0.1336348,0.06681746 +0.8375,0.98749995,0.11905503,0.11905497 +0.8375,0.98749995,0.08418465,0.16836923 +0.8375,0.98749995,0.1683693,0.08418459 +0.86249995,0.0125,0.07499999,0.075 +0.86249995,0.012499997,0.053033054,0.10606602 +0.86249995,0.012499999,0.10606593,0.05303301 +0.86249995,0.012499999,0.094494045,0.09449408 +0.86249995,0.012500001,0.06681746,0.1336348 +0.86249995,0.012499999,0.1336348,0.0668174 +0.86249995,0.012500001,0.11905497,0.11905508 +0.8625,0.012499999,0.08418465,0.1683693 +0.8625,0.012500002,0.1683693,0.084184654 +0.86249995,0.0375,0.07499999,0.075 +0.86249995,0.037499998,0.053033054,0.10606601 +0.86249995,0.0375,0.10606593,0.05303301 +0.86249995,0.0375,0.094494045,0.094494075 +0.86249995,0.0375,0.06681746,0.1336348 +0.86249995,0.0375,0.1336348,0.0668174 +0.86249995,0.0375,0.11905497,0.11905508 +0.8625,0.0375,0.08418465,0.16836931 +0.8625,0.0375,0.1683693,0.08418466 +0.86249995,0.0625,0.07499999,0.075 +0.86249995,0.0625,0.053033054,0.10606602 +0.86249995,0.0625,0.10606593,0.05303301 +0.86249995,0.0625,0.094494045,0.094494075 +0.86249995,0.0625,0.06681746,0.1336348 +0.86249995,0.0625,0.1336348,0.0668174 +0.86249995,0.0625,0.11905497,0.11905508 +0.8625,0.0625,0.08418465,0.16836932 +0.8625,0.0625,0.1683693,0.08418465 +0.86249995,0.0875,0.07499999,0.075 +0.86249995,0.08749999,0.053033054,0.10606601 +0.86249995,0.087500006,0.10606593,0.053033013 +0.86249995,0.087500006,0.094494045,0.09449408 +0.86249995,0.087500006,0.06681746,0.1336348 +0.86249995,0.0875,0.1336348,0.0668174 +0.86249995,0.0875,0.11905497,0.11905508 +0.8625,0.0875,0.08418465,0.16836931 +0.8625,0.087500006,0.1683693,0.084184654 +0.86249995,0.112500004,0.07499999,0.075 +0.86249995,0.1125,0.053033054,0.10606601 +0.86249995,0.112500004,0.10606593,0.05303301 +0.86249995,0.1125,0.094494045,0.094494075 +0.86249995,0.1125,0.06681746,0.1336348 +0.86249995,0.1125,0.1336348,0.0668174 +0.86249995,0.1125,0.11905497,0.119055085 +0.8625,0.112500004,0.08418465,0.16836931 +0.8625,0.1125,0.1683693,0.08418465 +0.86249995,0.1375,0.07499999,0.074999996 +0.86249995,0.1375,0.053033054,0.10606602 +0.86249995,0.1375,0.10606593,0.053033024 +0.86249995,0.1375,0.094494045,0.09449408 +0.86249995,0.1375,0.06681746,0.1336348 +0.86249995,0.1375,0.1336348,0.0668174 +0.86249995,0.13749999,0.11905497,0.11905508 +0.8625,0.1375,0.08418465,0.1683693 +0.8625,0.1375,0.1683693,0.084184654 +0.86249995,0.1625,0.07499999,0.075 +0.86249995,0.16250001,0.053033054,0.106066026 +0.86249995,0.1625,0.10606593,0.05303301 +0.86249995,0.1625,0.094494045,0.094494075 +0.86249995,0.1625,0.06681746,0.1336348 +0.86249995,0.1625,0.1336348,0.0668174 +0.86249995,0.1625,0.11905497,0.11905508 +0.8625,0.1625,0.08418465,0.1683693 +0.8625,0.1625,0.1683693,0.08418464 +0.86249995,0.1875,0.07499999,0.07499999 +0.86249995,0.1875,0.053033054,0.10606603 +0.86249995,0.1875,0.10606593,0.053033024 +0.86249995,0.1875,0.094494045,0.09449406 +0.86249995,0.1875,0.06681746,0.1336348 +0.86249995,0.1875,0.1336348,0.06681742 +0.86249995,0.1875,0.11905497,0.11905509 +0.8625,0.1875,0.08418465,0.16836931 +0.8625,0.1875,0.1683693,0.08418465 +0.86249995,0.2125,0.07499999,0.075 +0.86249995,0.2125,0.053033054,0.10606603 +0.86249995,0.2125,0.10606593,0.05303301 +0.86249995,0.21249999,0.094494045,0.094494075 +0.86249995,0.2125,0.06681746,0.1336348 +0.86249995,0.2125,0.1336348,0.0668174 +0.86249995,0.2125,0.11905497,0.11905509 +0.8625,0.2125,0.08418465,0.16836931 +0.8625,0.2125,0.1683693,0.08418465 +0.86249995,0.23750001,0.07499999,0.075 +0.86249995,0.2375,0.053033054,0.10606602 +0.86249995,0.2375,0.10606593,0.053033024 +0.86249995,0.2375,0.094494045,0.094494075 +0.86249995,0.23750001,0.06681746,0.13363482 +0.86249995,0.2375,0.1336348,0.06681743 +0.86249995,0.2375,0.11905497,0.11905506 +0.8625,0.2375,0.08418465,0.16836932 +0.8625,0.23750001,0.1683693,0.08418466 +0.86249995,0.2625,0.07499999,0.07500002 +0.86249995,0.2625,0.053033054,0.10606603 +0.86249995,0.2625,0.10606593,0.053033024 +0.86249995,0.2625,0.094494045,0.094494075 +0.86249995,0.2625,0.06681746,0.13363479 +0.86249995,0.2625,0.1336348,0.06681743 +0.86249995,0.2625,0.11905497,0.11905508 +0.8625,0.2625,0.08418465,0.1683693 +0.8625,0.2625,0.1683693,0.08418463 +0.86249995,0.2875,0.07499999,0.07499999 +0.86249995,0.2875,0.053033054,0.10606603 +0.86249995,0.28750002,0.10606593,0.053033024 +0.86249995,0.2875,0.094494045,0.094494045 +0.86249995,0.2875,0.06681746,0.1336348 +0.86249995,0.28750002,0.1336348,0.06681743 +0.86249995,0.2875,0.11905497,0.11905508 +0.8625,0.2875,0.08418465,0.1683693 +0.8625,0.2875,0.1683693,0.08418465 +0.86249995,0.3125,0.07499999,0.07499999 +0.86249995,0.3125,0.053033054,0.10606605 +0.86249995,0.3125,0.10606593,0.053032994 +0.86249995,0.3125,0.094494045,0.094494045 +0.86249995,0.3125,0.06681746,0.1336348 +0.86249995,0.3125,0.1336348,0.0668174 +0.86249995,0.3125,0.11905497,0.11905509 +0.8625,0.3125,0.08418465,0.1683693 +0.8625,0.3125,0.1683693,0.08418465 +0.86249995,0.3375,0.07499999,0.07499999 +0.86249995,0.3375,0.053033054,0.10606605 +0.86249995,0.33749998,0.10606593,0.053033024 +0.86249995,0.3375,0.094494045,0.094494045 +0.86249995,0.33750004,0.06681746,0.13363484 +0.86249995,0.33749998,0.1336348,0.06681743 +0.86249995,0.3375,0.11905497,0.11905509 +0.8625,0.3375,0.08418465,0.1683693 +0.8625,0.3375,0.1683693,0.08418465 +0.86249995,0.3625,0.07499999,0.07500002 +0.86249995,0.3625,0.053033054,0.10606602 +0.86249995,0.3625,0.10606593,0.053033024 +0.86249995,0.3625,0.094494045,0.094494075 +0.86249995,0.3625,0.06681746,0.1336348 +0.86249995,0.3625,0.1336348,0.06681743 +0.86249995,0.3625,0.11905497,0.11905506 +0.8625,0.3625,0.08418465,0.1683693 +0.8625,0.3625,0.1683693,0.08418465 +0.86249995,0.3875,0.07499999,0.07500002 +0.86249995,0.3875,0.053033054,0.10606602 +0.86249995,0.3875,0.10606593,0.053032994 +0.86249995,0.3875,0.094494045,0.094494075 +0.86249995,0.3875,0.06681746,0.13363484 +0.86249995,0.3875,0.1336348,0.0668174 +0.86249995,0.3875,0.11905497,0.11905506 +0.8625,0.3875,0.08418465,0.1683693 +0.8625,0.3875,0.1683693,0.08418465 +0.86249995,0.4125,0.07499999,0.07499999 +0.86249995,0.4125,0.053033054,0.10606605 +0.86249995,0.4125,0.10606593,0.053032994 +0.86249995,0.4125,0.094494045,0.094494045 +0.86249995,0.41250002,0.06681746,0.13363484 +0.86249995,0.4125,0.1336348,0.0668174 +0.86249995,0.4125,0.11905497,0.11905509 +0.8625,0.4125,0.08418465,0.1683693 +0.8625,0.4125,0.1683693,0.08418465 +0.86249995,0.4375,0.07499999,0.07499999 +0.86249995,0.4375,0.053033054,0.10606605 +0.86249995,0.4375,0.10606593,0.053032994 +0.86249995,0.4375,0.094494045,0.094494045 +0.86249995,0.4375,0.06681746,0.1336348 +0.86249995,0.4375,0.1336348,0.0668174 +0.86249995,0.4375,0.11905497,0.11905509 +0.8625,0.4375,0.08418465,0.1683693 +0.8625,0.4375,0.1683693,0.08418465 +0.86249995,0.4625,0.07499999,0.07499999 +0.86249995,0.4625,0.053033054,0.10606605 +0.86249995,0.46249998,0.10606593,0.053032964 +0.86249995,0.4625,0.094494045,0.094494045 +0.86249995,0.46250004,0.06681746,0.13363484 +0.86249995,0.46249998,0.1336348,0.06681737 +0.86249995,0.4625,0.11905497,0.11905509 +0.8625,0.46249998,0.08418465,0.16836926 +0.8625,0.46249998,0.1683693,0.08418462 +0.86249995,0.48749998,0.07499999,0.07499999 +0.86249995,0.4875,0.053033054,0.10606602 +0.86249995,0.4875,0.10606593,0.053032994 +0.86249995,0.48749998,0.094494045,0.094494045 +0.86249995,0.4875,0.06681746,0.13363484 +0.86249995,0.4875,0.1336348,0.0668174 +0.86249995,0.4875,0.11905497,0.11905506 +0.8625,0.4875,0.08418465,0.1683693 +0.8625,0.4875,0.1683693,0.08418465 +0.86249995,0.5125,0.07499999,0.07500002 +0.86249995,0.51250005,0.053033054,0.10606605 +0.86249995,0.5125,0.10606593,0.053032964 +0.86249995,0.5125,0.094494045,0.094494075 +0.86249995,0.51250005,0.06681746,0.13363487 +0.86249995,0.5125,0.1336348,0.06681737 +0.86249995,0.51250005,0.11905497,0.11905509 +0.8625,0.5125,0.08418465,0.1683693 +0.8625,0.5125,0.1683693,0.08418465 +0.86249995,0.5375,0.07499999,0.07499999 +0.86249995,0.5375,0.053033054,0.10606605 +0.86249995,0.5375,0.10606593,0.053032935 +0.86249995,0.5375,0.094494045,0.094494045 +0.86249995,0.5375,0.06681746,0.13363487 +0.86249995,0.5375,0.1336348,0.06681734 +0.86249995,0.5375,0.11905497,0.11905509 +0.8625,0.5375,0.08418465,0.16836932 +0.8625,0.5375,0.1683693,0.08418468 +0.86249995,0.5625,0.07499999,0.07500005 +0.86249995,0.5625,0.053033054,0.10606599 +0.86249995,0.5625,0.10606593,0.053032994 +0.86249995,0.5625,0.094494045,0.094494104 +0.86249995,0.5625,0.06681746,0.13363484 +0.86249995,0.5625,0.1336348,0.0668174 +0.86249995,0.5625,0.11905497,0.11905503 +0.8625,0.5625,0.08418465,0.1683693 +0.8625,0.5625,0.1683693,0.08418465 +0.86249995,0.5875,0.07499999,0.07499999 +0.86249995,0.5875,0.053033054,0.10606605 +0.86249995,0.5875,0.10606593,0.053032935 +0.86249995,0.5875,0.094494045,0.094494045 +0.86249995,0.5875,0.06681746,0.13363487 +0.86249995,0.5875,0.1336348,0.06681734 +0.86249995,0.5875,0.11905497,0.11905509 +0.8625,0.5875,0.08418465,0.1683693 +0.8625,0.5875,0.1683693,0.08418465 +0.86249995,0.61249995,0.07499999,0.07499999 +0.86249995,0.61249995,0.053033054,0.10606605 +0.86249995,0.6125,0.10606593,0.053032994 +0.86249995,0.61249995,0.094494045,0.094494045 +0.86249995,0.61249995,0.06681746,0.13363487 +0.86249995,0.6125,0.1336348,0.0668174 +0.86249995,0.61249995,0.11905497,0.11905509 +0.8625,0.6125,0.08418465,0.1683693 +0.8625,0.6125,0.1683693,0.08418465 +0.86249995,0.63750005,0.07499999,0.07499999 +0.86249995,0.63750005,0.053033054,0.10606605 +0.86249995,0.6375,0.10606593,0.053032994 +0.86249995,0.63750005,0.094494045,0.094494045 +0.86249995,0.63750005,0.06681746,0.13363487 +0.86249995,0.6375,0.1336348,0.0668174 +0.86249995,0.63750005,0.11905497,0.11905509 +0.8625,0.6375,0.08418465,0.1683693 +0.8625,0.6375,0.1683693,0.08418465 +0.86249995,0.6625,0.07499999,0.07499999 +0.86249995,0.6625,0.053033054,0.10606605 +0.86249995,0.6625,0.10606593,0.053032935 +0.86249995,0.6625,0.094494045,0.094494045 +0.86249995,0.6625,0.06681746,0.13363487 +0.86249995,0.6625,0.1336348,0.06681734 +0.86249995,0.6625,0.11905497,0.11905509 +0.8625,0.6625,0.08418465,0.1683693 +0.8625,0.6625,0.1683693,0.08418465 +0.86249995,0.6875,0.07499999,0.07500005 +0.86249995,0.6875,0.053033054,0.10606599 +0.86249995,0.6875,0.10606593,0.053032994 +0.86249995,0.6875,0.094494045,0.094494104 +0.86249995,0.6875,0.06681746,0.1336348 +0.86249995,0.6875,0.1336348,0.0668174 +0.86249995,0.6875,0.11905497,0.11905503 +0.8625,0.6875,0.08418465,0.1683693 +0.8625,0.6875,0.1683693,0.08418465 +0.86249995,0.7125,0.07499999,0.07499999 +0.86249995,0.7125,0.053033054,0.10606605 +0.86249995,0.7125,0.10606593,0.053032935 +0.86249995,0.7125,0.094494045,0.094494045 +0.86249995,0.7125,0.06681746,0.13363487 +0.86249995,0.7125,0.1336348,0.06681734 +0.86249995,0.7125,0.11905497,0.11905509 +0.8625,0.7125,0.08418465,0.1683693 +0.8625,0.7125,0.1683693,0.08418465 +0.86249995,0.73749995,0.07499999,0.07499999 +0.86249995,0.73749995,0.053033054,0.10606605 +0.86249995,0.7375,0.10606593,0.053032994 +0.86249995,0.73749995,0.094494045,0.094494045 +0.86249995,0.73749995,0.06681746,0.1336348 +0.86249995,0.7375,0.1336348,0.0668174 +0.86249995,0.73749995,0.11905497,0.11905509 +0.8625,0.7375,0.08418465,0.1683693 +0.8625,0.7375,0.1683693,0.08418465 +0.86249995,0.76250005,0.07499999,0.07499999 +0.86249995,0.7625,0.053033054,0.10606599 +0.86249995,0.7625,0.10606593,0.053032994 +0.86249995,0.76250005,0.094494045,0.094494045 +0.86249995,0.7625,0.06681746,0.1336348 +0.86249995,0.7625,0.1336348,0.0668174 +0.86249995,0.7625,0.11905497,0.11905503 +0.8625,0.7625,0.08418465,0.1683693 +0.8625,0.7625,0.1683693,0.08418465 +0.86249995,0.7875,0.07499999,0.07499999 +0.86249995,0.78749996,0.053033054,0.10606599 +0.86249995,0.7875,0.10606593,0.053032994 +0.86249995,0.7875,0.094494045,0.094494045 +0.86249995,0.78749996,0.06681746,0.1336348 +0.86249995,0.7875,0.1336348,0.0668174 +0.86249995,0.78749996,0.11905497,0.11905503 +0.8625,0.7875,0.08418465,0.1683693 +0.8625,0.7875,0.1683693,0.08418465 +0.86249995,0.8125,0.07499999,0.07500005 +0.86249995,0.8125,0.053033054,0.10606599 +0.86249995,0.8125,0.10606593,0.053033054 +0.86249995,0.8125,0.094494045,0.094494104 +0.86249995,0.8125,0.06681746,0.1336348 +0.86249995,0.8125,0.1336348,0.06681746 +0.86249995,0.8125,0.11905497,0.11905503 +0.8625,0.8125,0.08418465,0.1683693 +0.8625,0.8125,0.1683693,0.08418465 +0.86249995,0.8375,0.07499999,0.07499999 +0.86249995,0.8375,0.053033054,0.10606599 +0.86249995,0.8375,0.10606593,0.053033054 +0.86249995,0.8375,0.094494045,0.094494045 +0.86249995,0.8375,0.06681746,0.1336348 +0.86249995,0.8375,0.1336348,0.06681746 +0.86249995,0.8375,0.11905497,0.11905503 +0.8625,0.8375,0.08418465,0.1683693 +0.8625,0.8375,0.1683693,0.08418465 +0.86249995,0.86249995,0.07499999,0.07499999 +0.86249995,0.86249995,0.053033054,0.10606593 +0.86249995,0.86249995,0.10606593,0.053033054 +0.86249995,0.86249995,0.094494045,0.094494045 +0.86249995,0.86249995,0.06681746,0.1336348 +0.86249995,0.86249995,0.1336348,0.06681746 +0.86249995,0.86249995,0.11905497,0.11905497 +0.8625,0.8625,0.08418465,0.1683693 +0.8625,0.8625,0.1683693,0.08418465 +0.86249995,0.88750005,0.07499999,0.07499999 +0.86249995,0.88750005,0.053033054,0.10606593 +0.86249995,0.88750005,0.10606593,0.053033054 +0.86249995,0.88750005,0.094494045,0.094494045 +0.86249995,0.88750005,0.06681746,0.13363475 +0.86249995,0.88750005,0.1336348,0.06681746 +0.86249995,0.88750005,0.11905497,0.11905497 +0.8625,0.8875,0.08418465,0.1683693 +0.8625,0.8875,0.1683693,0.08418465 +0.86249995,0.9125,0.07499999,0.07499999 +0.86249995,0.9125,0.053033054,0.10606593 +0.86249995,0.9125,0.10606593,0.053033054 +0.86249995,0.9125,0.094494045,0.094494045 +0.86249995,0.9125,0.06681746,0.13363475 +0.86249995,0.9125,0.1336348,0.06681746 +0.86249995,0.9125,0.11905497,0.11905497 +0.8625,0.9125,0.08418465,0.1683693 +0.8625,0.9125,0.1683693,0.08418465 +0.86249995,0.9375,0.07499999,0.07500005 +0.86249995,0.9375,0.053033054,0.10606599 +0.86249995,0.9375,0.10606593,0.053033113 +0.86249995,0.9375,0.094494045,0.094494104 +0.86249995,0.9375,0.06681746,0.1336348 +0.86249995,0.9375,0.1336348,0.06681752 +0.86249995,0.9375,0.11905497,0.11905503 +0.8625,0.9375,0.08418465,0.1683693 +0.8625,0.9375,0.1683693,0.08418465 +0.86249995,0.9625,0.07499999,0.07499999 +0.86249995,0.9625,0.053033054,0.10606593 +0.86249995,0.9625,0.10606593,0.053033054 +0.86249995,0.9625,0.094494045,0.094494045 +0.86249995,0.9625,0.06681746,0.13363475 +0.86249995,0.9625,0.1336348,0.06681746 +0.86249995,0.9625,0.11905497,0.11905497 +0.8625,0.9625,0.08418465,0.1683693 +0.8625,0.9625,0.1683693,0.08418465 +0.86249995,0.98749995,0.07499999,0.07499999 +0.86249995,0.98749995,0.053033054,0.10606593 +0.86249995,0.98749995,0.10606593,0.053033054 +0.86249995,0.98749995,0.094494045,0.094494045 +0.86249995,0.98749995,0.06681746,0.13363475 +0.86249995,0.98749995,0.1336348,0.06681746 +0.86249995,0.98749995,0.11905497,0.11905497 +0.8625,0.98749995,0.08418465,0.16836923 +0.8625,0.98749995,0.1683693,0.08418459 +0.88750005,0.0125,0.07499999,0.075 +0.88750005,0.012499997,0.053033054,0.10606602 +0.88750005,0.012499999,0.10606593,0.05303301 +0.88750005,0.012499999,0.094494045,0.09449408 +0.88750005,0.012500001,0.06681746,0.1336348 +0.88750005,0.012499999,0.13363475,0.0668174 +0.88750005,0.012500001,0.11905497,0.11905508 +0.8875,0.012499999,0.08418465,0.1683693 +0.8875,0.012500002,0.1683693,0.084184654 +0.88750005,0.0375,0.07499999,0.075 +0.88750005,0.037499998,0.053033054,0.10606601 +0.88750005,0.0375,0.10606593,0.05303301 +0.88750005,0.0375,0.094494045,0.094494075 +0.88750005,0.0375,0.06681746,0.1336348 +0.88750005,0.0375,0.13363475,0.0668174 +0.88750005,0.0375,0.11905497,0.11905508 +0.8875,0.0375,0.08418465,0.16836931 +0.8875,0.0375,0.1683693,0.08418466 +0.88750005,0.0625,0.07499999,0.075 +0.88750005,0.0625,0.053033054,0.10606602 +0.88750005,0.0625,0.10606593,0.05303301 +0.88750005,0.0625,0.094494045,0.094494075 +0.88750005,0.0625,0.06681746,0.1336348 +0.88750005,0.0625,0.13363475,0.0668174 +0.88750005,0.0625,0.11905497,0.11905508 +0.8875,0.0625,0.08418465,0.16836932 +0.8875,0.0625,0.1683693,0.08418465 +0.88750005,0.0875,0.07499999,0.075 +0.88750005,0.08749999,0.053033054,0.10606601 +0.88750005,0.087500006,0.10606593,0.053033013 +0.88750005,0.087500006,0.094494045,0.09449408 +0.88750005,0.087500006,0.06681746,0.1336348 +0.88750005,0.0875,0.13363475,0.0668174 +0.88750005,0.0875,0.11905497,0.11905508 +0.8875,0.0875,0.08418465,0.16836931 +0.8875,0.087500006,0.1683693,0.084184654 +0.88750005,0.112500004,0.07499999,0.075 +0.88750005,0.1125,0.053033054,0.10606601 +0.88750005,0.112500004,0.10606593,0.05303301 +0.88750005,0.1125,0.094494045,0.094494075 +0.88750005,0.1125,0.06681746,0.1336348 +0.88750005,0.1125,0.13363475,0.0668174 +0.88750005,0.1125,0.11905497,0.119055085 +0.8875,0.112500004,0.08418465,0.16836931 +0.8875,0.1125,0.1683693,0.08418465 +0.88750005,0.1375,0.07499999,0.074999996 +0.88750005,0.1375,0.053033054,0.10606602 +0.88750005,0.1375,0.10606593,0.053033024 +0.88750005,0.1375,0.094494045,0.09449408 +0.88750005,0.1375,0.06681746,0.1336348 +0.88750005,0.1375,0.13363475,0.0668174 +0.88750005,0.13749999,0.11905497,0.11905508 +0.8875,0.1375,0.08418465,0.1683693 +0.8875,0.1375,0.1683693,0.084184654 +0.88750005,0.1625,0.07499999,0.075 +0.88750005,0.16250001,0.053033054,0.106066026 +0.88750005,0.1625,0.10606593,0.05303301 +0.88750005,0.1625,0.094494045,0.094494075 +0.88750005,0.1625,0.06681746,0.1336348 +0.88750005,0.1625,0.13363475,0.0668174 +0.88750005,0.1625,0.11905497,0.11905508 +0.8875,0.1625,0.08418465,0.1683693 +0.8875,0.1625,0.1683693,0.08418464 +0.88750005,0.1875,0.07499999,0.07499999 +0.88750005,0.1875,0.053033054,0.10606603 +0.88750005,0.1875,0.10606593,0.053033024 +0.88750005,0.1875,0.094494045,0.09449406 +0.88750005,0.1875,0.06681746,0.1336348 +0.88750005,0.1875,0.13363475,0.06681742 +0.88750005,0.1875,0.11905497,0.11905509 +0.8875,0.1875,0.08418465,0.16836931 +0.8875,0.1875,0.1683693,0.08418465 +0.88750005,0.2125,0.07499999,0.075 +0.88750005,0.2125,0.053033054,0.10606603 +0.88750005,0.2125,0.10606593,0.05303301 +0.88750005,0.21249999,0.094494045,0.094494075 +0.88750005,0.2125,0.06681746,0.1336348 +0.88750005,0.2125,0.13363475,0.0668174 +0.88750005,0.2125,0.11905497,0.11905509 +0.8875,0.2125,0.08418465,0.16836931 +0.8875,0.2125,0.1683693,0.08418465 +0.88750005,0.23750001,0.07499999,0.075 +0.88750005,0.2375,0.053033054,0.10606602 +0.88750005,0.2375,0.10606593,0.053033024 +0.88750005,0.2375,0.094494045,0.094494075 +0.88750005,0.23750001,0.06681746,0.13363482 +0.88750005,0.2375,0.13363475,0.06681743 +0.88750005,0.2375,0.11905497,0.11905506 +0.8875,0.2375,0.08418465,0.16836932 +0.8875,0.23750001,0.1683693,0.08418466 +0.88750005,0.2625,0.07499999,0.07500002 +0.88750005,0.2625,0.053033054,0.10606603 +0.88750005,0.2625,0.10606593,0.053033024 +0.88750005,0.2625,0.094494045,0.094494075 +0.88750005,0.2625,0.06681746,0.13363479 +0.88750005,0.2625,0.13363475,0.06681743 +0.88750005,0.2625,0.11905497,0.11905508 +0.8875,0.2625,0.08418465,0.1683693 +0.8875,0.2625,0.1683693,0.08418463 +0.88750005,0.2875,0.07499999,0.07499999 +0.88750005,0.2875,0.053033054,0.10606603 +0.88750005,0.28750002,0.10606593,0.053033024 +0.88750005,0.2875,0.094494045,0.094494045 +0.88750005,0.2875,0.06681746,0.1336348 +0.88750005,0.28750002,0.13363475,0.06681743 +0.88750005,0.2875,0.11905497,0.11905508 +0.8875,0.2875,0.08418465,0.1683693 +0.8875,0.2875,0.1683693,0.08418465 +0.88750005,0.3125,0.07499999,0.07499999 +0.88750005,0.3125,0.053033054,0.10606605 +0.88750005,0.3125,0.10606593,0.053032994 +0.88750005,0.3125,0.094494045,0.094494045 +0.88750005,0.3125,0.06681746,0.1336348 +0.88750005,0.3125,0.13363475,0.0668174 +0.88750005,0.3125,0.11905497,0.11905509 +0.8875,0.3125,0.08418465,0.1683693 +0.8875,0.3125,0.1683693,0.08418465 +0.88750005,0.3375,0.07499999,0.07499999 +0.88750005,0.3375,0.053033054,0.10606605 +0.88750005,0.33749998,0.10606593,0.053033024 +0.88750005,0.3375,0.094494045,0.094494045 +0.88750005,0.33750004,0.06681746,0.13363484 +0.88750005,0.33749998,0.13363475,0.06681743 +0.88750005,0.3375,0.11905497,0.11905509 +0.8875,0.3375,0.08418465,0.1683693 +0.8875,0.3375,0.1683693,0.08418465 +0.88750005,0.3625,0.07499999,0.07500002 +0.88750005,0.3625,0.053033054,0.10606602 +0.88750005,0.3625,0.10606593,0.053033024 +0.88750005,0.3625,0.094494045,0.094494075 +0.88750005,0.3625,0.06681746,0.1336348 +0.88750005,0.3625,0.13363475,0.06681743 +0.88750005,0.3625,0.11905497,0.11905506 +0.8875,0.3625,0.08418465,0.1683693 +0.8875,0.3625,0.1683693,0.08418465 +0.88750005,0.3875,0.07499999,0.07500002 +0.88750005,0.3875,0.053033054,0.10606602 +0.88750005,0.3875,0.10606593,0.053032994 +0.88750005,0.3875,0.094494045,0.094494075 +0.88750005,0.3875,0.06681746,0.13363484 +0.88750005,0.3875,0.13363475,0.0668174 +0.88750005,0.3875,0.11905497,0.11905506 +0.8875,0.3875,0.08418465,0.1683693 +0.8875,0.3875,0.1683693,0.08418465 +0.88750005,0.4125,0.07499999,0.07499999 +0.88750005,0.4125,0.053033054,0.10606605 +0.88750005,0.4125,0.10606593,0.053032994 +0.88750005,0.4125,0.094494045,0.094494045 +0.88750005,0.41250002,0.06681746,0.13363484 +0.88750005,0.4125,0.13363475,0.0668174 +0.88750005,0.4125,0.11905497,0.11905509 +0.8875,0.4125,0.08418465,0.1683693 +0.8875,0.4125,0.1683693,0.08418465 +0.88750005,0.4375,0.07499999,0.07499999 +0.88750005,0.4375,0.053033054,0.10606605 +0.88750005,0.4375,0.10606593,0.053032994 +0.88750005,0.4375,0.094494045,0.094494045 +0.88750005,0.4375,0.06681746,0.1336348 +0.88750005,0.4375,0.13363475,0.0668174 +0.88750005,0.4375,0.11905497,0.11905509 +0.8875,0.4375,0.08418465,0.1683693 +0.8875,0.4375,0.1683693,0.08418465 +0.88750005,0.4625,0.07499999,0.07499999 +0.88750005,0.4625,0.053033054,0.10606605 +0.88750005,0.46249998,0.10606593,0.053032964 +0.88750005,0.4625,0.094494045,0.094494045 +0.88750005,0.46250004,0.06681746,0.13363484 +0.88750005,0.46249998,0.13363475,0.06681737 +0.88750005,0.4625,0.11905497,0.11905509 +0.8875,0.46249998,0.08418465,0.16836926 +0.8875,0.46249998,0.1683693,0.08418462 +0.88750005,0.48749998,0.07499999,0.07499999 +0.88750005,0.4875,0.053033054,0.10606602 +0.88750005,0.4875,0.10606593,0.053032994 +0.88750005,0.48749998,0.094494045,0.094494045 +0.88750005,0.4875,0.06681746,0.13363484 +0.88750005,0.4875,0.13363475,0.0668174 +0.88750005,0.4875,0.11905497,0.11905506 +0.8875,0.4875,0.08418465,0.1683693 +0.8875,0.4875,0.1683693,0.08418465 +0.88750005,0.5125,0.07499999,0.07500002 +0.88750005,0.51250005,0.053033054,0.10606605 +0.88750005,0.5125,0.10606593,0.053032964 +0.88750005,0.5125,0.094494045,0.094494075 +0.88750005,0.51250005,0.06681746,0.13363487 +0.88750005,0.5125,0.13363475,0.06681737 +0.88750005,0.51250005,0.11905497,0.11905509 +0.8875,0.5125,0.08418465,0.1683693 +0.8875,0.5125,0.1683693,0.08418465 +0.88750005,0.5375,0.07499999,0.07499999 +0.88750005,0.5375,0.053033054,0.10606605 +0.88750005,0.5375,0.10606593,0.053032935 +0.88750005,0.5375,0.094494045,0.094494045 +0.88750005,0.5375,0.06681746,0.13363487 +0.88750005,0.5375,0.13363475,0.06681734 +0.88750005,0.5375,0.11905497,0.11905509 +0.8875,0.5375,0.08418465,0.16836932 +0.8875,0.5375,0.1683693,0.08418468 +0.88750005,0.5625,0.07499999,0.07500005 +0.88750005,0.5625,0.053033054,0.10606599 +0.88750005,0.5625,0.10606593,0.053032994 +0.88750005,0.5625,0.094494045,0.094494104 +0.88750005,0.5625,0.06681746,0.13363484 +0.88750005,0.5625,0.13363475,0.0668174 +0.88750005,0.5625,0.11905497,0.11905503 +0.8875,0.5625,0.08418465,0.1683693 +0.8875,0.5625,0.1683693,0.08418465 +0.88750005,0.5875,0.07499999,0.07499999 +0.88750005,0.5875,0.053033054,0.10606605 +0.88750005,0.5875,0.10606593,0.053032935 +0.88750005,0.5875,0.094494045,0.094494045 +0.88750005,0.5875,0.06681746,0.13363487 +0.88750005,0.5875,0.13363475,0.06681734 +0.88750005,0.5875,0.11905497,0.11905509 +0.8875,0.5875,0.08418465,0.1683693 +0.8875,0.5875,0.1683693,0.08418465 +0.88750005,0.61249995,0.07499999,0.07499999 +0.88750005,0.61249995,0.053033054,0.10606605 +0.88750005,0.6125,0.10606593,0.053032994 +0.88750005,0.61249995,0.094494045,0.094494045 +0.88750005,0.61249995,0.06681746,0.13363487 +0.88750005,0.6125,0.13363475,0.0668174 +0.88750005,0.61249995,0.11905497,0.11905509 +0.8875,0.6125,0.08418465,0.1683693 +0.8875,0.6125,0.1683693,0.08418465 +0.88750005,0.63750005,0.07499999,0.07499999 +0.88750005,0.63750005,0.053033054,0.10606605 +0.88750005,0.6375,0.10606593,0.053032994 +0.88750005,0.63750005,0.094494045,0.094494045 +0.88750005,0.63750005,0.06681746,0.13363487 +0.88750005,0.6375,0.13363475,0.0668174 +0.88750005,0.63750005,0.11905497,0.11905509 +0.8875,0.6375,0.08418465,0.1683693 +0.8875,0.6375,0.1683693,0.08418465 +0.88750005,0.6625,0.07499999,0.07499999 +0.88750005,0.6625,0.053033054,0.10606605 +0.88750005,0.6625,0.10606593,0.053032935 +0.88750005,0.6625,0.094494045,0.094494045 +0.88750005,0.6625,0.06681746,0.13363487 +0.88750005,0.6625,0.13363475,0.06681734 +0.88750005,0.6625,0.11905497,0.11905509 +0.8875,0.6625,0.08418465,0.1683693 +0.8875,0.6625,0.1683693,0.08418465 +0.88750005,0.6875,0.07499999,0.07500005 +0.88750005,0.6875,0.053033054,0.10606599 +0.88750005,0.6875,0.10606593,0.053032994 +0.88750005,0.6875,0.094494045,0.094494104 +0.88750005,0.6875,0.06681746,0.1336348 +0.88750005,0.6875,0.13363475,0.0668174 +0.88750005,0.6875,0.11905497,0.11905503 +0.8875,0.6875,0.08418465,0.1683693 +0.8875,0.6875,0.1683693,0.08418465 +0.88750005,0.7125,0.07499999,0.07499999 +0.88750005,0.7125,0.053033054,0.10606605 +0.88750005,0.7125,0.10606593,0.053032935 +0.88750005,0.7125,0.094494045,0.094494045 +0.88750005,0.7125,0.06681746,0.13363487 +0.88750005,0.7125,0.13363475,0.06681734 +0.88750005,0.7125,0.11905497,0.11905509 +0.8875,0.7125,0.08418465,0.1683693 +0.8875,0.7125,0.1683693,0.08418465 +0.88750005,0.73749995,0.07499999,0.07499999 +0.88750005,0.73749995,0.053033054,0.10606605 +0.88750005,0.7375,0.10606593,0.053032994 +0.88750005,0.73749995,0.094494045,0.094494045 +0.88750005,0.73749995,0.06681746,0.1336348 +0.88750005,0.7375,0.13363475,0.0668174 +0.88750005,0.73749995,0.11905497,0.11905509 +0.8875,0.7375,0.08418465,0.1683693 +0.8875,0.7375,0.1683693,0.08418465 +0.88750005,0.76250005,0.07499999,0.07499999 +0.88750005,0.7625,0.053033054,0.10606599 +0.88750005,0.7625,0.10606593,0.053032994 +0.88750005,0.76250005,0.094494045,0.094494045 +0.88750005,0.7625,0.06681746,0.1336348 +0.88750005,0.7625,0.13363475,0.0668174 +0.88750005,0.7625,0.11905497,0.11905503 +0.8875,0.7625,0.08418465,0.1683693 +0.8875,0.7625,0.1683693,0.08418465 +0.88750005,0.7875,0.07499999,0.07499999 +0.88750005,0.78749996,0.053033054,0.10606599 +0.88750005,0.7875,0.10606593,0.053032994 +0.88750005,0.7875,0.094494045,0.094494045 +0.88750005,0.78749996,0.06681746,0.1336348 +0.88750005,0.7875,0.13363475,0.0668174 +0.88750005,0.78749996,0.11905497,0.11905503 +0.8875,0.7875,0.08418465,0.1683693 +0.8875,0.7875,0.1683693,0.08418465 +0.88750005,0.8125,0.07499999,0.07500005 +0.88750005,0.8125,0.053033054,0.10606599 +0.88750005,0.8125,0.10606593,0.053033054 +0.88750005,0.8125,0.094494045,0.094494104 +0.88750005,0.8125,0.06681746,0.1336348 +0.88750005,0.8125,0.13363475,0.06681746 +0.88750005,0.8125,0.11905497,0.11905503 +0.8875,0.8125,0.08418465,0.1683693 +0.8875,0.8125,0.1683693,0.08418465 +0.88750005,0.8375,0.07499999,0.07499999 +0.88750005,0.8375,0.053033054,0.10606599 +0.88750005,0.8375,0.10606593,0.053033054 +0.88750005,0.8375,0.094494045,0.094494045 +0.88750005,0.8375,0.06681746,0.1336348 +0.88750005,0.8375,0.13363475,0.06681746 +0.88750005,0.8375,0.11905497,0.11905503 +0.8875,0.8375,0.08418465,0.1683693 +0.8875,0.8375,0.1683693,0.08418465 +0.88750005,0.86249995,0.07499999,0.07499999 +0.88750005,0.86249995,0.053033054,0.10606593 +0.88750005,0.86249995,0.10606593,0.053033054 +0.88750005,0.86249995,0.094494045,0.094494045 +0.88750005,0.86249995,0.06681746,0.1336348 +0.88750005,0.86249995,0.13363475,0.06681746 +0.88750005,0.86249995,0.11905497,0.11905497 +0.8875,0.8625,0.08418465,0.1683693 +0.8875,0.8625,0.1683693,0.08418465 +0.88750005,0.88750005,0.07499999,0.07499999 +0.88750005,0.88750005,0.053033054,0.10606593 +0.88750005,0.88750005,0.10606593,0.053033054 +0.88750005,0.88750005,0.094494045,0.094494045 +0.88750005,0.88750005,0.06681746,0.13363475 +0.88750005,0.88750005,0.13363475,0.06681746 +0.88750005,0.88750005,0.11905497,0.11905497 +0.8875,0.8875,0.08418465,0.1683693 +0.8875,0.8875,0.1683693,0.08418465 +0.88750005,0.9125,0.07499999,0.07499999 +0.88750005,0.9125,0.053033054,0.10606593 +0.88750005,0.9125,0.10606593,0.053033054 +0.88750005,0.9125,0.094494045,0.094494045 +0.88750005,0.9125,0.06681746,0.13363475 +0.88750005,0.9125,0.13363475,0.06681746 +0.88750005,0.9125,0.11905497,0.11905497 +0.8875,0.9125,0.08418465,0.1683693 +0.8875,0.9125,0.1683693,0.08418465 +0.88750005,0.9375,0.07499999,0.07500005 +0.88750005,0.9375,0.053033054,0.10606599 +0.88750005,0.9375,0.10606593,0.053033113 +0.88750005,0.9375,0.094494045,0.094494104 +0.88750005,0.9375,0.06681746,0.1336348 +0.88750005,0.9375,0.13363475,0.06681752 +0.88750005,0.9375,0.11905497,0.11905503 +0.8875,0.9375,0.08418465,0.1683693 +0.8875,0.9375,0.1683693,0.08418465 +0.88750005,0.9625,0.07499999,0.07499999 +0.88750005,0.9625,0.053033054,0.10606593 +0.88750005,0.9625,0.10606593,0.053033054 +0.88750005,0.9625,0.094494045,0.094494045 +0.88750005,0.9625,0.06681746,0.13363475 +0.88750005,0.9625,0.13363475,0.06681746 +0.88750005,0.9625,0.11905497,0.11905497 +0.8875,0.9625,0.08418465,0.1683693 +0.8875,0.9625,0.1683693,0.08418465 +0.88750005,0.98749995,0.07499999,0.07499999 +0.88750005,0.98749995,0.053033054,0.10606593 +0.88750005,0.98749995,0.10606593,0.053033054 +0.88750005,0.98749995,0.094494045,0.094494045 +0.88750005,0.98749995,0.06681746,0.13363475 +0.88750005,0.98749995,0.13363475,0.06681746 +0.88750005,0.98749995,0.11905497,0.11905497 +0.8875,0.98749995,0.08418465,0.16836923 +0.8875,0.98749995,0.1683693,0.08418459 +0.9125,0.0125,0.07499999,0.075 +0.9125,0.012499997,0.053033054,0.10606602 +0.9125,0.012499999,0.10606593,0.05303301 +0.9125,0.012499999,0.094494045,0.09449408 +0.9125,0.012500001,0.06681746,0.1336348 +0.9125,0.012499999,0.13363475,0.0668174 +0.9125,0.012500001,0.11905497,0.11905508 +0.9125,0.012499999,0.08418465,0.1683693 +0.9125,0.012500002,0.1683693,0.084184654 +0.9125,0.0375,0.07499999,0.075 +0.9125,0.037499998,0.053033054,0.10606601 +0.9125,0.0375,0.10606593,0.05303301 +0.9125,0.0375,0.094494045,0.094494075 +0.9125,0.0375,0.06681746,0.1336348 +0.9125,0.0375,0.13363475,0.0668174 +0.9125,0.0375,0.11905497,0.11905508 +0.9125,0.0375,0.08418465,0.16836931 +0.9125,0.0375,0.1683693,0.08418466 +0.9125,0.0625,0.07499999,0.075 +0.9125,0.0625,0.053033054,0.10606602 +0.9125,0.0625,0.10606593,0.05303301 +0.9125,0.0625,0.094494045,0.094494075 +0.9125,0.0625,0.06681746,0.1336348 +0.9125,0.0625,0.13363475,0.0668174 +0.9125,0.0625,0.11905497,0.11905508 +0.9125,0.0625,0.08418465,0.16836932 +0.9125,0.0625,0.1683693,0.08418465 +0.9125,0.0875,0.07499999,0.075 +0.9125,0.08749999,0.053033054,0.10606601 +0.9125,0.087500006,0.10606593,0.053033013 +0.9125,0.087500006,0.094494045,0.09449408 +0.9125,0.087500006,0.06681746,0.1336348 +0.9125,0.0875,0.13363475,0.0668174 +0.9125,0.0875,0.11905497,0.11905508 +0.9125,0.0875,0.08418465,0.16836931 +0.9125,0.087500006,0.1683693,0.084184654 +0.9125,0.112500004,0.07499999,0.075 +0.9125,0.1125,0.053033054,0.10606601 +0.9125,0.112500004,0.10606593,0.05303301 +0.9125,0.1125,0.094494045,0.094494075 +0.9125,0.1125,0.06681746,0.1336348 +0.9125,0.1125,0.13363475,0.0668174 +0.9125,0.1125,0.11905497,0.119055085 +0.9125,0.112500004,0.08418465,0.16836931 +0.9125,0.1125,0.1683693,0.08418465 +0.9125,0.1375,0.07499999,0.074999996 +0.9125,0.1375,0.053033054,0.10606602 +0.9125,0.1375,0.10606593,0.053033024 +0.9125,0.1375,0.094494045,0.09449408 +0.9125,0.1375,0.06681746,0.1336348 +0.9125,0.1375,0.13363475,0.0668174 +0.9125,0.13749999,0.11905497,0.11905508 +0.9125,0.1375,0.08418465,0.1683693 +0.9125,0.1375,0.1683693,0.084184654 +0.9125,0.1625,0.07499999,0.075 +0.9125,0.16250001,0.053033054,0.106066026 +0.9125,0.1625,0.10606593,0.05303301 +0.9125,0.1625,0.094494045,0.094494075 +0.9125,0.1625,0.06681746,0.1336348 +0.9125,0.1625,0.13363475,0.0668174 +0.9125,0.1625,0.11905497,0.11905508 +0.9125,0.1625,0.08418465,0.1683693 +0.9125,0.1625,0.1683693,0.08418464 +0.9125,0.1875,0.07499999,0.07499999 +0.9125,0.1875,0.053033054,0.10606603 +0.9125,0.1875,0.10606593,0.053033024 +0.9125,0.1875,0.094494045,0.09449406 +0.9125,0.1875,0.06681746,0.1336348 +0.9125,0.1875,0.13363475,0.06681742 +0.9125,0.1875,0.11905497,0.11905509 +0.9125,0.1875,0.08418465,0.16836931 +0.9125,0.1875,0.1683693,0.08418465 +0.9125,0.2125,0.07499999,0.075 +0.9125,0.2125,0.053033054,0.10606603 +0.9125,0.2125,0.10606593,0.05303301 +0.9125,0.21249999,0.094494045,0.094494075 +0.9125,0.2125,0.06681746,0.1336348 +0.9125,0.2125,0.13363475,0.0668174 +0.9125,0.2125,0.11905497,0.11905509 +0.9125,0.2125,0.08418465,0.16836931 +0.9125,0.2125,0.1683693,0.08418465 +0.9125,0.23750001,0.07499999,0.075 +0.9125,0.2375,0.053033054,0.10606602 +0.9125,0.2375,0.10606593,0.053033024 +0.9125,0.2375,0.094494045,0.094494075 +0.9125,0.23750001,0.06681746,0.13363482 +0.9125,0.2375,0.13363475,0.06681743 +0.9125,0.2375,0.11905497,0.11905506 +0.9125,0.2375,0.08418465,0.16836932 +0.9125,0.23750001,0.1683693,0.08418466 +0.9125,0.2625,0.07499999,0.07500002 +0.9125,0.2625,0.053033054,0.10606603 +0.9125,0.2625,0.10606593,0.053033024 +0.9125,0.2625,0.094494045,0.094494075 +0.9125,0.2625,0.06681746,0.13363479 +0.9125,0.2625,0.13363475,0.06681743 +0.9125,0.2625,0.11905497,0.11905508 +0.9125,0.2625,0.08418465,0.1683693 +0.9125,0.2625,0.1683693,0.08418463 +0.9125,0.2875,0.07499999,0.07499999 +0.9125,0.2875,0.053033054,0.10606603 +0.9125,0.28750002,0.10606593,0.053033024 +0.9125,0.2875,0.094494045,0.094494045 +0.9125,0.2875,0.06681746,0.1336348 +0.9125,0.28750002,0.13363475,0.06681743 +0.9125,0.2875,0.11905497,0.11905508 +0.9125,0.2875,0.08418465,0.1683693 +0.9125,0.2875,0.1683693,0.08418465 +0.9125,0.3125,0.07499999,0.07499999 +0.9125,0.3125,0.053033054,0.10606605 +0.9125,0.3125,0.10606593,0.053032994 +0.9125,0.3125,0.094494045,0.094494045 +0.9125,0.3125,0.06681746,0.1336348 +0.9125,0.3125,0.13363475,0.0668174 +0.9125,0.3125,0.11905497,0.11905509 +0.9125,0.3125,0.08418465,0.1683693 +0.9125,0.3125,0.1683693,0.08418465 +0.9125,0.3375,0.07499999,0.07499999 +0.9125,0.3375,0.053033054,0.10606605 +0.9125,0.33749998,0.10606593,0.053033024 +0.9125,0.3375,0.094494045,0.094494045 +0.9125,0.33750004,0.06681746,0.13363484 +0.9125,0.33749998,0.13363475,0.06681743 +0.9125,0.3375,0.11905497,0.11905509 +0.9125,0.3375,0.08418465,0.1683693 +0.9125,0.3375,0.1683693,0.08418465 +0.9125,0.3625,0.07499999,0.07500002 +0.9125,0.3625,0.053033054,0.10606602 +0.9125,0.3625,0.10606593,0.053033024 +0.9125,0.3625,0.094494045,0.094494075 +0.9125,0.3625,0.06681746,0.1336348 +0.9125,0.3625,0.13363475,0.06681743 +0.9125,0.3625,0.11905497,0.11905506 +0.9125,0.3625,0.08418465,0.1683693 +0.9125,0.3625,0.1683693,0.08418465 +0.9125,0.3875,0.07499999,0.07500002 +0.9125,0.3875,0.053033054,0.10606602 +0.9125,0.3875,0.10606593,0.053032994 +0.9125,0.3875,0.094494045,0.094494075 +0.9125,0.3875,0.06681746,0.13363484 +0.9125,0.3875,0.13363475,0.0668174 +0.9125,0.3875,0.11905497,0.11905506 +0.9125,0.3875,0.08418465,0.1683693 +0.9125,0.3875,0.1683693,0.08418465 +0.9125,0.4125,0.07499999,0.07499999 +0.9125,0.4125,0.053033054,0.10606605 +0.9125,0.4125,0.10606593,0.053032994 +0.9125,0.4125,0.094494045,0.094494045 +0.9125,0.41250002,0.06681746,0.13363484 +0.9125,0.4125,0.13363475,0.0668174 +0.9125,0.4125,0.11905497,0.11905509 +0.9125,0.4125,0.08418465,0.1683693 +0.9125,0.4125,0.1683693,0.08418465 +0.9125,0.4375,0.07499999,0.07499999 +0.9125,0.4375,0.053033054,0.10606605 +0.9125,0.4375,0.10606593,0.053032994 +0.9125,0.4375,0.094494045,0.094494045 +0.9125,0.4375,0.06681746,0.1336348 +0.9125,0.4375,0.13363475,0.0668174 +0.9125,0.4375,0.11905497,0.11905509 +0.9125,0.4375,0.08418465,0.1683693 +0.9125,0.4375,0.1683693,0.08418465 +0.9125,0.4625,0.07499999,0.07499999 +0.9125,0.4625,0.053033054,0.10606605 +0.9125,0.46249998,0.10606593,0.053032964 +0.9125,0.4625,0.094494045,0.094494045 +0.9125,0.46250004,0.06681746,0.13363484 +0.9125,0.46249998,0.13363475,0.06681737 +0.9125,0.4625,0.11905497,0.11905509 +0.9125,0.46249998,0.08418465,0.16836926 +0.9125,0.46249998,0.1683693,0.08418462 +0.9125,0.48749998,0.07499999,0.07499999 +0.9125,0.4875,0.053033054,0.10606602 +0.9125,0.4875,0.10606593,0.053032994 +0.9125,0.48749998,0.094494045,0.094494045 +0.9125,0.4875,0.06681746,0.13363484 +0.9125,0.4875,0.13363475,0.0668174 +0.9125,0.4875,0.11905497,0.11905506 +0.9125,0.4875,0.08418465,0.1683693 +0.9125,0.4875,0.1683693,0.08418465 +0.9125,0.5125,0.07499999,0.07500002 +0.9125,0.51250005,0.053033054,0.10606605 +0.9125,0.5125,0.10606593,0.053032964 +0.9125,0.5125,0.094494045,0.094494075 +0.9125,0.51250005,0.06681746,0.13363487 +0.9125,0.5125,0.13363475,0.06681737 +0.9125,0.51250005,0.11905497,0.11905509 +0.9125,0.5125,0.08418465,0.1683693 +0.9125,0.5125,0.1683693,0.08418465 +0.9125,0.5375,0.07499999,0.07499999 +0.9125,0.5375,0.053033054,0.10606605 +0.9125,0.5375,0.10606593,0.053032935 +0.9125,0.5375,0.094494045,0.094494045 +0.9125,0.5375,0.06681746,0.13363487 +0.9125,0.5375,0.13363475,0.06681734 +0.9125,0.5375,0.11905497,0.11905509 +0.9125,0.5375,0.08418465,0.16836932 +0.9125,0.5375,0.1683693,0.08418468 +0.9125,0.5625,0.07499999,0.07500005 +0.9125,0.5625,0.053033054,0.10606599 +0.9125,0.5625,0.10606593,0.053032994 +0.9125,0.5625,0.094494045,0.094494104 +0.9125,0.5625,0.06681746,0.13363484 +0.9125,0.5625,0.13363475,0.0668174 +0.9125,0.5625,0.11905497,0.11905503 +0.9125,0.5625,0.08418465,0.1683693 +0.9125,0.5625,0.1683693,0.08418465 +0.9125,0.5875,0.07499999,0.07499999 +0.9125,0.5875,0.053033054,0.10606605 +0.9125,0.5875,0.10606593,0.053032935 +0.9125,0.5875,0.094494045,0.094494045 +0.9125,0.5875,0.06681746,0.13363487 +0.9125,0.5875,0.13363475,0.06681734 +0.9125,0.5875,0.11905497,0.11905509 +0.9125,0.5875,0.08418465,0.1683693 +0.9125,0.5875,0.1683693,0.08418465 +0.9125,0.61249995,0.07499999,0.07499999 +0.9125,0.61249995,0.053033054,0.10606605 +0.9125,0.6125,0.10606593,0.053032994 +0.9125,0.61249995,0.094494045,0.094494045 +0.9125,0.61249995,0.06681746,0.13363487 +0.9125,0.6125,0.13363475,0.0668174 +0.9125,0.61249995,0.11905497,0.11905509 +0.9125,0.6125,0.08418465,0.1683693 +0.9125,0.6125,0.1683693,0.08418465 +0.9125,0.63750005,0.07499999,0.07499999 +0.9125,0.63750005,0.053033054,0.10606605 +0.9125,0.6375,0.10606593,0.053032994 +0.9125,0.63750005,0.094494045,0.094494045 +0.9125,0.63750005,0.06681746,0.13363487 +0.9125,0.6375,0.13363475,0.0668174 +0.9125,0.63750005,0.11905497,0.11905509 +0.9125,0.6375,0.08418465,0.1683693 +0.9125,0.6375,0.1683693,0.08418465 +0.9125,0.6625,0.07499999,0.07499999 +0.9125,0.6625,0.053033054,0.10606605 +0.9125,0.6625,0.10606593,0.053032935 +0.9125,0.6625,0.094494045,0.094494045 +0.9125,0.6625,0.06681746,0.13363487 +0.9125,0.6625,0.13363475,0.06681734 +0.9125,0.6625,0.11905497,0.11905509 +0.9125,0.6625,0.08418465,0.1683693 +0.9125,0.6625,0.1683693,0.08418465 +0.9125,0.6875,0.07499999,0.07500005 +0.9125,0.6875,0.053033054,0.10606599 +0.9125,0.6875,0.10606593,0.053032994 +0.9125,0.6875,0.094494045,0.094494104 +0.9125,0.6875,0.06681746,0.1336348 +0.9125,0.6875,0.13363475,0.0668174 +0.9125,0.6875,0.11905497,0.11905503 +0.9125,0.6875,0.08418465,0.1683693 +0.9125,0.6875,0.1683693,0.08418465 +0.9125,0.7125,0.07499999,0.07499999 +0.9125,0.7125,0.053033054,0.10606605 +0.9125,0.7125,0.10606593,0.053032935 +0.9125,0.7125,0.094494045,0.094494045 +0.9125,0.7125,0.06681746,0.13363487 +0.9125,0.7125,0.13363475,0.06681734 +0.9125,0.7125,0.11905497,0.11905509 +0.9125,0.7125,0.08418465,0.1683693 +0.9125,0.7125,0.1683693,0.08418465 +0.9125,0.73749995,0.07499999,0.07499999 +0.9125,0.73749995,0.053033054,0.10606605 +0.9125,0.7375,0.10606593,0.053032994 +0.9125,0.73749995,0.094494045,0.094494045 +0.9125,0.73749995,0.06681746,0.1336348 +0.9125,0.7375,0.13363475,0.0668174 +0.9125,0.73749995,0.11905497,0.11905509 +0.9125,0.7375,0.08418465,0.1683693 +0.9125,0.7375,0.1683693,0.08418465 +0.9125,0.76250005,0.07499999,0.07499999 +0.9125,0.7625,0.053033054,0.10606599 +0.9125,0.7625,0.10606593,0.053032994 +0.9125,0.76250005,0.094494045,0.094494045 +0.9125,0.7625,0.06681746,0.1336348 +0.9125,0.7625,0.13363475,0.0668174 +0.9125,0.7625,0.11905497,0.11905503 +0.9125,0.7625,0.08418465,0.1683693 +0.9125,0.7625,0.1683693,0.08418465 +0.9125,0.7875,0.07499999,0.07499999 +0.9125,0.78749996,0.053033054,0.10606599 +0.9125,0.7875,0.10606593,0.053032994 +0.9125,0.7875,0.094494045,0.094494045 +0.9125,0.78749996,0.06681746,0.1336348 +0.9125,0.7875,0.13363475,0.0668174 +0.9125,0.78749996,0.11905497,0.11905503 +0.9125,0.7875,0.08418465,0.1683693 +0.9125,0.7875,0.1683693,0.08418465 +0.9125,0.8125,0.07499999,0.07500005 +0.9125,0.8125,0.053033054,0.10606599 +0.9125,0.8125,0.10606593,0.053033054 +0.9125,0.8125,0.094494045,0.094494104 +0.9125,0.8125,0.06681746,0.1336348 +0.9125,0.8125,0.13363475,0.06681746 +0.9125,0.8125,0.11905497,0.11905503 +0.9125,0.8125,0.08418465,0.1683693 +0.9125,0.8125,0.1683693,0.08418465 +0.9125,0.8375,0.07499999,0.07499999 +0.9125,0.8375,0.053033054,0.10606599 +0.9125,0.8375,0.10606593,0.053033054 +0.9125,0.8375,0.094494045,0.094494045 +0.9125,0.8375,0.06681746,0.1336348 +0.9125,0.8375,0.13363475,0.06681746 +0.9125,0.8375,0.11905497,0.11905503 +0.9125,0.8375,0.08418465,0.1683693 +0.9125,0.8375,0.1683693,0.08418465 +0.9125,0.86249995,0.07499999,0.07499999 +0.9125,0.86249995,0.053033054,0.10606593 +0.9125,0.86249995,0.10606593,0.053033054 +0.9125,0.86249995,0.094494045,0.094494045 +0.9125,0.86249995,0.06681746,0.1336348 +0.9125,0.86249995,0.13363475,0.06681746 +0.9125,0.86249995,0.11905497,0.11905497 +0.9125,0.8625,0.08418465,0.1683693 +0.9125,0.8625,0.1683693,0.08418465 +0.9125,0.88750005,0.07499999,0.07499999 +0.9125,0.88750005,0.053033054,0.10606593 +0.9125,0.88750005,0.10606593,0.053033054 +0.9125,0.88750005,0.094494045,0.094494045 +0.9125,0.88750005,0.06681746,0.13363475 +0.9125,0.88750005,0.13363475,0.06681746 +0.9125,0.88750005,0.11905497,0.11905497 +0.9125,0.8875,0.08418465,0.1683693 +0.9125,0.8875,0.1683693,0.08418465 +0.9125,0.9125,0.07499999,0.07499999 +0.9125,0.9125,0.053033054,0.10606593 +0.9125,0.9125,0.10606593,0.053033054 +0.9125,0.9125,0.094494045,0.094494045 +0.9125,0.9125,0.06681746,0.13363475 +0.9125,0.9125,0.13363475,0.06681746 +0.9125,0.9125,0.11905497,0.11905497 +0.9125,0.9125,0.08418465,0.1683693 +0.9125,0.9125,0.1683693,0.08418465 +0.9125,0.9375,0.07499999,0.07500005 +0.9125,0.9375,0.053033054,0.10606599 +0.9125,0.9375,0.10606593,0.053033113 +0.9125,0.9375,0.094494045,0.094494104 +0.9125,0.9375,0.06681746,0.1336348 +0.9125,0.9375,0.13363475,0.06681752 +0.9125,0.9375,0.11905497,0.11905503 +0.9125,0.9375,0.08418465,0.1683693 +0.9125,0.9375,0.1683693,0.08418465 +0.9125,0.9625,0.07499999,0.07499999 +0.9125,0.9625,0.053033054,0.10606593 +0.9125,0.9625,0.10606593,0.053033054 +0.9125,0.9625,0.094494045,0.094494045 +0.9125,0.9625,0.06681746,0.13363475 +0.9125,0.9625,0.13363475,0.06681746 +0.9125,0.9625,0.11905497,0.11905497 +0.9125,0.9625,0.08418465,0.1683693 +0.9125,0.9625,0.1683693,0.08418465 +0.9125,0.98749995,0.07499999,0.07499999 +0.9125,0.98749995,0.053033054,0.10606593 +0.9125,0.98749995,0.10606593,0.053033054 +0.9125,0.98749995,0.094494045,0.094494045 +0.9125,0.98749995,0.06681746,0.13363475 +0.9125,0.98749995,0.13363475,0.06681746 +0.9125,0.98749995,0.11905497,0.11905497 +0.9125,0.98749995,0.08418465,0.16836923 +0.9125,0.98749995,0.1683693,0.08418459 +0.9375,0.0125,0.07500005,0.075 +0.9375,0.012499997,0.053033113,0.10606602 +0.9375,0.012499999,0.10606599,0.05303301 +0.9375,0.012499999,0.094494104,0.09449408 +0.9375,0.012500001,0.06681752,0.1336348 +0.9375,0.012499999,0.1336348,0.0668174 +0.9375,0.012500001,0.11905503,0.11905508 +0.9375,0.012499999,0.08418465,0.1683693 +0.9375,0.012500002,0.1683693,0.084184654 +0.9375,0.0375,0.07500005,0.075 +0.9375,0.037499998,0.053033113,0.10606601 +0.9375,0.0375,0.10606599,0.05303301 +0.9375,0.0375,0.094494104,0.094494075 +0.9375,0.0375,0.06681752,0.1336348 +0.9375,0.0375,0.1336348,0.0668174 +0.9375,0.0375,0.11905503,0.11905508 +0.9375,0.0375,0.08418465,0.16836931 +0.9375,0.0375,0.1683693,0.08418466 +0.9375,0.0625,0.07500005,0.075 +0.9375,0.0625,0.053033113,0.10606602 +0.9375,0.0625,0.10606599,0.05303301 +0.9375,0.0625,0.094494104,0.094494075 +0.9375,0.0625,0.06681752,0.1336348 +0.9375,0.0625,0.1336348,0.0668174 +0.9375,0.0625,0.11905503,0.11905508 +0.9375,0.0625,0.08418465,0.16836932 +0.9375,0.0625,0.1683693,0.08418465 +0.9375,0.0875,0.07500005,0.075 +0.9375,0.08749999,0.053033113,0.10606601 +0.9375,0.087500006,0.10606599,0.053033013 +0.9375,0.087500006,0.094494104,0.09449408 +0.9375,0.087500006,0.06681752,0.1336348 +0.9375,0.0875,0.1336348,0.0668174 +0.9375,0.0875,0.11905503,0.11905508 +0.9375,0.0875,0.08418465,0.16836931 +0.9375,0.087500006,0.1683693,0.084184654 +0.9375,0.112500004,0.07500005,0.075 +0.9375,0.1125,0.053033113,0.10606601 +0.9375,0.112500004,0.10606599,0.05303301 +0.9375,0.1125,0.094494104,0.094494075 +0.9375,0.1125,0.06681752,0.1336348 +0.9375,0.1125,0.1336348,0.0668174 +0.9375,0.1125,0.11905503,0.119055085 +0.9375,0.112500004,0.08418465,0.16836931 +0.9375,0.1125,0.1683693,0.08418465 +0.9375,0.1375,0.07500005,0.074999996 +0.9375,0.1375,0.053033113,0.10606602 +0.9375,0.1375,0.10606599,0.053033024 +0.9375,0.1375,0.094494104,0.09449408 +0.9375,0.1375,0.06681752,0.1336348 +0.9375,0.1375,0.1336348,0.0668174 +0.9375,0.13749999,0.11905503,0.11905508 +0.9375,0.1375,0.08418465,0.1683693 +0.9375,0.1375,0.1683693,0.084184654 +0.9375,0.1625,0.07500005,0.075 +0.9375,0.16250001,0.053033113,0.106066026 +0.9375,0.1625,0.10606599,0.05303301 +0.9375,0.1625,0.094494104,0.094494075 +0.9375,0.1625,0.06681752,0.1336348 +0.9375,0.1625,0.1336348,0.0668174 +0.9375,0.1625,0.11905503,0.11905508 +0.9375,0.1625,0.08418465,0.1683693 +0.9375,0.1625,0.1683693,0.08418464 +0.9375,0.1875,0.07500005,0.07499999 +0.9375,0.1875,0.053033113,0.10606603 +0.9375,0.1875,0.10606599,0.053033024 +0.9375,0.1875,0.094494104,0.09449406 +0.9375,0.1875,0.06681752,0.1336348 +0.9375,0.1875,0.1336348,0.06681742 +0.9375,0.1875,0.11905503,0.11905509 +0.9375,0.1875,0.08418465,0.16836931 +0.9375,0.1875,0.1683693,0.08418465 +0.9375,0.2125,0.07500005,0.075 +0.9375,0.2125,0.053033113,0.10606603 +0.9375,0.2125,0.10606599,0.05303301 +0.9375,0.21249999,0.094494104,0.094494075 +0.9375,0.2125,0.06681752,0.1336348 +0.9375,0.2125,0.1336348,0.0668174 +0.9375,0.2125,0.11905503,0.11905509 +0.9375,0.2125,0.08418465,0.16836931 +0.9375,0.2125,0.1683693,0.08418465 +0.9375,0.23750001,0.07500005,0.075 +0.9375,0.2375,0.053033113,0.10606602 +0.9375,0.2375,0.10606599,0.053033024 +0.9375,0.2375,0.094494104,0.094494075 +0.9375,0.23750001,0.06681752,0.13363482 +0.9375,0.2375,0.1336348,0.06681743 +0.9375,0.2375,0.11905503,0.11905506 +0.9375,0.2375,0.08418465,0.16836932 +0.9375,0.23750001,0.1683693,0.08418466 +0.9375,0.2625,0.07500005,0.07500002 +0.9375,0.2625,0.053033113,0.10606603 +0.9375,0.2625,0.10606599,0.053033024 +0.9375,0.2625,0.094494104,0.094494075 +0.9375,0.2625,0.06681752,0.13363479 +0.9375,0.2625,0.1336348,0.06681743 +0.9375,0.2625,0.11905503,0.11905508 +0.9375,0.2625,0.08418465,0.1683693 +0.9375,0.2625,0.1683693,0.08418463 +0.9375,0.2875,0.07500005,0.07499999 +0.9375,0.2875,0.053033113,0.10606603 +0.9375,0.28750002,0.10606599,0.053033024 +0.9375,0.2875,0.094494104,0.094494045 +0.9375,0.2875,0.06681752,0.1336348 +0.9375,0.28750002,0.1336348,0.06681743 +0.9375,0.2875,0.11905503,0.11905508 +0.9375,0.2875,0.08418465,0.1683693 +0.9375,0.2875,0.1683693,0.08418465 +0.9375,0.3125,0.07500005,0.07499999 +0.9375,0.3125,0.053033113,0.10606605 +0.9375,0.3125,0.10606599,0.053032994 +0.9375,0.3125,0.094494104,0.094494045 +0.9375,0.3125,0.06681752,0.1336348 +0.9375,0.3125,0.1336348,0.0668174 +0.9375,0.3125,0.11905503,0.11905509 +0.9375,0.3125,0.08418465,0.1683693 +0.9375,0.3125,0.1683693,0.08418465 +0.9375,0.3375,0.07500005,0.07499999 +0.9375,0.3375,0.053033113,0.10606605 +0.9375,0.33749998,0.10606599,0.053033024 +0.9375,0.3375,0.094494104,0.094494045 +0.9375,0.33750004,0.06681752,0.13363484 +0.9375,0.33749998,0.1336348,0.06681743 +0.9375,0.3375,0.11905503,0.11905509 +0.9375,0.3375,0.08418465,0.1683693 +0.9375,0.3375,0.1683693,0.08418465 +0.9375,0.3625,0.07500005,0.07500002 +0.9375,0.3625,0.053033113,0.10606602 +0.9375,0.3625,0.10606599,0.053033024 +0.9375,0.3625,0.094494104,0.094494075 +0.9375,0.3625,0.06681752,0.1336348 +0.9375,0.3625,0.1336348,0.06681743 +0.9375,0.3625,0.11905503,0.11905506 +0.9375,0.3625,0.08418465,0.1683693 +0.9375,0.3625,0.1683693,0.08418465 +0.9375,0.3875,0.07500005,0.07500002 +0.9375,0.3875,0.053033113,0.10606602 +0.9375,0.3875,0.10606599,0.053032994 +0.9375,0.3875,0.094494104,0.094494075 +0.9375,0.3875,0.06681752,0.13363484 +0.9375,0.3875,0.1336348,0.0668174 +0.9375,0.3875,0.11905503,0.11905506 +0.9375,0.3875,0.08418465,0.1683693 +0.9375,0.3875,0.1683693,0.08418465 +0.9375,0.4125,0.07500005,0.07499999 +0.9375,0.4125,0.053033113,0.10606605 +0.9375,0.4125,0.10606599,0.053032994 +0.9375,0.4125,0.094494104,0.094494045 +0.9375,0.41250002,0.06681752,0.13363484 +0.9375,0.4125,0.1336348,0.0668174 +0.9375,0.4125,0.11905503,0.11905509 +0.9375,0.4125,0.08418465,0.1683693 +0.9375,0.4125,0.1683693,0.08418465 +0.9375,0.4375,0.07500005,0.07499999 +0.9375,0.4375,0.053033113,0.10606605 +0.9375,0.4375,0.10606599,0.053032994 +0.9375,0.4375,0.094494104,0.094494045 +0.9375,0.4375,0.06681752,0.1336348 +0.9375,0.4375,0.1336348,0.0668174 +0.9375,0.4375,0.11905503,0.11905509 +0.9375,0.4375,0.08418465,0.1683693 +0.9375,0.4375,0.1683693,0.08418465 +0.9375,0.4625,0.07500005,0.07499999 +0.9375,0.4625,0.053033113,0.10606605 +0.9375,0.46249998,0.10606599,0.053032964 +0.9375,0.4625,0.094494104,0.094494045 +0.9375,0.46250004,0.06681752,0.13363484 +0.9375,0.46249998,0.1336348,0.06681737 +0.9375,0.4625,0.11905503,0.11905509 +0.9375,0.46249998,0.08418465,0.16836926 +0.9375,0.46249998,0.1683693,0.08418462 +0.9375,0.48749998,0.07500005,0.07499999 +0.9375,0.4875,0.053033113,0.10606602 +0.9375,0.4875,0.10606599,0.053032994 +0.9375,0.48749998,0.094494104,0.094494045 +0.9375,0.4875,0.06681752,0.13363484 +0.9375,0.4875,0.1336348,0.0668174 +0.9375,0.4875,0.11905503,0.11905506 +0.9375,0.4875,0.08418465,0.1683693 +0.9375,0.4875,0.1683693,0.08418465 +0.9375,0.5125,0.07500005,0.07500002 +0.9375,0.51250005,0.053033113,0.10606605 +0.9375,0.5125,0.10606599,0.053032964 +0.9375,0.5125,0.094494104,0.094494075 +0.9375,0.51250005,0.06681752,0.13363487 +0.9375,0.5125,0.1336348,0.06681737 +0.9375,0.51250005,0.11905503,0.11905509 +0.9375,0.5125,0.08418465,0.1683693 +0.9375,0.5125,0.1683693,0.08418465 +0.9375,0.5375,0.07500005,0.07499999 +0.9375,0.5375,0.053033113,0.10606605 +0.9375,0.5375,0.10606599,0.053032935 +0.9375,0.5375,0.094494104,0.094494045 +0.9375,0.5375,0.06681752,0.13363487 +0.9375,0.5375,0.1336348,0.06681734 +0.9375,0.5375,0.11905503,0.11905509 +0.9375,0.5375,0.08418465,0.16836932 +0.9375,0.5375,0.1683693,0.08418468 +0.9375,0.5625,0.07500005,0.07500005 +0.9375,0.5625,0.053033113,0.10606599 +0.9375,0.5625,0.10606599,0.053032994 +0.9375,0.5625,0.094494104,0.094494104 +0.9375,0.5625,0.06681752,0.13363484 +0.9375,0.5625,0.1336348,0.0668174 +0.9375,0.5625,0.11905503,0.11905503 +0.9375,0.5625,0.08418465,0.1683693 +0.9375,0.5625,0.1683693,0.08418465 +0.9375,0.5875,0.07500005,0.07499999 +0.9375,0.5875,0.053033113,0.10606605 +0.9375,0.5875,0.10606599,0.053032935 +0.9375,0.5875,0.094494104,0.094494045 +0.9375,0.5875,0.06681752,0.13363487 +0.9375,0.5875,0.1336348,0.06681734 +0.9375,0.5875,0.11905503,0.11905509 +0.9375,0.5875,0.08418465,0.1683693 +0.9375,0.5875,0.1683693,0.08418465 +0.9375,0.61249995,0.07500005,0.07499999 +0.9375,0.61249995,0.053033113,0.10606605 +0.9375,0.6125,0.10606599,0.053032994 +0.9375,0.61249995,0.094494104,0.094494045 +0.9375,0.61249995,0.06681752,0.13363487 +0.9375,0.6125,0.1336348,0.0668174 +0.9375,0.61249995,0.11905503,0.11905509 +0.9375,0.6125,0.08418465,0.1683693 +0.9375,0.6125,0.1683693,0.08418465 +0.9375,0.63750005,0.07500005,0.07499999 +0.9375,0.63750005,0.053033113,0.10606605 +0.9375,0.6375,0.10606599,0.053032994 +0.9375,0.63750005,0.094494104,0.094494045 +0.9375,0.63750005,0.06681752,0.13363487 +0.9375,0.6375,0.1336348,0.0668174 +0.9375,0.63750005,0.11905503,0.11905509 +0.9375,0.6375,0.08418465,0.1683693 +0.9375,0.6375,0.1683693,0.08418465 +0.9375,0.6625,0.07500005,0.07499999 +0.9375,0.6625,0.053033113,0.10606605 +0.9375,0.6625,0.10606599,0.053032935 +0.9375,0.6625,0.094494104,0.094494045 +0.9375,0.6625,0.06681752,0.13363487 +0.9375,0.6625,0.1336348,0.06681734 +0.9375,0.6625,0.11905503,0.11905509 +0.9375,0.6625,0.08418465,0.1683693 +0.9375,0.6625,0.1683693,0.08418465 +0.9375,0.6875,0.07500005,0.07500005 +0.9375,0.6875,0.053033113,0.10606599 +0.9375,0.6875,0.10606599,0.053032994 +0.9375,0.6875,0.094494104,0.094494104 +0.9375,0.6875,0.06681752,0.1336348 +0.9375,0.6875,0.1336348,0.0668174 +0.9375,0.6875,0.11905503,0.11905503 +0.9375,0.6875,0.08418465,0.1683693 +0.9375,0.6875,0.1683693,0.08418465 +0.9375,0.7125,0.07500005,0.07499999 +0.9375,0.7125,0.053033113,0.10606605 +0.9375,0.7125,0.10606599,0.053032935 +0.9375,0.7125,0.094494104,0.094494045 +0.9375,0.7125,0.06681752,0.13363487 +0.9375,0.7125,0.1336348,0.06681734 +0.9375,0.7125,0.11905503,0.11905509 +0.9375,0.7125,0.08418465,0.1683693 +0.9375,0.7125,0.1683693,0.08418465 +0.9375,0.73749995,0.07500005,0.07499999 +0.9375,0.73749995,0.053033113,0.10606605 +0.9375,0.7375,0.10606599,0.053032994 +0.9375,0.73749995,0.094494104,0.094494045 +0.9375,0.73749995,0.06681752,0.1336348 +0.9375,0.7375,0.1336348,0.0668174 +0.9375,0.73749995,0.11905503,0.11905509 +0.9375,0.7375,0.08418465,0.1683693 +0.9375,0.7375,0.1683693,0.08418465 +0.9375,0.76250005,0.07500005,0.07499999 +0.9375,0.7625,0.053033113,0.10606599 +0.9375,0.7625,0.10606599,0.053032994 +0.9375,0.76250005,0.094494104,0.094494045 +0.9375,0.7625,0.06681752,0.1336348 +0.9375,0.7625,0.1336348,0.0668174 +0.9375,0.7625,0.11905503,0.11905503 +0.9375,0.7625,0.08418465,0.1683693 +0.9375,0.7625,0.1683693,0.08418465 +0.9375,0.7875,0.07500005,0.07499999 +0.9375,0.78749996,0.053033113,0.10606599 +0.9375,0.7875,0.10606599,0.053032994 +0.9375,0.7875,0.094494104,0.094494045 +0.9375,0.78749996,0.06681752,0.1336348 +0.9375,0.7875,0.1336348,0.0668174 +0.9375,0.78749996,0.11905503,0.11905503 +0.9375,0.7875,0.08418465,0.1683693 +0.9375,0.7875,0.1683693,0.08418465 +0.9375,0.8125,0.07500005,0.07500005 +0.9375,0.8125,0.053033113,0.10606599 +0.9375,0.8125,0.10606599,0.053033054 +0.9375,0.8125,0.094494104,0.094494104 +0.9375,0.8125,0.06681752,0.1336348 +0.9375,0.8125,0.1336348,0.06681746 +0.9375,0.8125,0.11905503,0.11905503 +0.9375,0.8125,0.08418465,0.1683693 +0.9375,0.8125,0.1683693,0.08418465 +0.9375,0.8375,0.07500005,0.07499999 +0.9375,0.8375,0.053033113,0.10606599 +0.9375,0.8375,0.10606599,0.053033054 +0.9375,0.8375,0.094494104,0.094494045 +0.9375,0.8375,0.06681752,0.1336348 +0.9375,0.8375,0.1336348,0.06681746 +0.9375,0.8375,0.11905503,0.11905503 +0.9375,0.8375,0.08418465,0.1683693 +0.9375,0.8375,0.1683693,0.08418465 +0.9375,0.86249995,0.07500005,0.07499999 +0.9375,0.86249995,0.053033113,0.10606593 +0.9375,0.86249995,0.10606599,0.053033054 +0.9375,0.86249995,0.094494104,0.094494045 +0.9375,0.86249995,0.06681752,0.1336348 +0.9375,0.86249995,0.1336348,0.06681746 +0.9375,0.86249995,0.11905503,0.11905497 +0.9375,0.8625,0.08418465,0.1683693 +0.9375,0.8625,0.1683693,0.08418465 +0.9375,0.88750005,0.07500005,0.07499999 +0.9375,0.88750005,0.053033113,0.10606593 +0.9375,0.88750005,0.10606599,0.053033054 +0.9375,0.88750005,0.094494104,0.094494045 +0.9375,0.88750005,0.06681752,0.13363475 +0.9375,0.88750005,0.1336348,0.06681746 +0.9375,0.88750005,0.11905503,0.11905497 +0.9375,0.8875,0.08418465,0.1683693 +0.9375,0.8875,0.1683693,0.08418465 +0.9375,0.9125,0.07500005,0.07499999 +0.9375,0.9125,0.053033113,0.10606593 +0.9375,0.9125,0.10606599,0.053033054 +0.9375,0.9125,0.094494104,0.094494045 +0.9375,0.9125,0.06681752,0.13363475 +0.9375,0.9125,0.1336348,0.06681746 +0.9375,0.9125,0.11905503,0.11905497 +0.9375,0.9125,0.08418465,0.1683693 +0.9375,0.9125,0.1683693,0.08418465 +0.9375,0.9375,0.07500005,0.07500005 +0.9375,0.9375,0.053033113,0.10606599 +0.9375,0.9375,0.10606599,0.053033113 +0.9375,0.9375,0.094494104,0.094494104 +0.9375,0.9375,0.06681752,0.1336348 +0.9375,0.9375,0.1336348,0.06681752 +0.9375,0.9375,0.11905503,0.11905503 +0.9375,0.9375,0.08418465,0.1683693 +0.9375,0.9375,0.1683693,0.08418465 +0.9375,0.9625,0.07500005,0.07499999 +0.9375,0.9625,0.053033113,0.10606593 +0.9375,0.9625,0.10606599,0.053033054 +0.9375,0.9625,0.094494104,0.094494045 +0.9375,0.9625,0.06681752,0.13363475 +0.9375,0.9625,0.1336348,0.06681746 +0.9375,0.9625,0.11905503,0.11905497 +0.9375,0.9625,0.08418465,0.1683693 +0.9375,0.9625,0.1683693,0.08418465 +0.9375,0.98749995,0.07500005,0.07499999 +0.9375,0.98749995,0.053033113,0.10606593 +0.9375,0.98749995,0.10606599,0.053033054 +0.9375,0.98749995,0.094494104,0.094494045 +0.9375,0.98749995,0.06681752,0.13363475 +0.9375,0.98749995,0.1336348,0.06681746 +0.9375,0.98749995,0.11905503,0.11905497 +0.9375,0.98749995,0.08418465,0.16836923 +0.9375,0.98749995,0.1683693,0.08418459 +0.9625,0.0125,0.07499999,0.075 +0.9625,0.012499997,0.053033054,0.10606602 +0.9625,0.012499999,0.10606593,0.05303301 +0.9625,0.012499999,0.094494045,0.09449408 +0.9625,0.012500001,0.06681746,0.1336348 +0.9625,0.012499999,0.13363475,0.0668174 +0.9625,0.012500001,0.11905497,0.11905508 +0.9625,0.012499999,0.08418465,0.1683693 +0.9625,0.012500002,0.1683693,0.084184654 +0.9625,0.0375,0.07499999,0.075 +0.9625,0.037499998,0.053033054,0.10606601 +0.9625,0.0375,0.10606593,0.05303301 +0.9625,0.0375,0.094494045,0.094494075 +0.9625,0.0375,0.06681746,0.1336348 +0.9625,0.0375,0.13363475,0.0668174 +0.9625,0.0375,0.11905497,0.11905508 +0.9625,0.0375,0.08418465,0.16836931 +0.9625,0.0375,0.1683693,0.08418466 +0.9625,0.0625,0.07499999,0.075 +0.9625,0.0625,0.053033054,0.10606602 +0.9625,0.0625,0.10606593,0.05303301 +0.9625,0.0625,0.094494045,0.094494075 +0.9625,0.0625,0.06681746,0.1336348 +0.9625,0.0625,0.13363475,0.0668174 +0.9625,0.0625,0.11905497,0.11905508 +0.9625,0.0625,0.08418465,0.16836932 +0.9625,0.0625,0.1683693,0.08418465 +0.9625,0.0875,0.07499999,0.075 +0.9625,0.08749999,0.053033054,0.10606601 +0.9625,0.087500006,0.10606593,0.053033013 +0.9625,0.087500006,0.094494045,0.09449408 +0.9625,0.087500006,0.06681746,0.1336348 +0.9625,0.0875,0.13363475,0.0668174 +0.9625,0.0875,0.11905497,0.11905508 +0.9625,0.0875,0.08418465,0.16836931 +0.9625,0.087500006,0.1683693,0.084184654 +0.9625,0.112500004,0.07499999,0.075 +0.9625,0.1125,0.053033054,0.10606601 +0.9625,0.112500004,0.10606593,0.05303301 +0.9625,0.1125,0.094494045,0.094494075 +0.9625,0.1125,0.06681746,0.1336348 +0.9625,0.1125,0.13363475,0.0668174 +0.9625,0.1125,0.11905497,0.119055085 +0.9625,0.112500004,0.08418465,0.16836931 +0.9625,0.1125,0.1683693,0.08418465 +0.9625,0.1375,0.07499999,0.074999996 +0.9625,0.1375,0.053033054,0.10606602 +0.9625,0.1375,0.10606593,0.053033024 +0.9625,0.1375,0.094494045,0.09449408 +0.9625,0.1375,0.06681746,0.1336348 +0.9625,0.1375,0.13363475,0.0668174 +0.9625,0.13749999,0.11905497,0.11905508 +0.9625,0.1375,0.08418465,0.1683693 +0.9625,0.1375,0.1683693,0.084184654 +0.9625,0.1625,0.07499999,0.075 +0.9625,0.16250001,0.053033054,0.106066026 +0.9625,0.1625,0.10606593,0.05303301 +0.9625,0.1625,0.094494045,0.094494075 +0.9625,0.1625,0.06681746,0.1336348 +0.9625,0.1625,0.13363475,0.0668174 +0.9625,0.1625,0.11905497,0.11905508 +0.9625,0.1625,0.08418465,0.1683693 +0.9625,0.1625,0.1683693,0.08418464 +0.9625,0.1875,0.07499999,0.07499999 +0.9625,0.1875,0.053033054,0.10606603 +0.9625,0.1875,0.10606593,0.053033024 +0.9625,0.1875,0.094494045,0.09449406 +0.9625,0.1875,0.06681746,0.1336348 +0.9625,0.1875,0.13363475,0.06681742 +0.9625,0.1875,0.11905497,0.11905509 +0.9625,0.1875,0.08418465,0.16836931 +0.9625,0.1875,0.1683693,0.08418465 +0.9625,0.2125,0.07499999,0.075 +0.9625,0.2125,0.053033054,0.10606603 +0.9625,0.2125,0.10606593,0.05303301 +0.9625,0.21249999,0.094494045,0.094494075 +0.9625,0.2125,0.06681746,0.1336348 +0.9625,0.2125,0.13363475,0.0668174 +0.9625,0.2125,0.11905497,0.11905509 +0.9625,0.2125,0.08418465,0.16836931 +0.9625,0.2125,0.1683693,0.08418465 +0.9625,0.23750001,0.07499999,0.075 +0.9625,0.2375,0.053033054,0.10606602 +0.9625,0.2375,0.10606593,0.053033024 +0.9625,0.2375,0.094494045,0.094494075 +0.9625,0.23750001,0.06681746,0.13363482 +0.9625,0.2375,0.13363475,0.06681743 +0.9625,0.2375,0.11905497,0.11905506 +0.9625,0.2375,0.08418465,0.16836932 +0.9625,0.23750001,0.1683693,0.08418466 +0.9625,0.2625,0.07499999,0.07500002 +0.9625,0.2625,0.053033054,0.10606603 +0.9625,0.2625,0.10606593,0.053033024 +0.9625,0.2625,0.094494045,0.094494075 +0.9625,0.2625,0.06681746,0.13363479 +0.9625,0.2625,0.13363475,0.06681743 +0.9625,0.2625,0.11905497,0.11905508 +0.9625,0.2625,0.08418465,0.1683693 +0.9625,0.2625,0.1683693,0.08418463 +0.9625,0.2875,0.07499999,0.07499999 +0.9625,0.2875,0.053033054,0.10606603 +0.9625,0.28750002,0.10606593,0.053033024 +0.9625,0.2875,0.094494045,0.094494045 +0.9625,0.2875,0.06681746,0.1336348 +0.9625,0.28750002,0.13363475,0.06681743 +0.9625,0.2875,0.11905497,0.11905508 +0.9625,0.2875,0.08418465,0.1683693 +0.9625,0.2875,0.1683693,0.08418465 +0.9625,0.3125,0.07499999,0.07499999 +0.9625,0.3125,0.053033054,0.10606605 +0.9625,0.3125,0.10606593,0.053032994 +0.9625,0.3125,0.094494045,0.094494045 +0.9625,0.3125,0.06681746,0.1336348 +0.9625,0.3125,0.13363475,0.0668174 +0.9625,0.3125,0.11905497,0.11905509 +0.9625,0.3125,0.08418465,0.1683693 +0.9625,0.3125,0.1683693,0.08418465 +0.9625,0.3375,0.07499999,0.07499999 +0.9625,0.3375,0.053033054,0.10606605 +0.9625,0.33749998,0.10606593,0.053033024 +0.9625,0.3375,0.094494045,0.094494045 +0.9625,0.33750004,0.06681746,0.13363484 +0.9625,0.33749998,0.13363475,0.06681743 +0.9625,0.3375,0.11905497,0.11905509 +0.9625,0.3375,0.08418465,0.1683693 +0.9625,0.3375,0.1683693,0.08418465 +0.9625,0.3625,0.07499999,0.07500002 +0.9625,0.3625,0.053033054,0.10606602 +0.9625,0.3625,0.10606593,0.053033024 +0.9625,0.3625,0.094494045,0.094494075 +0.9625,0.3625,0.06681746,0.1336348 +0.9625,0.3625,0.13363475,0.06681743 +0.9625,0.3625,0.11905497,0.11905506 +0.9625,0.3625,0.08418465,0.1683693 +0.9625,0.3625,0.1683693,0.08418465 +0.9625,0.3875,0.07499999,0.07500002 +0.9625,0.3875,0.053033054,0.10606602 +0.9625,0.3875,0.10606593,0.053032994 +0.9625,0.3875,0.094494045,0.094494075 +0.9625,0.3875,0.06681746,0.13363484 +0.9625,0.3875,0.13363475,0.0668174 +0.9625,0.3875,0.11905497,0.11905506 +0.9625,0.3875,0.08418465,0.1683693 +0.9625,0.3875,0.1683693,0.08418465 +0.9625,0.4125,0.07499999,0.07499999 +0.9625,0.4125,0.053033054,0.10606605 +0.9625,0.4125,0.10606593,0.053032994 +0.9625,0.4125,0.094494045,0.094494045 +0.9625,0.41250002,0.06681746,0.13363484 +0.9625,0.4125,0.13363475,0.0668174 +0.9625,0.4125,0.11905497,0.11905509 +0.9625,0.4125,0.08418465,0.1683693 +0.9625,0.4125,0.1683693,0.08418465 +0.9625,0.4375,0.07499999,0.07499999 +0.9625,0.4375,0.053033054,0.10606605 +0.9625,0.4375,0.10606593,0.053032994 +0.9625,0.4375,0.094494045,0.094494045 +0.9625,0.4375,0.06681746,0.1336348 +0.9625,0.4375,0.13363475,0.0668174 +0.9625,0.4375,0.11905497,0.11905509 +0.9625,0.4375,0.08418465,0.1683693 +0.9625,0.4375,0.1683693,0.08418465 +0.9625,0.4625,0.07499999,0.07499999 +0.9625,0.4625,0.053033054,0.10606605 +0.9625,0.46249998,0.10606593,0.053032964 +0.9625,0.4625,0.094494045,0.094494045 +0.9625,0.46250004,0.06681746,0.13363484 +0.9625,0.46249998,0.13363475,0.06681737 +0.9625,0.4625,0.11905497,0.11905509 +0.9625,0.46249998,0.08418465,0.16836926 +0.9625,0.46249998,0.1683693,0.08418462 +0.9625,0.48749998,0.07499999,0.07499999 +0.9625,0.4875,0.053033054,0.10606602 +0.9625,0.4875,0.10606593,0.053032994 +0.9625,0.48749998,0.094494045,0.094494045 +0.9625,0.4875,0.06681746,0.13363484 +0.9625,0.4875,0.13363475,0.0668174 +0.9625,0.4875,0.11905497,0.11905506 +0.9625,0.4875,0.08418465,0.1683693 +0.9625,0.4875,0.1683693,0.08418465 +0.9625,0.5125,0.07499999,0.07500002 +0.9625,0.51250005,0.053033054,0.10606605 +0.9625,0.5125,0.10606593,0.053032964 +0.9625,0.5125,0.094494045,0.094494075 +0.9625,0.51250005,0.06681746,0.13363487 +0.9625,0.5125,0.13363475,0.06681737 +0.9625,0.51250005,0.11905497,0.11905509 +0.9625,0.5125,0.08418465,0.1683693 +0.9625,0.5125,0.1683693,0.08418465 +0.9625,0.5375,0.07499999,0.07499999 +0.9625,0.5375,0.053033054,0.10606605 +0.9625,0.5375,0.10606593,0.053032935 +0.9625,0.5375,0.094494045,0.094494045 +0.9625,0.5375,0.06681746,0.13363487 +0.9625,0.5375,0.13363475,0.06681734 +0.9625,0.5375,0.11905497,0.11905509 +0.9625,0.5375,0.08418465,0.16836932 +0.9625,0.5375,0.1683693,0.08418468 +0.9625,0.5625,0.07499999,0.07500005 +0.9625,0.5625,0.053033054,0.10606599 +0.9625,0.5625,0.10606593,0.053032994 +0.9625,0.5625,0.094494045,0.094494104 +0.9625,0.5625,0.06681746,0.13363484 +0.9625,0.5625,0.13363475,0.0668174 +0.9625,0.5625,0.11905497,0.11905503 +0.9625,0.5625,0.08418465,0.1683693 +0.9625,0.5625,0.1683693,0.08418465 +0.9625,0.5875,0.07499999,0.07499999 +0.9625,0.5875,0.053033054,0.10606605 +0.9625,0.5875,0.10606593,0.053032935 +0.9625,0.5875,0.094494045,0.094494045 +0.9625,0.5875,0.06681746,0.13363487 +0.9625,0.5875,0.13363475,0.06681734 +0.9625,0.5875,0.11905497,0.11905509 +0.9625,0.5875,0.08418465,0.1683693 +0.9625,0.5875,0.1683693,0.08418465 +0.9625,0.61249995,0.07499999,0.07499999 +0.9625,0.61249995,0.053033054,0.10606605 +0.9625,0.6125,0.10606593,0.053032994 +0.9625,0.61249995,0.094494045,0.094494045 +0.9625,0.61249995,0.06681746,0.13363487 +0.9625,0.6125,0.13363475,0.0668174 +0.9625,0.61249995,0.11905497,0.11905509 +0.9625,0.6125,0.08418465,0.1683693 +0.9625,0.6125,0.1683693,0.08418465 +0.9625,0.63750005,0.07499999,0.07499999 +0.9625,0.63750005,0.053033054,0.10606605 +0.9625,0.6375,0.10606593,0.053032994 +0.9625,0.63750005,0.094494045,0.094494045 +0.9625,0.63750005,0.06681746,0.13363487 +0.9625,0.6375,0.13363475,0.0668174 +0.9625,0.63750005,0.11905497,0.11905509 +0.9625,0.6375,0.08418465,0.1683693 +0.9625,0.6375,0.1683693,0.08418465 +0.9625,0.6625,0.07499999,0.07499999 +0.9625,0.6625,0.053033054,0.10606605 +0.9625,0.6625,0.10606593,0.053032935 +0.9625,0.6625,0.094494045,0.094494045 +0.9625,0.6625,0.06681746,0.13363487 +0.9625,0.6625,0.13363475,0.06681734 +0.9625,0.6625,0.11905497,0.11905509 +0.9625,0.6625,0.08418465,0.1683693 +0.9625,0.6625,0.1683693,0.08418465 +0.9625,0.6875,0.07499999,0.07500005 +0.9625,0.6875,0.053033054,0.10606599 +0.9625,0.6875,0.10606593,0.053032994 +0.9625,0.6875,0.094494045,0.094494104 +0.9625,0.6875,0.06681746,0.1336348 +0.9625,0.6875,0.13363475,0.0668174 +0.9625,0.6875,0.11905497,0.11905503 +0.9625,0.6875,0.08418465,0.1683693 +0.9625,0.6875,0.1683693,0.08418465 +0.9625,0.7125,0.07499999,0.07499999 +0.9625,0.7125,0.053033054,0.10606605 +0.9625,0.7125,0.10606593,0.053032935 +0.9625,0.7125,0.094494045,0.094494045 +0.9625,0.7125,0.06681746,0.13363487 +0.9625,0.7125,0.13363475,0.06681734 +0.9625,0.7125,0.11905497,0.11905509 +0.9625,0.7125,0.08418465,0.1683693 +0.9625,0.7125,0.1683693,0.08418465 +0.9625,0.73749995,0.07499999,0.07499999 +0.9625,0.73749995,0.053033054,0.10606605 +0.9625,0.7375,0.10606593,0.053032994 +0.9625,0.73749995,0.094494045,0.094494045 +0.9625,0.73749995,0.06681746,0.1336348 +0.9625,0.7375,0.13363475,0.0668174 +0.9625,0.73749995,0.11905497,0.11905509 +0.9625,0.7375,0.08418465,0.1683693 +0.9625,0.7375,0.1683693,0.08418465 +0.9625,0.76250005,0.07499999,0.07499999 +0.9625,0.7625,0.053033054,0.10606599 +0.9625,0.7625,0.10606593,0.053032994 +0.9625,0.76250005,0.094494045,0.094494045 +0.9625,0.7625,0.06681746,0.1336348 +0.9625,0.7625,0.13363475,0.0668174 +0.9625,0.7625,0.11905497,0.11905503 +0.9625,0.7625,0.08418465,0.1683693 +0.9625,0.7625,0.1683693,0.08418465 +0.9625,0.7875,0.07499999,0.07499999 +0.9625,0.78749996,0.053033054,0.10606599 +0.9625,0.7875,0.10606593,0.053032994 +0.9625,0.7875,0.094494045,0.094494045 +0.9625,0.78749996,0.06681746,0.1336348 +0.9625,0.7875,0.13363475,0.0668174 +0.9625,0.78749996,0.11905497,0.11905503 +0.9625,0.7875,0.08418465,0.1683693 +0.9625,0.7875,0.1683693,0.08418465 +0.9625,0.8125,0.07499999,0.07500005 +0.9625,0.8125,0.053033054,0.10606599 +0.9625,0.8125,0.10606593,0.053033054 +0.9625,0.8125,0.094494045,0.094494104 +0.9625,0.8125,0.06681746,0.1336348 +0.9625,0.8125,0.13363475,0.06681746 +0.9625,0.8125,0.11905497,0.11905503 +0.9625,0.8125,0.08418465,0.1683693 +0.9625,0.8125,0.1683693,0.08418465 +0.9625,0.8375,0.07499999,0.07499999 +0.9625,0.8375,0.053033054,0.10606599 +0.9625,0.8375,0.10606593,0.053033054 +0.9625,0.8375,0.094494045,0.094494045 +0.9625,0.8375,0.06681746,0.1336348 +0.9625,0.8375,0.13363475,0.06681746 +0.9625,0.8375,0.11905497,0.11905503 +0.9625,0.8375,0.08418465,0.1683693 +0.9625,0.8375,0.1683693,0.08418465 +0.9625,0.86249995,0.07499999,0.07499999 +0.9625,0.86249995,0.053033054,0.10606593 +0.9625,0.86249995,0.10606593,0.053033054 +0.9625,0.86249995,0.094494045,0.094494045 +0.9625,0.86249995,0.06681746,0.1336348 +0.9625,0.86249995,0.13363475,0.06681746 +0.9625,0.86249995,0.11905497,0.11905497 +0.9625,0.8625,0.08418465,0.1683693 +0.9625,0.8625,0.1683693,0.08418465 +0.9625,0.88750005,0.07499999,0.07499999 +0.9625,0.88750005,0.053033054,0.10606593 +0.9625,0.88750005,0.10606593,0.053033054 +0.9625,0.88750005,0.094494045,0.094494045 +0.9625,0.88750005,0.06681746,0.13363475 +0.9625,0.88750005,0.13363475,0.06681746 +0.9625,0.88750005,0.11905497,0.11905497 +0.9625,0.8875,0.08418465,0.1683693 +0.9625,0.8875,0.1683693,0.08418465 +0.9625,0.9125,0.07499999,0.07499999 +0.9625,0.9125,0.053033054,0.10606593 +0.9625,0.9125,0.10606593,0.053033054 +0.9625,0.9125,0.094494045,0.094494045 +0.9625,0.9125,0.06681746,0.13363475 +0.9625,0.9125,0.13363475,0.06681746 +0.9625,0.9125,0.11905497,0.11905497 +0.9625,0.9125,0.08418465,0.1683693 +0.9625,0.9125,0.1683693,0.08418465 +0.9625,0.9375,0.07499999,0.07500005 +0.9625,0.9375,0.053033054,0.10606599 +0.9625,0.9375,0.10606593,0.053033113 +0.9625,0.9375,0.094494045,0.094494104 +0.9625,0.9375,0.06681746,0.1336348 +0.9625,0.9375,0.13363475,0.06681752 +0.9625,0.9375,0.11905497,0.11905503 +0.9625,0.9375,0.08418465,0.1683693 +0.9625,0.9375,0.1683693,0.08418465 +0.9625,0.9625,0.07499999,0.07499999 +0.9625,0.9625,0.053033054,0.10606593 +0.9625,0.9625,0.10606593,0.053033054 +0.9625,0.9625,0.094494045,0.094494045 +0.9625,0.9625,0.06681746,0.13363475 +0.9625,0.9625,0.13363475,0.06681746 +0.9625,0.9625,0.11905497,0.11905497 +0.9625,0.9625,0.08418465,0.1683693 +0.9625,0.9625,0.1683693,0.08418465 +0.9625,0.98749995,0.07499999,0.07499999 +0.9625,0.98749995,0.053033054,0.10606593 +0.9625,0.98749995,0.10606593,0.053033054 +0.9625,0.98749995,0.094494045,0.094494045 +0.9625,0.98749995,0.06681746,0.13363475 +0.9625,0.98749995,0.13363475,0.06681746 +0.9625,0.98749995,0.11905497,0.11905497 +0.9625,0.98749995,0.08418465,0.16836923 +0.9625,0.98749995,0.1683693,0.08418459 +0.98749995,0.0125,0.07499999,0.075 +0.98749995,0.012499997,0.053033054,0.10606602 +0.98749995,0.012499999,0.10606593,0.05303301 +0.98749995,0.012499999,0.094494045,0.09449408 +0.98749995,0.012500001,0.06681746,0.1336348 +0.98749995,0.012499999,0.13363475,0.0668174 +0.98749995,0.012500001,0.11905497,0.11905508 +0.98749995,0.012499999,0.08418459,0.1683693 +0.98749995,0.012500002,0.16836923,0.084184654 +0.98749995,0.0375,0.07499999,0.075 +0.98749995,0.037499998,0.053033054,0.10606601 +0.98749995,0.0375,0.10606593,0.05303301 +0.98749995,0.0375,0.094494045,0.094494075 +0.98749995,0.0375,0.06681746,0.1336348 +0.98749995,0.0375,0.13363475,0.0668174 +0.98749995,0.0375,0.11905497,0.11905508 +0.98749995,0.0375,0.08418459,0.16836931 +0.98749995,0.0375,0.16836923,0.08418466 +0.98749995,0.0625,0.07499999,0.075 +0.98749995,0.0625,0.053033054,0.10606602 +0.98749995,0.0625,0.10606593,0.05303301 +0.98749995,0.0625,0.094494045,0.094494075 +0.98749995,0.0625,0.06681746,0.1336348 +0.98749995,0.0625,0.13363475,0.0668174 +0.98749995,0.0625,0.11905497,0.11905508 +0.98749995,0.0625,0.08418459,0.16836932 +0.98749995,0.0625,0.16836923,0.08418465 +0.98749995,0.0875,0.07499999,0.075 +0.98749995,0.08749999,0.053033054,0.10606601 +0.98749995,0.087500006,0.10606593,0.053033013 +0.98749995,0.087500006,0.094494045,0.09449408 +0.98749995,0.087500006,0.06681746,0.1336348 +0.98749995,0.0875,0.13363475,0.0668174 +0.98749995,0.0875,0.11905497,0.11905508 +0.98749995,0.0875,0.08418459,0.16836931 +0.98749995,0.087500006,0.16836923,0.084184654 +0.98749995,0.112500004,0.07499999,0.075 +0.98749995,0.1125,0.053033054,0.10606601 +0.98749995,0.112500004,0.10606593,0.05303301 +0.98749995,0.1125,0.094494045,0.094494075 +0.98749995,0.1125,0.06681746,0.1336348 +0.98749995,0.1125,0.13363475,0.0668174 +0.98749995,0.1125,0.11905497,0.119055085 +0.98749995,0.112500004,0.08418459,0.16836931 +0.98749995,0.1125,0.16836923,0.08418465 +0.98749995,0.1375,0.07499999,0.074999996 +0.98749995,0.1375,0.053033054,0.10606602 +0.98749995,0.1375,0.10606593,0.053033024 +0.98749995,0.1375,0.094494045,0.09449408 +0.98749995,0.1375,0.06681746,0.1336348 +0.98749995,0.1375,0.13363475,0.0668174 +0.98749995,0.13749999,0.11905497,0.11905508 +0.98749995,0.1375,0.08418459,0.1683693 +0.98749995,0.1375,0.16836923,0.084184654 +0.98749995,0.1625,0.07499999,0.075 +0.98749995,0.16250001,0.053033054,0.106066026 +0.98749995,0.1625,0.10606593,0.05303301 +0.98749995,0.1625,0.094494045,0.094494075 +0.98749995,0.1625,0.06681746,0.1336348 +0.98749995,0.1625,0.13363475,0.0668174 +0.98749995,0.1625,0.11905497,0.11905508 +0.98749995,0.1625,0.08418459,0.1683693 +0.98749995,0.1625,0.16836923,0.08418464 +0.98749995,0.1875,0.07499999,0.07499999 +0.98749995,0.1875,0.053033054,0.10606603 +0.98749995,0.1875,0.10606593,0.053033024 +0.98749995,0.1875,0.094494045,0.09449406 +0.98749995,0.1875,0.06681746,0.1336348 +0.98749995,0.1875,0.13363475,0.06681742 +0.98749995,0.1875,0.11905497,0.11905509 +0.98749995,0.1875,0.08418459,0.16836931 +0.98749995,0.1875,0.16836923,0.08418465 +0.98749995,0.2125,0.07499999,0.075 +0.98749995,0.2125,0.053033054,0.10606603 +0.98749995,0.2125,0.10606593,0.05303301 +0.98749995,0.21249999,0.094494045,0.094494075 +0.98749995,0.2125,0.06681746,0.1336348 +0.98749995,0.2125,0.13363475,0.0668174 +0.98749995,0.2125,0.11905497,0.11905509 +0.98749995,0.2125,0.08418459,0.16836931 +0.98749995,0.2125,0.16836923,0.08418465 +0.98749995,0.23750001,0.07499999,0.075 +0.98749995,0.2375,0.053033054,0.10606602 +0.98749995,0.2375,0.10606593,0.053033024 +0.98749995,0.2375,0.094494045,0.094494075 +0.98749995,0.23750001,0.06681746,0.13363482 +0.98749995,0.2375,0.13363475,0.06681743 +0.98749995,0.2375,0.11905497,0.11905506 +0.98749995,0.2375,0.08418459,0.16836932 +0.98749995,0.23750001,0.16836923,0.08418466 +0.98749995,0.2625,0.07499999,0.07500002 +0.98749995,0.2625,0.053033054,0.10606603 +0.98749995,0.2625,0.10606593,0.053033024 +0.98749995,0.2625,0.094494045,0.094494075 +0.98749995,0.2625,0.06681746,0.13363479 +0.98749995,0.2625,0.13363475,0.06681743 +0.98749995,0.2625,0.11905497,0.11905508 +0.98749995,0.2625,0.08418459,0.1683693 +0.98749995,0.2625,0.16836923,0.08418463 +0.98749995,0.2875,0.07499999,0.07499999 +0.98749995,0.2875,0.053033054,0.10606603 +0.98749995,0.28750002,0.10606593,0.053033024 +0.98749995,0.2875,0.094494045,0.094494045 +0.98749995,0.2875,0.06681746,0.1336348 +0.98749995,0.28750002,0.13363475,0.06681743 +0.98749995,0.2875,0.11905497,0.11905508 +0.98749995,0.2875,0.08418459,0.1683693 +0.98749995,0.2875,0.16836923,0.08418465 +0.98749995,0.3125,0.07499999,0.07499999 +0.98749995,0.3125,0.053033054,0.10606605 +0.98749995,0.3125,0.10606593,0.053032994 +0.98749995,0.3125,0.094494045,0.094494045 +0.98749995,0.3125,0.06681746,0.1336348 +0.98749995,0.3125,0.13363475,0.0668174 +0.98749995,0.3125,0.11905497,0.11905509 +0.98749995,0.3125,0.08418459,0.1683693 +0.98749995,0.3125,0.16836923,0.08418465 +0.98749995,0.3375,0.07499999,0.07499999 +0.98749995,0.3375,0.053033054,0.10606605 +0.98749995,0.33749998,0.10606593,0.053033024 +0.98749995,0.3375,0.094494045,0.094494045 +0.98749995,0.33750004,0.06681746,0.13363484 +0.98749995,0.33749998,0.13363475,0.06681743 +0.98749995,0.3375,0.11905497,0.11905509 +0.98749995,0.3375,0.08418459,0.1683693 +0.98749995,0.3375,0.16836923,0.08418465 +0.98749995,0.3625,0.07499999,0.07500002 +0.98749995,0.3625,0.053033054,0.10606602 +0.98749995,0.3625,0.10606593,0.053033024 +0.98749995,0.3625,0.094494045,0.094494075 +0.98749995,0.3625,0.06681746,0.1336348 +0.98749995,0.3625,0.13363475,0.06681743 +0.98749995,0.3625,0.11905497,0.11905506 +0.98749995,0.3625,0.08418459,0.1683693 +0.98749995,0.3625,0.16836923,0.08418465 +0.98749995,0.3875,0.07499999,0.07500002 +0.98749995,0.3875,0.053033054,0.10606602 +0.98749995,0.3875,0.10606593,0.053032994 +0.98749995,0.3875,0.094494045,0.094494075 +0.98749995,0.3875,0.06681746,0.13363484 +0.98749995,0.3875,0.13363475,0.0668174 +0.98749995,0.3875,0.11905497,0.11905506 +0.98749995,0.3875,0.08418459,0.1683693 +0.98749995,0.3875,0.16836923,0.08418465 +0.98749995,0.4125,0.07499999,0.07499999 +0.98749995,0.4125,0.053033054,0.10606605 +0.98749995,0.4125,0.10606593,0.053032994 +0.98749995,0.4125,0.094494045,0.094494045 +0.98749995,0.41250002,0.06681746,0.13363484 +0.98749995,0.4125,0.13363475,0.0668174 +0.98749995,0.4125,0.11905497,0.11905509 +0.98749995,0.4125,0.08418459,0.1683693 +0.98749995,0.4125,0.16836923,0.08418465 +0.98749995,0.4375,0.07499999,0.07499999 +0.98749995,0.4375,0.053033054,0.10606605 +0.98749995,0.4375,0.10606593,0.053032994 +0.98749995,0.4375,0.094494045,0.094494045 +0.98749995,0.4375,0.06681746,0.1336348 +0.98749995,0.4375,0.13363475,0.0668174 +0.98749995,0.4375,0.11905497,0.11905509 +0.98749995,0.4375,0.08418459,0.1683693 +0.98749995,0.4375,0.16836923,0.08418465 +0.98749995,0.4625,0.07499999,0.07499999 +0.98749995,0.4625,0.053033054,0.10606605 +0.98749995,0.46249998,0.10606593,0.053032964 +0.98749995,0.4625,0.094494045,0.094494045 +0.98749995,0.46250004,0.06681746,0.13363484 +0.98749995,0.46249998,0.13363475,0.06681737 +0.98749995,0.4625,0.11905497,0.11905509 +0.98749995,0.46249998,0.08418459,0.16836926 +0.98749995,0.46249998,0.16836923,0.08418462 +0.98749995,0.48749998,0.07499999,0.07499999 +0.98749995,0.4875,0.053033054,0.10606602 +0.98749995,0.4875,0.10606593,0.053032994 +0.98749995,0.48749998,0.094494045,0.094494045 +0.98749995,0.4875,0.06681746,0.13363484 +0.98749995,0.4875,0.13363475,0.0668174 +0.98749995,0.4875,0.11905497,0.11905506 +0.98749995,0.4875,0.08418459,0.1683693 +0.98749995,0.4875,0.16836923,0.08418465 +0.98749995,0.5125,0.07499999,0.07500002 +0.98749995,0.51250005,0.053033054,0.10606605 +0.98749995,0.5125,0.10606593,0.053032964 +0.98749995,0.5125,0.094494045,0.094494075 +0.98749995,0.51250005,0.06681746,0.13363487 +0.98749995,0.5125,0.13363475,0.06681737 +0.98749995,0.51250005,0.11905497,0.11905509 +0.98749995,0.5125,0.08418459,0.1683693 +0.98749995,0.5125,0.16836923,0.08418465 +0.98749995,0.5375,0.07499999,0.07499999 +0.98749995,0.5375,0.053033054,0.10606605 +0.98749995,0.5375,0.10606593,0.053032935 +0.98749995,0.5375,0.094494045,0.094494045 +0.98749995,0.5375,0.06681746,0.13363487 +0.98749995,0.5375,0.13363475,0.06681734 +0.98749995,0.5375,0.11905497,0.11905509 +0.98749995,0.5375,0.08418459,0.16836932 +0.98749995,0.5375,0.16836923,0.08418468 +0.98749995,0.5625,0.07499999,0.07500005 +0.98749995,0.5625,0.053033054,0.10606599 +0.98749995,0.5625,0.10606593,0.053032994 +0.98749995,0.5625,0.094494045,0.094494104 +0.98749995,0.5625,0.06681746,0.13363484 +0.98749995,0.5625,0.13363475,0.0668174 +0.98749995,0.5625,0.11905497,0.11905503 +0.98749995,0.5625,0.08418459,0.1683693 +0.98749995,0.5625,0.16836923,0.08418465 +0.98749995,0.5875,0.07499999,0.07499999 +0.98749995,0.5875,0.053033054,0.10606605 +0.98749995,0.5875,0.10606593,0.053032935 +0.98749995,0.5875,0.094494045,0.094494045 +0.98749995,0.5875,0.06681746,0.13363487 +0.98749995,0.5875,0.13363475,0.06681734 +0.98749995,0.5875,0.11905497,0.11905509 +0.98749995,0.5875,0.08418459,0.1683693 +0.98749995,0.5875,0.16836923,0.08418465 +0.98749995,0.61249995,0.07499999,0.07499999 +0.98749995,0.61249995,0.053033054,0.10606605 +0.98749995,0.6125,0.10606593,0.053032994 +0.98749995,0.61249995,0.094494045,0.094494045 +0.98749995,0.61249995,0.06681746,0.13363487 +0.98749995,0.6125,0.13363475,0.0668174 +0.98749995,0.61249995,0.11905497,0.11905509 +0.98749995,0.6125,0.08418459,0.1683693 +0.98749995,0.6125,0.16836923,0.08418465 +0.98749995,0.63750005,0.07499999,0.07499999 +0.98749995,0.63750005,0.053033054,0.10606605 +0.98749995,0.6375,0.10606593,0.053032994 +0.98749995,0.63750005,0.094494045,0.094494045 +0.98749995,0.63750005,0.06681746,0.13363487 +0.98749995,0.6375,0.13363475,0.0668174 +0.98749995,0.63750005,0.11905497,0.11905509 +0.98749995,0.6375,0.08418459,0.1683693 +0.98749995,0.6375,0.16836923,0.08418465 +0.98749995,0.6625,0.07499999,0.07499999 +0.98749995,0.6625,0.053033054,0.10606605 +0.98749995,0.6625,0.10606593,0.053032935 +0.98749995,0.6625,0.094494045,0.094494045 +0.98749995,0.6625,0.06681746,0.13363487 +0.98749995,0.6625,0.13363475,0.06681734 +0.98749995,0.6625,0.11905497,0.11905509 +0.98749995,0.6625,0.08418459,0.1683693 +0.98749995,0.6625,0.16836923,0.08418465 +0.98749995,0.6875,0.07499999,0.07500005 +0.98749995,0.6875,0.053033054,0.10606599 +0.98749995,0.6875,0.10606593,0.053032994 +0.98749995,0.6875,0.094494045,0.094494104 +0.98749995,0.6875,0.06681746,0.1336348 +0.98749995,0.6875,0.13363475,0.0668174 +0.98749995,0.6875,0.11905497,0.11905503 +0.98749995,0.6875,0.08418459,0.1683693 +0.98749995,0.6875,0.16836923,0.08418465 +0.98749995,0.7125,0.07499999,0.07499999 +0.98749995,0.7125,0.053033054,0.10606605 +0.98749995,0.7125,0.10606593,0.053032935 +0.98749995,0.7125,0.094494045,0.094494045 +0.98749995,0.7125,0.06681746,0.13363487 +0.98749995,0.7125,0.13363475,0.06681734 +0.98749995,0.7125,0.11905497,0.11905509 +0.98749995,0.7125,0.08418459,0.1683693 +0.98749995,0.7125,0.16836923,0.08418465 +0.98749995,0.73749995,0.07499999,0.07499999 +0.98749995,0.73749995,0.053033054,0.10606605 +0.98749995,0.7375,0.10606593,0.053032994 +0.98749995,0.73749995,0.094494045,0.094494045 +0.98749995,0.73749995,0.06681746,0.1336348 +0.98749995,0.7375,0.13363475,0.0668174 +0.98749995,0.73749995,0.11905497,0.11905509 +0.98749995,0.7375,0.08418459,0.1683693 +0.98749995,0.7375,0.16836923,0.08418465 +0.98749995,0.76250005,0.07499999,0.07499999 +0.98749995,0.7625,0.053033054,0.10606599 +0.98749995,0.7625,0.10606593,0.053032994 +0.98749995,0.76250005,0.094494045,0.094494045 +0.98749995,0.7625,0.06681746,0.1336348 +0.98749995,0.7625,0.13363475,0.0668174 +0.98749995,0.7625,0.11905497,0.11905503 +0.98749995,0.7625,0.08418459,0.1683693 +0.98749995,0.7625,0.16836923,0.08418465 +0.98749995,0.7875,0.07499999,0.07499999 +0.98749995,0.78749996,0.053033054,0.10606599 +0.98749995,0.7875,0.10606593,0.053032994 +0.98749995,0.7875,0.094494045,0.094494045 +0.98749995,0.78749996,0.06681746,0.1336348 +0.98749995,0.7875,0.13363475,0.0668174 +0.98749995,0.78749996,0.11905497,0.11905503 +0.98749995,0.7875,0.08418459,0.1683693 +0.98749995,0.7875,0.16836923,0.08418465 +0.98749995,0.8125,0.07499999,0.07500005 +0.98749995,0.8125,0.053033054,0.10606599 +0.98749995,0.8125,0.10606593,0.053033054 +0.98749995,0.8125,0.094494045,0.094494104 +0.98749995,0.8125,0.06681746,0.1336348 +0.98749995,0.8125,0.13363475,0.06681746 +0.98749995,0.8125,0.11905497,0.11905503 +0.98749995,0.8125,0.08418459,0.1683693 +0.98749995,0.8125,0.16836923,0.08418465 +0.98749995,0.8375,0.07499999,0.07499999 +0.98749995,0.8375,0.053033054,0.10606599 +0.98749995,0.8375,0.10606593,0.053033054 +0.98749995,0.8375,0.094494045,0.094494045 +0.98749995,0.8375,0.06681746,0.1336348 +0.98749995,0.8375,0.13363475,0.06681746 +0.98749995,0.8375,0.11905497,0.11905503 +0.98749995,0.8375,0.08418459,0.1683693 +0.98749995,0.8375,0.16836923,0.08418465 +0.98749995,0.86249995,0.07499999,0.07499999 +0.98749995,0.86249995,0.053033054,0.10606593 +0.98749995,0.86249995,0.10606593,0.053033054 +0.98749995,0.86249995,0.094494045,0.094494045 +0.98749995,0.86249995,0.06681746,0.1336348 +0.98749995,0.86249995,0.13363475,0.06681746 +0.98749995,0.86249995,0.11905497,0.11905497 +0.98749995,0.8625,0.08418459,0.1683693 +0.98749995,0.8625,0.16836923,0.08418465 +0.98749995,0.88750005,0.07499999,0.07499999 +0.98749995,0.88750005,0.053033054,0.10606593 +0.98749995,0.88750005,0.10606593,0.053033054 +0.98749995,0.88750005,0.094494045,0.094494045 +0.98749995,0.88750005,0.06681746,0.13363475 +0.98749995,0.88750005,0.13363475,0.06681746 +0.98749995,0.88750005,0.11905497,0.11905497 +0.98749995,0.8875,0.08418459,0.1683693 +0.98749995,0.8875,0.16836923,0.08418465 +0.98749995,0.9125,0.07499999,0.07499999 +0.98749995,0.9125,0.053033054,0.10606593 +0.98749995,0.9125,0.10606593,0.053033054 +0.98749995,0.9125,0.094494045,0.094494045 +0.98749995,0.9125,0.06681746,0.13363475 +0.98749995,0.9125,0.13363475,0.06681746 +0.98749995,0.9125,0.11905497,0.11905497 +0.98749995,0.9125,0.08418459,0.1683693 +0.98749995,0.9125,0.16836923,0.08418465 +0.98749995,0.9375,0.07499999,0.07500005 +0.98749995,0.9375,0.053033054,0.10606599 +0.98749995,0.9375,0.10606593,0.053033113 +0.98749995,0.9375,0.094494045,0.094494104 +0.98749995,0.9375,0.06681746,0.1336348 +0.98749995,0.9375,0.13363475,0.06681752 +0.98749995,0.9375,0.11905497,0.11905503 +0.98749995,0.9375,0.08418459,0.1683693 +0.98749995,0.9375,0.16836923,0.08418465 +0.98749995,0.9625,0.07499999,0.07499999 +0.98749995,0.9625,0.053033054,0.10606593 +0.98749995,0.9625,0.10606593,0.053033054 +0.98749995,0.9625,0.094494045,0.094494045 +0.98749995,0.9625,0.06681746,0.13363475 +0.98749995,0.9625,0.13363475,0.06681746 +0.98749995,0.9625,0.11905497,0.11905497 +0.98749995,0.9625,0.08418459,0.1683693 +0.98749995,0.9625,0.16836923,0.08418465 +0.98749995,0.98749995,0.07499999,0.07499999 +0.98749995,0.98749995,0.053033054,0.10606593 +0.98749995,0.98749995,0.10606593,0.053033054 +0.98749995,0.98749995,0.094494045,0.094494045 +0.98749995,0.98749995,0.06681746,0.13363475 +0.98749995,0.98749995,0.13363475,0.06681746 +0.98749995,0.98749995,0.11905497,0.11905497 +0.98749995,0.98749995,0.08418459,0.16836923 +0.98749995,0.98749995,0.16836923,0.08418459 +0.025,0.025,0.15,0.15 +0.024999999,0.024999995,0.10606602,0.21213204 +0.024999995,0.024999999,0.21213204,0.10606602 +0.024999999,0.024999999,0.18898816,0.18898816 +0.024999999,0.025000002,0.1336348,0.2672696 +0.025000002,0.024999999,0.2672696,0.1336348 +0.025000002,0.025000002,0.23811015,0.23811015 +0.025000004,0.024999999,0.16836931,0.3367386 +0.024999999,0.025000004,0.3367386,0.16836931 +0.025,0.075,0.15,0.15 +0.024999999,0.074999996,0.10606602,0.21213202 +0.024999995,0.075,0.21213204,0.10606602 +0.024999999,0.075,0.18898816,0.18898815 +0.024999999,0.075,0.1336348,0.2672696 +0.025000002,0.075,0.2672696,0.1336348 +0.025000002,0.075,0.23811015,0.23811015 +0.025000004,0.075,0.16836931,0.33673862 +0.024999999,0.075,0.3367386,0.16836932 +0.025,0.125,0.15,0.15 +0.024999999,0.125,0.10606602,0.21213204 +0.024999995,0.125,0.21213204,0.10606602 +0.024999999,0.125,0.18898816,0.18898815 +0.024999999,0.125,0.1336348,0.2672696 +0.025000002,0.125,0.2672696,0.1336348 +0.025000002,0.125,0.23811015,0.23811015 +0.025000004,0.125,0.16836931,0.33673865 +0.024999999,0.125,0.3367386,0.1683693 +0.025,0.175,0.15,0.15 +0.024999999,0.17499998,0.10606602,0.21213202 +0.024999995,0.17500001,0.21213204,0.106066026 +0.024999999,0.17500001,0.18898816,0.18898816 +0.024999999,0.17500001,0.1336348,0.2672696 +0.025000002,0.175,0.2672696,0.1336348 +0.025000002,0.175,0.23811015,0.23811015 +0.025000004,0.175,0.16836931,0.33673862 +0.024999999,0.17500001,0.3367386,0.16836931 +0.025,0.22500001,0.15,0.15 +0.024999999,0.225,0.10606602,0.21213202 +0.024999995,0.22500001,0.21213204,0.10606602 +0.024999999,0.225,0.18898816,0.18898815 +0.024999999,0.225,0.1336348,0.2672696 +0.025000002,0.225,0.2672696,0.1336348 +0.025000002,0.225,0.23811015,0.23811017 +0.025000004,0.22500001,0.16836931,0.33673862 +0.024999999,0.225,0.3367386,0.1683693 +0.025,0.275,0.15,0.14999999 +0.024999999,0.275,0.10606602,0.21213204 +0.024999995,0.275,0.21213204,0.10606605 +0.024999999,0.275,0.18898816,0.18898816 +0.024999999,0.275,0.1336348,0.2672696 +0.025000002,0.275,0.2672696,0.1336348 +0.025000002,0.27499998,0.23811015,0.23811015 +0.025000004,0.275,0.16836931,0.3367386 +0.024999999,0.275,0.3367386,0.16836931 +0.025,0.325,0.15,0.15 +0.024999999,0.32500002,0.10606602,0.21213205 +0.024999995,0.325,0.21213204,0.10606602 +0.024999999,0.325,0.18898816,0.18898815 +0.024999999,0.325,0.1336348,0.2672696 +0.025000002,0.325,0.2672696,0.1336348 +0.025000002,0.325,0.23811015,0.23811015 +0.025000004,0.325,0.16836931,0.3367386 +0.024999999,0.325,0.3367386,0.16836928 +0.025,0.375,0.15,0.14999998 +0.024999999,0.375,0.10606602,0.21213207 +0.024999995,0.375,0.21213204,0.10606605 +0.024999999,0.375,0.18898816,0.18898812 +0.024999999,0.375,0.1336348,0.2672696 +0.025000002,0.375,0.2672696,0.13363484 +0.025000002,0.375,0.23811015,0.23811018 +0.025000004,0.375,0.16836931,0.33673862 +0.024999999,0.375,0.3367386,0.1683693 +0.025,0.425,0.15,0.15 +0.024999999,0.425,0.10606602,0.21213207 +0.024999995,0.425,0.21213204,0.10606602 +0.024999999,0.42499998,0.18898816,0.18898815 +0.024999999,0.425,0.1336348,0.2672696 +0.025000002,0.425,0.2672696,0.1336348 +0.025000002,0.425,0.23811015,0.23811018 +0.025000004,0.425,0.16836931,0.33673862 +0.024999999,0.425,0.3367386,0.1683693 +0.025,0.47500002,0.15,0.15 +0.024999999,0.475,0.10606602,0.21213204 +0.024999995,0.475,0.21213204,0.10606605 +0.024999999,0.475,0.18898816,0.18898815 +0.024999999,0.47500002,0.1336348,0.26726964 +0.025000002,0.475,0.2672696,0.13363487 +0.025000002,0.475,0.23811015,0.23811013 +0.025000004,0.475,0.16836931,0.33673865 +0.024999999,0.47500002,0.3367386,0.16836932 +0.025,0.525,0.15,0.15000004 +0.024999999,0.525,0.10606602,0.21213207 +0.024999995,0.525,0.21213204,0.10606605 +0.024999999,0.525,0.18898816,0.18898815 +0.024999999,0.525,0.1336348,0.26726958 +0.025000002,0.525,0.2672696,0.13363487 +0.025000002,0.525,0.23811015,0.23811015 +0.025000004,0.525,0.16836931,0.3367386 +0.024999999,0.525,0.3367386,0.16836926 +0.025,0.575,0.15,0.14999998 +0.024999999,0.575,0.10606602,0.21213207 +0.024999995,0.57500005,0.21213204,0.10606605 +0.024999999,0.575,0.18898816,0.18898809 +0.024999999,0.575,0.1336348,0.2672696 +0.025000002,0.57500005,0.2672696,0.13363487 +0.025000002,0.575,0.23811015,0.23811015 +0.025000004,0.575,0.16836931,0.3367386 +0.024999999,0.575,0.3367386,0.1683693 +0.025,0.625,0.15,0.14999998 +0.024999999,0.625,0.10606602,0.2121321 +0.024999995,0.625,0.21213204,0.10606599 +0.024999999,0.625,0.18898816,0.18898809 +0.024999999,0.625,0.1336348,0.2672696 +0.025000002,0.625,0.2672696,0.1336348 +0.025000002,0.625,0.23811015,0.23811018 +0.025000004,0.625,0.16836931,0.3367386 +0.024999999,0.625,0.3367386,0.1683693 +0.025,0.675,0.15,0.14999998 +0.024999999,0.675,0.10606602,0.2121321 +0.024999995,0.67499995,0.21213204,0.10606605 +0.024999999,0.675,0.18898816,0.18898809 +0.024999999,0.6750001,0.1336348,0.26726967 +0.025000002,0.67499995,0.2672696,0.13363487 +0.025000002,0.675,0.23811015,0.23811018 +0.025000004,0.675,0.16836931,0.3367386 +0.024999999,0.675,0.3367386,0.1683693 +0.025,0.725,0.15,0.15000004 +0.024999999,0.725,0.10606602,0.21213204 +0.024999995,0.725,0.21213204,0.10606605 +0.024999999,0.725,0.18898816,0.18898815 +0.024999999,0.725,0.1336348,0.2672696 +0.025000002,0.725,0.2672696,0.13363487 +0.025000002,0.725,0.23811015,0.23811013 +0.025000004,0.725,0.16836931,0.3367386 +0.024999999,0.725,0.3367386,0.1683693 +0.025,0.775,0.15,0.15000004 +0.024999999,0.775,0.10606602,0.21213204 +0.024999995,0.775,0.21213204,0.10606599 +0.024999999,0.775,0.18898816,0.18898815 +0.024999999,0.775,0.1336348,0.26726967 +0.025000002,0.775,0.2672696,0.1336348 +0.025000002,0.775,0.23811015,0.23811013 +0.025000004,0.775,0.16836931,0.3367386 +0.024999999,0.775,0.3367386,0.1683693 +0.025,0.825,0.15,0.14999998 +0.024999999,0.825,0.10606602,0.2121321 +0.024999995,0.825,0.21213204,0.10606599 +0.024999999,0.825,0.18898816,0.18898809 +0.024999999,0.82500005,0.1336348,0.26726967 +0.025000002,0.825,0.2672696,0.1336348 +0.025000002,0.825,0.23811015,0.23811018 +0.025000004,0.825,0.16836931,0.3367386 +0.024999999,0.825,0.3367386,0.1683693 +0.025,0.875,0.15,0.14999998 +0.024999999,0.875,0.10606602,0.2121321 +0.024999995,0.875,0.21213204,0.10606599 +0.024999999,0.875,0.18898816,0.18898809 +0.024999999,0.875,0.1336348,0.2672696 +0.025000002,0.875,0.2672696,0.1336348 +0.025000002,0.875,0.23811015,0.23811018 +0.025000004,0.875,0.16836931,0.3367386 +0.024999999,0.875,0.3367386,0.1683693 +0.025,0.925,0.15,0.14999998 +0.024999999,0.925,0.10606602,0.2121321 +0.024999995,0.92499995,0.21213204,0.10606593 +0.024999999,0.925,0.18898816,0.18898809 +0.024999999,0.9250001,0.1336348,0.26726967 +0.025000002,0.92499995,0.2672696,0.13363475 +0.025000002,0.925,0.23811015,0.23811018 +0.025000004,0.92499995,0.16836931,0.33673853 +0.024999999,0.92499995,0.3367386,0.16836923 +0.025,0.97499996,0.15,0.14999998 +0.024999999,0.975,0.10606602,0.21213204 +0.024999995,0.975,0.21213204,0.10606599 +0.024999999,0.97499996,0.18898816,0.18898809 +0.024999999,0.975,0.1336348,0.26726967 +0.025000002,0.975,0.2672696,0.1336348 +0.025000002,0.975,0.23811015,0.23811013 +0.025000004,0.975,0.16836931,0.3367386 +0.024999999,0.975,0.3367386,0.1683693 +0.075,0.025,0.15,0.15 +0.075,0.024999995,0.10606602,0.21213204 +0.074999996,0.024999999,0.21213202,0.10606602 +0.075,0.024999999,0.18898815,0.18898816 +0.075,0.025000002,0.1336348,0.2672696 +0.075,0.024999999,0.2672696,0.1336348 +0.075,0.025000002,0.23811015,0.23811015 +0.075,0.024999999,0.16836932,0.3367386 +0.075,0.025000004,0.33673862,0.16836931 +0.075,0.075,0.15,0.15 +0.075,0.074999996,0.10606602,0.21213202 +0.074999996,0.075,0.21213202,0.10606602 +0.075,0.075,0.18898815,0.18898815 +0.075,0.075,0.1336348,0.2672696 +0.075,0.075,0.2672696,0.1336348 +0.075,0.075,0.23811015,0.23811015 +0.075,0.075,0.16836932,0.33673862 +0.075,0.075,0.33673862,0.16836932 +0.075,0.125,0.15,0.15 +0.075,0.125,0.10606602,0.21213204 +0.074999996,0.125,0.21213202,0.10606602 +0.075,0.125,0.18898815,0.18898815 +0.075,0.125,0.1336348,0.2672696 +0.075,0.125,0.2672696,0.1336348 +0.075,0.125,0.23811015,0.23811015 +0.075,0.125,0.16836932,0.33673865 +0.075,0.125,0.33673862,0.1683693 +0.075,0.175,0.15,0.15 +0.075,0.17499998,0.10606602,0.21213202 +0.074999996,0.17500001,0.21213202,0.106066026 +0.075,0.17500001,0.18898815,0.18898816 +0.075,0.17500001,0.1336348,0.2672696 +0.075,0.175,0.2672696,0.1336348 +0.075,0.175,0.23811015,0.23811015 +0.075,0.175,0.16836932,0.33673862 +0.075,0.17500001,0.33673862,0.16836931 +0.075,0.22500001,0.15,0.15 +0.075,0.225,0.10606602,0.21213202 +0.074999996,0.22500001,0.21213202,0.10606602 +0.075,0.225,0.18898815,0.18898815 +0.075,0.225,0.1336348,0.2672696 +0.075,0.225,0.2672696,0.1336348 +0.075,0.225,0.23811015,0.23811017 +0.075,0.22500001,0.16836932,0.33673862 +0.075,0.225,0.33673862,0.1683693 +0.075,0.275,0.15,0.14999999 +0.075,0.275,0.10606602,0.21213204 +0.074999996,0.275,0.21213202,0.10606605 +0.075,0.275,0.18898815,0.18898816 +0.075,0.275,0.1336348,0.2672696 +0.075,0.275,0.2672696,0.1336348 +0.075,0.27499998,0.23811015,0.23811015 +0.075,0.275,0.16836932,0.3367386 +0.075,0.275,0.33673862,0.16836931 +0.075,0.325,0.15,0.15 +0.075,0.32500002,0.10606602,0.21213205 +0.074999996,0.325,0.21213202,0.10606602 +0.075,0.325,0.18898815,0.18898815 +0.075,0.325,0.1336348,0.2672696 +0.075,0.325,0.2672696,0.1336348 +0.075,0.325,0.23811015,0.23811015 +0.075,0.325,0.16836932,0.3367386 +0.075,0.325,0.33673862,0.16836928 +0.075,0.375,0.15,0.14999998 +0.075,0.375,0.10606602,0.21213207 +0.074999996,0.375,0.21213202,0.10606605 +0.075,0.375,0.18898815,0.18898812 +0.075,0.375,0.1336348,0.2672696 +0.075,0.375,0.2672696,0.13363484 +0.075,0.375,0.23811015,0.23811018 +0.075,0.375,0.16836932,0.33673862 +0.075,0.375,0.33673862,0.1683693 +0.075,0.425,0.15,0.15 +0.075,0.425,0.10606602,0.21213207 +0.074999996,0.425,0.21213202,0.10606602 +0.075,0.42499998,0.18898815,0.18898815 +0.075,0.425,0.1336348,0.2672696 +0.075,0.425,0.2672696,0.1336348 +0.075,0.425,0.23811015,0.23811018 +0.075,0.425,0.16836932,0.33673862 +0.075,0.425,0.33673862,0.1683693 +0.075,0.47500002,0.15,0.15 +0.075,0.475,0.10606602,0.21213204 +0.074999996,0.475,0.21213202,0.10606605 +0.075,0.475,0.18898815,0.18898815 +0.075,0.47500002,0.1336348,0.26726964 +0.075,0.475,0.2672696,0.13363487 +0.075,0.475,0.23811015,0.23811013 +0.075,0.475,0.16836932,0.33673865 +0.075,0.47500002,0.33673862,0.16836932 +0.075,0.525,0.15,0.15000004 +0.075,0.525,0.10606602,0.21213207 +0.074999996,0.525,0.21213202,0.10606605 +0.075,0.525,0.18898815,0.18898815 +0.075,0.525,0.1336348,0.26726958 +0.075,0.525,0.2672696,0.13363487 +0.075,0.525,0.23811015,0.23811015 +0.075,0.525,0.16836932,0.3367386 +0.075,0.525,0.33673862,0.16836926 +0.075,0.575,0.15,0.14999998 +0.075,0.575,0.10606602,0.21213207 +0.074999996,0.57500005,0.21213202,0.10606605 +0.075,0.575,0.18898815,0.18898809 +0.075,0.575,0.1336348,0.2672696 +0.075,0.57500005,0.2672696,0.13363487 +0.075,0.575,0.23811015,0.23811015 +0.075,0.575,0.16836932,0.3367386 +0.075,0.575,0.33673862,0.1683693 +0.075,0.625,0.15,0.14999998 +0.075,0.625,0.10606602,0.2121321 +0.074999996,0.625,0.21213202,0.10606599 +0.075,0.625,0.18898815,0.18898809 +0.075,0.625,0.1336348,0.2672696 +0.075,0.625,0.2672696,0.1336348 +0.075,0.625,0.23811015,0.23811018 +0.075,0.625,0.16836932,0.3367386 +0.075,0.625,0.33673862,0.1683693 +0.075,0.675,0.15,0.14999998 +0.075,0.675,0.10606602,0.2121321 +0.074999996,0.67499995,0.21213202,0.10606605 +0.075,0.675,0.18898815,0.18898809 +0.075,0.6750001,0.1336348,0.26726967 +0.075,0.67499995,0.2672696,0.13363487 +0.075,0.675,0.23811015,0.23811018 +0.075,0.675,0.16836932,0.3367386 +0.075,0.675,0.33673862,0.1683693 +0.075,0.725,0.15,0.15000004 +0.075,0.725,0.10606602,0.21213204 +0.074999996,0.725,0.21213202,0.10606605 +0.075,0.725,0.18898815,0.18898815 +0.075,0.725,0.1336348,0.2672696 +0.075,0.725,0.2672696,0.13363487 +0.075,0.725,0.23811015,0.23811013 +0.075,0.725,0.16836932,0.3367386 +0.075,0.725,0.33673862,0.1683693 +0.075,0.775,0.15,0.15000004 +0.075,0.775,0.10606602,0.21213204 +0.074999996,0.775,0.21213202,0.10606599 +0.075,0.775,0.18898815,0.18898815 +0.075,0.775,0.1336348,0.26726967 +0.075,0.775,0.2672696,0.1336348 +0.075,0.775,0.23811015,0.23811013 +0.075,0.775,0.16836932,0.3367386 +0.075,0.775,0.33673862,0.1683693 +0.075,0.825,0.15,0.14999998 +0.075,0.825,0.10606602,0.2121321 +0.074999996,0.825,0.21213202,0.10606599 +0.075,0.825,0.18898815,0.18898809 +0.075,0.82500005,0.1336348,0.26726967 +0.075,0.825,0.2672696,0.1336348 +0.075,0.825,0.23811015,0.23811018 +0.075,0.825,0.16836932,0.3367386 +0.075,0.825,0.33673862,0.1683693 +0.075,0.875,0.15,0.14999998 +0.075,0.875,0.10606602,0.2121321 +0.074999996,0.875,0.21213202,0.10606599 +0.075,0.875,0.18898815,0.18898809 +0.075,0.875,0.1336348,0.2672696 +0.075,0.875,0.2672696,0.1336348 +0.075,0.875,0.23811015,0.23811018 +0.075,0.875,0.16836932,0.3367386 +0.075,0.875,0.33673862,0.1683693 +0.075,0.925,0.15,0.14999998 +0.075,0.925,0.10606602,0.2121321 +0.074999996,0.92499995,0.21213202,0.10606593 +0.075,0.925,0.18898815,0.18898809 +0.075,0.9250001,0.1336348,0.26726967 +0.075,0.92499995,0.2672696,0.13363475 +0.075,0.925,0.23811015,0.23811018 +0.075,0.92499995,0.16836932,0.33673853 +0.075,0.92499995,0.33673862,0.16836923 +0.075,0.97499996,0.15,0.14999998 +0.075,0.975,0.10606602,0.21213204 +0.074999996,0.975,0.21213202,0.10606599 +0.075,0.97499996,0.18898815,0.18898809 +0.075,0.975,0.1336348,0.26726967 +0.075,0.975,0.2672696,0.1336348 +0.075,0.975,0.23811015,0.23811013 +0.075,0.975,0.16836932,0.3367386 +0.075,0.975,0.33673862,0.1683693 +0.125,0.025,0.15,0.15 +0.125,0.024999995,0.10606602,0.21213204 +0.125,0.024999999,0.21213204,0.10606602 +0.125,0.024999999,0.18898815,0.18898816 +0.125,0.025000002,0.1336348,0.2672696 +0.125,0.024999999,0.2672696,0.1336348 +0.125,0.025000002,0.23811015,0.23811015 +0.125,0.024999999,0.1683693,0.3367386 +0.125,0.025000004,0.33673865,0.16836931 +0.125,0.075,0.15,0.15 +0.125,0.074999996,0.10606602,0.21213202 +0.125,0.075,0.21213204,0.10606602 +0.125,0.075,0.18898815,0.18898815 +0.125,0.075,0.1336348,0.2672696 +0.125,0.075,0.2672696,0.1336348 +0.125,0.075,0.23811015,0.23811015 +0.125,0.075,0.1683693,0.33673862 +0.125,0.075,0.33673865,0.16836932 +0.125,0.125,0.15,0.15 +0.125,0.125,0.10606602,0.21213204 +0.125,0.125,0.21213204,0.10606602 +0.125,0.125,0.18898815,0.18898815 +0.125,0.125,0.1336348,0.2672696 +0.125,0.125,0.2672696,0.1336348 +0.125,0.125,0.23811015,0.23811015 +0.125,0.125,0.1683693,0.33673865 +0.125,0.125,0.33673865,0.1683693 +0.125,0.175,0.15,0.15 +0.125,0.17499998,0.10606602,0.21213202 +0.125,0.17500001,0.21213204,0.106066026 +0.125,0.17500001,0.18898815,0.18898816 +0.125,0.17500001,0.1336348,0.2672696 +0.125,0.175,0.2672696,0.1336348 +0.125,0.175,0.23811015,0.23811015 +0.125,0.175,0.1683693,0.33673862 +0.125,0.17500001,0.33673865,0.16836931 +0.125,0.22500001,0.15,0.15 +0.125,0.225,0.10606602,0.21213202 +0.125,0.22500001,0.21213204,0.10606602 +0.125,0.225,0.18898815,0.18898815 +0.125,0.225,0.1336348,0.2672696 +0.125,0.225,0.2672696,0.1336348 +0.125,0.225,0.23811015,0.23811017 +0.125,0.22500001,0.1683693,0.33673862 +0.125,0.225,0.33673865,0.1683693 +0.125,0.275,0.15,0.14999999 +0.125,0.275,0.10606602,0.21213204 +0.125,0.275,0.21213204,0.10606605 +0.125,0.275,0.18898815,0.18898816 +0.125,0.275,0.1336348,0.2672696 +0.125,0.275,0.2672696,0.1336348 +0.125,0.27499998,0.23811015,0.23811015 +0.125,0.275,0.1683693,0.3367386 +0.125,0.275,0.33673865,0.16836931 +0.125,0.325,0.15,0.15 +0.125,0.32500002,0.10606602,0.21213205 +0.125,0.325,0.21213204,0.10606602 +0.125,0.325,0.18898815,0.18898815 +0.125,0.325,0.1336348,0.2672696 +0.125,0.325,0.2672696,0.1336348 +0.125,0.325,0.23811015,0.23811015 +0.125,0.325,0.1683693,0.3367386 +0.125,0.325,0.33673865,0.16836928 +0.125,0.375,0.15,0.14999998 +0.125,0.375,0.10606602,0.21213207 +0.125,0.375,0.21213204,0.10606605 +0.125,0.375,0.18898815,0.18898812 +0.125,0.375,0.1336348,0.2672696 +0.125,0.375,0.2672696,0.13363484 +0.125,0.375,0.23811015,0.23811018 +0.125,0.375,0.1683693,0.33673862 +0.125,0.375,0.33673865,0.1683693 +0.125,0.425,0.15,0.15 +0.125,0.425,0.10606602,0.21213207 +0.125,0.425,0.21213204,0.10606602 +0.125,0.42499998,0.18898815,0.18898815 +0.125,0.425,0.1336348,0.2672696 +0.125,0.425,0.2672696,0.1336348 +0.125,0.425,0.23811015,0.23811018 +0.125,0.425,0.1683693,0.33673862 +0.125,0.425,0.33673865,0.1683693 +0.125,0.47500002,0.15,0.15 +0.125,0.475,0.10606602,0.21213204 +0.125,0.475,0.21213204,0.10606605 +0.125,0.475,0.18898815,0.18898815 +0.125,0.47500002,0.1336348,0.26726964 +0.125,0.475,0.2672696,0.13363487 +0.125,0.475,0.23811015,0.23811013 +0.125,0.475,0.1683693,0.33673865 +0.125,0.47500002,0.33673865,0.16836932 +0.125,0.525,0.15,0.15000004 +0.125,0.525,0.10606602,0.21213207 +0.125,0.525,0.21213204,0.10606605 +0.125,0.525,0.18898815,0.18898815 +0.125,0.525,0.1336348,0.26726958 +0.125,0.525,0.2672696,0.13363487 +0.125,0.525,0.23811015,0.23811015 +0.125,0.525,0.1683693,0.3367386 +0.125,0.525,0.33673865,0.16836926 +0.125,0.575,0.15,0.14999998 +0.125,0.575,0.10606602,0.21213207 +0.125,0.57500005,0.21213204,0.10606605 +0.125,0.575,0.18898815,0.18898809 +0.125,0.575,0.1336348,0.2672696 +0.125,0.57500005,0.2672696,0.13363487 +0.125,0.575,0.23811015,0.23811015 +0.125,0.575,0.1683693,0.3367386 +0.125,0.575,0.33673865,0.1683693 +0.125,0.625,0.15,0.14999998 +0.125,0.625,0.10606602,0.2121321 +0.125,0.625,0.21213204,0.10606599 +0.125,0.625,0.18898815,0.18898809 +0.125,0.625,0.1336348,0.2672696 +0.125,0.625,0.2672696,0.1336348 +0.125,0.625,0.23811015,0.23811018 +0.125,0.625,0.1683693,0.3367386 +0.125,0.625,0.33673865,0.1683693 +0.125,0.675,0.15,0.14999998 +0.125,0.675,0.10606602,0.2121321 +0.125,0.67499995,0.21213204,0.10606605 +0.125,0.675,0.18898815,0.18898809 +0.125,0.6750001,0.1336348,0.26726967 +0.125,0.67499995,0.2672696,0.13363487 +0.125,0.675,0.23811015,0.23811018 +0.125,0.675,0.1683693,0.3367386 +0.125,0.675,0.33673865,0.1683693 +0.125,0.725,0.15,0.15000004 +0.125,0.725,0.10606602,0.21213204 +0.125,0.725,0.21213204,0.10606605 +0.125,0.725,0.18898815,0.18898815 +0.125,0.725,0.1336348,0.2672696 +0.125,0.725,0.2672696,0.13363487 +0.125,0.725,0.23811015,0.23811013 +0.125,0.725,0.1683693,0.3367386 +0.125,0.725,0.33673865,0.1683693 +0.125,0.775,0.15,0.15000004 +0.125,0.775,0.10606602,0.21213204 +0.125,0.775,0.21213204,0.10606599 +0.125,0.775,0.18898815,0.18898815 +0.125,0.775,0.1336348,0.26726967 +0.125,0.775,0.2672696,0.1336348 +0.125,0.775,0.23811015,0.23811013 +0.125,0.775,0.1683693,0.3367386 +0.125,0.775,0.33673865,0.1683693 +0.125,0.825,0.15,0.14999998 +0.125,0.825,0.10606602,0.2121321 +0.125,0.825,0.21213204,0.10606599 +0.125,0.825,0.18898815,0.18898809 +0.125,0.82500005,0.1336348,0.26726967 +0.125,0.825,0.2672696,0.1336348 +0.125,0.825,0.23811015,0.23811018 +0.125,0.825,0.1683693,0.3367386 +0.125,0.825,0.33673865,0.1683693 +0.125,0.875,0.15,0.14999998 +0.125,0.875,0.10606602,0.2121321 +0.125,0.875,0.21213204,0.10606599 +0.125,0.875,0.18898815,0.18898809 +0.125,0.875,0.1336348,0.2672696 +0.125,0.875,0.2672696,0.1336348 +0.125,0.875,0.23811015,0.23811018 +0.125,0.875,0.1683693,0.3367386 +0.125,0.875,0.33673865,0.1683693 +0.125,0.925,0.15,0.14999998 +0.125,0.925,0.10606602,0.2121321 +0.125,0.92499995,0.21213204,0.10606593 +0.125,0.925,0.18898815,0.18898809 +0.125,0.9250001,0.1336348,0.26726967 +0.125,0.92499995,0.2672696,0.13363475 +0.125,0.925,0.23811015,0.23811018 +0.125,0.92499995,0.1683693,0.33673853 +0.125,0.92499995,0.33673865,0.16836923 +0.125,0.97499996,0.15,0.14999998 +0.125,0.975,0.10606602,0.21213204 +0.125,0.975,0.21213204,0.10606599 +0.125,0.97499996,0.18898815,0.18898809 +0.125,0.975,0.1336348,0.26726967 +0.125,0.975,0.2672696,0.1336348 +0.125,0.975,0.23811015,0.23811013 +0.125,0.975,0.1683693,0.3367386 +0.125,0.975,0.33673865,0.1683693 +0.175,0.025,0.15,0.15 +0.17500001,0.024999995,0.106066026,0.21213204 +0.17499998,0.024999999,0.21213202,0.10606602 +0.17500001,0.024999999,0.18898816,0.18898816 +0.175,0.025000002,0.1336348,0.2672696 +0.17500001,0.024999999,0.2672696,0.1336348 +0.175,0.025000002,0.23811015,0.23811015 +0.17500001,0.024999999,0.16836931,0.3367386 +0.175,0.025000004,0.33673862,0.16836931 +0.175,0.075,0.15,0.15 +0.17500001,0.074999996,0.106066026,0.21213202 +0.17499998,0.075,0.21213202,0.10606602 +0.17500001,0.075,0.18898816,0.18898815 +0.175,0.075,0.1336348,0.2672696 +0.17500001,0.075,0.2672696,0.1336348 +0.175,0.075,0.23811015,0.23811015 +0.17500001,0.075,0.16836931,0.33673862 +0.175,0.075,0.33673862,0.16836932 +0.175,0.125,0.15,0.15 +0.17500001,0.125,0.106066026,0.21213204 +0.17499998,0.125,0.21213202,0.10606602 +0.17500001,0.125,0.18898816,0.18898815 +0.175,0.125,0.1336348,0.2672696 +0.17500001,0.125,0.2672696,0.1336348 +0.175,0.125,0.23811015,0.23811015 +0.17500001,0.125,0.16836931,0.33673865 +0.175,0.125,0.33673862,0.1683693 +0.175,0.175,0.15,0.15 +0.17500001,0.17499998,0.106066026,0.21213202 +0.17499998,0.17500001,0.21213202,0.106066026 +0.17500001,0.17500001,0.18898816,0.18898816 +0.175,0.17500001,0.1336348,0.2672696 +0.17500001,0.175,0.2672696,0.1336348 +0.175,0.175,0.23811015,0.23811015 +0.17500001,0.175,0.16836931,0.33673862 +0.175,0.17500001,0.33673862,0.16836931 +0.175,0.22500001,0.15,0.15 +0.17500001,0.225,0.106066026,0.21213202 +0.17499998,0.22500001,0.21213202,0.10606602 +0.17500001,0.225,0.18898816,0.18898815 +0.175,0.225,0.1336348,0.2672696 +0.17500001,0.225,0.2672696,0.1336348 +0.175,0.225,0.23811015,0.23811017 +0.17500001,0.22500001,0.16836931,0.33673862 +0.175,0.225,0.33673862,0.1683693 +0.175,0.275,0.15,0.14999999 +0.17500001,0.275,0.106066026,0.21213204 +0.17499998,0.275,0.21213202,0.10606605 +0.17500001,0.275,0.18898816,0.18898816 +0.175,0.275,0.1336348,0.2672696 +0.17500001,0.275,0.2672696,0.1336348 +0.175,0.27499998,0.23811015,0.23811015 +0.17500001,0.275,0.16836931,0.3367386 +0.175,0.275,0.33673862,0.16836931 +0.175,0.325,0.15,0.15 +0.17500001,0.32500002,0.106066026,0.21213205 +0.17499998,0.325,0.21213202,0.10606602 +0.17500001,0.325,0.18898816,0.18898815 +0.175,0.325,0.1336348,0.2672696 +0.17500001,0.325,0.2672696,0.1336348 +0.175,0.325,0.23811015,0.23811015 +0.17500001,0.325,0.16836931,0.3367386 +0.175,0.325,0.33673862,0.16836928 +0.175,0.375,0.15,0.14999998 +0.17500001,0.375,0.106066026,0.21213207 +0.17499998,0.375,0.21213202,0.10606605 +0.17500001,0.375,0.18898816,0.18898812 +0.175,0.375,0.1336348,0.2672696 +0.17500001,0.375,0.2672696,0.13363484 +0.175,0.375,0.23811015,0.23811018 +0.17500001,0.375,0.16836931,0.33673862 +0.175,0.375,0.33673862,0.1683693 +0.175,0.425,0.15,0.15 +0.17500001,0.425,0.106066026,0.21213207 +0.17499998,0.425,0.21213202,0.10606602 +0.17500001,0.42499998,0.18898816,0.18898815 +0.175,0.425,0.1336348,0.2672696 +0.17500001,0.425,0.2672696,0.1336348 +0.175,0.425,0.23811015,0.23811018 +0.17500001,0.425,0.16836931,0.33673862 +0.175,0.425,0.33673862,0.1683693 +0.175,0.47500002,0.15,0.15 +0.17500001,0.475,0.106066026,0.21213204 +0.17499998,0.475,0.21213202,0.10606605 +0.17500001,0.475,0.18898816,0.18898815 +0.175,0.47500002,0.1336348,0.26726964 +0.17500001,0.475,0.2672696,0.13363487 +0.175,0.475,0.23811015,0.23811013 +0.17500001,0.475,0.16836931,0.33673865 +0.175,0.47500002,0.33673862,0.16836932 +0.175,0.525,0.15,0.15000004 +0.17500001,0.525,0.106066026,0.21213207 +0.17499998,0.525,0.21213202,0.10606605 +0.17500001,0.525,0.18898816,0.18898815 +0.175,0.525,0.1336348,0.26726958 +0.17500001,0.525,0.2672696,0.13363487 +0.175,0.525,0.23811015,0.23811015 +0.17500001,0.525,0.16836931,0.3367386 +0.175,0.525,0.33673862,0.16836926 +0.175,0.575,0.15,0.14999998 +0.17500001,0.575,0.106066026,0.21213207 +0.17499998,0.57500005,0.21213202,0.10606605 +0.17500001,0.575,0.18898816,0.18898809 +0.175,0.575,0.1336348,0.2672696 +0.17500001,0.57500005,0.2672696,0.13363487 +0.175,0.575,0.23811015,0.23811015 +0.17500001,0.575,0.16836931,0.3367386 +0.175,0.575,0.33673862,0.1683693 +0.175,0.625,0.15,0.14999998 +0.17500001,0.625,0.106066026,0.2121321 +0.17499998,0.625,0.21213202,0.10606599 +0.17500001,0.625,0.18898816,0.18898809 +0.175,0.625,0.1336348,0.2672696 +0.17500001,0.625,0.2672696,0.1336348 +0.175,0.625,0.23811015,0.23811018 +0.17500001,0.625,0.16836931,0.3367386 +0.175,0.625,0.33673862,0.1683693 +0.175,0.675,0.15,0.14999998 +0.17500001,0.675,0.106066026,0.2121321 +0.17499998,0.67499995,0.21213202,0.10606605 +0.17500001,0.675,0.18898816,0.18898809 +0.175,0.6750001,0.1336348,0.26726967 +0.17500001,0.67499995,0.2672696,0.13363487 +0.175,0.675,0.23811015,0.23811018 +0.17500001,0.675,0.16836931,0.3367386 +0.175,0.675,0.33673862,0.1683693 +0.175,0.725,0.15,0.15000004 +0.17500001,0.725,0.106066026,0.21213204 +0.17499998,0.725,0.21213202,0.10606605 +0.17500001,0.725,0.18898816,0.18898815 +0.175,0.725,0.1336348,0.2672696 +0.17500001,0.725,0.2672696,0.13363487 +0.175,0.725,0.23811015,0.23811013 +0.17500001,0.725,0.16836931,0.3367386 +0.175,0.725,0.33673862,0.1683693 +0.175,0.775,0.15,0.15000004 +0.17500001,0.775,0.106066026,0.21213204 +0.17499998,0.775,0.21213202,0.10606599 +0.17500001,0.775,0.18898816,0.18898815 +0.175,0.775,0.1336348,0.26726967 +0.17500001,0.775,0.2672696,0.1336348 +0.175,0.775,0.23811015,0.23811013 +0.17500001,0.775,0.16836931,0.3367386 +0.175,0.775,0.33673862,0.1683693 +0.175,0.825,0.15,0.14999998 +0.17500001,0.825,0.106066026,0.2121321 +0.17499998,0.825,0.21213202,0.10606599 +0.17500001,0.825,0.18898816,0.18898809 +0.175,0.82500005,0.1336348,0.26726967 +0.17500001,0.825,0.2672696,0.1336348 +0.175,0.825,0.23811015,0.23811018 +0.17500001,0.825,0.16836931,0.3367386 +0.175,0.825,0.33673862,0.1683693 +0.175,0.875,0.15,0.14999998 +0.17500001,0.875,0.106066026,0.2121321 +0.17499998,0.875,0.21213202,0.10606599 +0.17500001,0.875,0.18898816,0.18898809 +0.175,0.875,0.1336348,0.2672696 +0.17500001,0.875,0.2672696,0.1336348 +0.175,0.875,0.23811015,0.23811018 +0.17500001,0.875,0.16836931,0.3367386 +0.175,0.875,0.33673862,0.1683693 +0.175,0.925,0.15,0.14999998 +0.17500001,0.925,0.106066026,0.2121321 +0.17499998,0.92499995,0.21213202,0.10606593 +0.17500001,0.925,0.18898816,0.18898809 +0.175,0.9250001,0.1336348,0.26726967 +0.17500001,0.92499995,0.2672696,0.13363475 +0.175,0.925,0.23811015,0.23811018 +0.17500001,0.92499995,0.16836931,0.33673853 +0.175,0.92499995,0.33673862,0.16836923 +0.175,0.97499996,0.15,0.14999998 +0.17500001,0.975,0.106066026,0.21213204 +0.17499998,0.975,0.21213202,0.10606599 +0.17500001,0.97499996,0.18898816,0.18898809 +0.175,0.975,0.1336348,0.26726967 +0.17500001,0.975,0.2672696,0.1336348 +0.175,0.975,0.23811015,0.23811013 +0.17500001,0.975,0.16836931,0.3367386 +0.175,0.975,0.33673862,0.1683693 +0.22500001,0.025,0.15,0.15 +0.22500001,0.024999995,0.10606602,0.21213204 +0.225,0.024999999,0.21213202,0.10606602 +0.225,0.024999999,0.18898815,0.18898816 +0.225,0.025000002,0.1336348,0.2672696 +0.225,0.024999999,0.2672696,0.1336348 +0.225,0.025000002,0.23811017,0.23811015 +0.225,0.024999999,0.1683693,0.3367386 +0.22500001,0.025000004,0.33673862,0.16836931 +0.22500001,0.075,0.15,0.15 +0.22500001,0.074999996,0.10606602,0.21213202 +0.225,0.075,0.21213202,0.10606602 +0.225,0.075,0.18898815,0.18898815 +0.225,0.075,0.1336348,0.2672696 +0.225,0.075,0.2672696,0.1336348 +0.225,0.075,0.23811017,0.23811015 +0.225,0.075,0.1683693,0.33673862 +0.22500001,0.075,0.33673862,0.16836932 +0.22500001,0.125,0.15,0.15 +0.22500001,0.125,0.10606602,0.21213204 +0.225,0.125,0.21213202,0.10606602 +0.225,0.125,0.18898815,0.18898815 +0.225,0.125,0.1336348,0.2672696 +0.225,0.125,0.2672696,0.1336348 +0.225,0.125,0.23811017,0.23811015 +0.225,0.125,0.1683693,0.33673865 +0.22500001,0.125,0.33673862,0.1683693 +0.22500001,0.175,0.15,0.15 +0.22500001,0.17499998,0.10606602,0.21213202 +0.225,0.17500001,0.21213202,0.106066026 +0.225,0.17500001,0.18898815,0.18898816 +0.225,0.17500001,0.1336348,0.2672696 +0.225,0.175,0.2672696,0.1336348 +0.225,0.175,0.23811017,0.23811015 +0.225,0.175,0.1683693,0.33673862 +0.22500001,0.17500001,0.33673862,0.16836931 +0.22500001,0.22500001,0.15,0.15 +0.22500001,0.225,0.10606602,0.21213202 +0.225,0.22500001,0.21213202,0.10606602 +0.225,0.225,0.18898815,0.18898815 +0.225,0.225,0.1336348,0.2672696 +0.225,0.225,0.2672696,0.1336348 +0.225,0.225,0.23811017,0.23811017 +0.225,0.22500001,0.1683693,0.33673862 +0.22500001,0.225,0.33673862,0.1683693 +0.22500001,0.275,0.15,0.14999999 +0.22500001,0.275,0.10606602,0.21213204 +0.225,0.275,0.21213202,0.10606605 +0.225,0.275,0.18898815,0.18898816 +0.225,0.275,0.1336348,0.2672696 +0.225,0.275,0.2672696,0.1336348 +0.225,0.27499998,0.23811017,0.23811015 +0.225,0.275,0.1683693,0.3367386 +0.22500001,0.275,0.33673862,0.16836931 +0.22500001,0.325,0.15,0.15 +0.22500001,0.32500002,0.10606602,0.21213205 +0.225,0.325,0.21213202,0.10606602 +0.225,0.325,0.18898815,0.18898815 +0.225,0.325,0.1336348,0.2672696 +0.225,0.325,0.2672696,0.1336348 +0.225,0.325,0.23811017,0.23811015 +0.225,0.325,0.1683693,0.3367386 +0.22500001,0.325,0.33673862,0.16836928 +0.22500001,0.375,0.15,0.14999998 +0.22500001,0.375,0.10606602,0.21213207 +0.225,0.375,0.21213202,0.10606605 +0.225,0.375,0.18898815,0.18898812 +0.225,0.375,0.1336348,0.2672696 +0.225,0.375,0.2672696,0.13363484 +0.225,0.375,0.23811017,0.23811018 +0.225,0.375,0.1683693,0.33673862 +0.22500001,0.375,0.33673862,0.1683693 +0.22500001,0.425,0.15,0.15 +0.22500001,0.425,0.10606602,0.21213207 +0.225,0.425,0.21213202,0.10606602 +0.225,0.42499998,0.18898815,0.18898815 +0.225,0.425,0.1336348,0.2672696 +0.225,0.425,0.2672696,0.1336348 +0.225,0.425,0.23811017,0.23811018 +0.225,0.425,0.1683693,0.33673862 +0.22500001,0.425,0.33673862,0.1683693 +0.22500001,0.47500002,0.15,0.15 +0.22500001,0.475,0.10606602,0.21213204 +0.225,0.475,0.21213202,0.10606605 +0.225,0.475,0.18898815,0.18898815 +0.225,0.47500002,0.1336348,0.26726964 +0.225,0.475,0.2672696,0.13363487 +0.225,0.475,0.23811017,0.23811013 +0.225,0.475,0.1683693,0.33673865 +0.22500001,0.47500002,0.33673862,0.16836932 +0.22500001,0.525,0.15,0.15000004 +0.22500001,0.525,0.10606602,0.21213207 +0.225,0.525,0.21213202,0.10606605 +0.225,0.525,0.18898815,0.18898815 +0.225,0.525,0.1336348,0.26726958 +0.225,0.525,0.2672696,0.13363487 +0.225,0.525,0.23811017,0.23811015 +0.225,0.525,0.1683693,0.3367386 +0.22500001,0.525,0.33673862,0.16836926 +0.22500001,0.575,0.15,0.14999998 +0.22500001,0.575,0.10606602,0.21213207 +0.225,0.57500005,0.21213202,0.10606605 +0.225,0.575,0.18898815,0.18898809 +0.225,0.575,0.1336348,0.2672696 +0.225,0.57500005,0.2672696,0.13363487 +0.225,0.575,0.23811017,0.23811015 +0.225,0.575,0.1683693,0.3367386 +0.22500001,0.575,0.33673862,0.1683693 +0.22500001,0.625,0.15,0.14999998 +0.22500001,0.625,0.10606602,0.2121321 +0.225,0.625,0.21213202,0.10606599 +0.225,0.625,0.18898815,0.18898809 +0.225,0.625,0.1336348,0.2672696 +0.225,0.625,0.2672696,0.1336348 +0.225,0.625,0.23811017,0.23811018 +0.225,0.625,0.1683693,0.3367386 +0.22500001,0.625,0.33673862,0.1683693 +0.22500001,0.675,0.15,0.14999998 +0.22500001,0.675,0.10606602,0.2121321 +0.225,0.67499995,0.21213202,0.10606605 +0.225,0.675,0.18898815,0.18898809 +0.225,0.6750001,0.1336348,0.26726967 +0.225,0.67499995,0.2672696,0.13363487 +0.225,0.675,0.23811017,0.23811018 +0.225,0.675,0.1683693,0.3367386 +0.22500001,0.675,0.33673862,0.1683693 +0.22500001,0.725,0.15,0.15000004 +0.22500001,0.725,0.10606602,0.21213204 +0.225,0.725,0.21213202,0.10606605 +0.225,0.725,0.18898815,0.18898815 +0.225,0.725,0.1336348,0.2672696 +0.225,0.725,0.2672696,0.13363487 +0.225,0.725,0.23811017,0.23811013 +0.225,0.725,0.1683693,0.3367386 +0.22500001,0.725,0.33673862,0.1683693 +0.22500001,0.775,0.15,0.15000004 +0.22500001,0.775,0.10606602,0.21213204 +0.225,0.775,0.21213202,0.10606599 +0.225,0.775,0.18898815,0.18898815 +0.225,0.775,0.1336348,0.26726967 +0.225,0.775,0.2672696,0.1336348 +0.225,0.775,0.23811017,0.23811013 +0.225,0.775,0.1683693,0.3367386 +0.22500001,0.775,0.33673862,0.1683693 +0.22500001,0.825,0.15,0.14999998 +0.22500001,0.825,0.10606602,0.2121321 +0.225,0.825,0.21213202,0.10606599 +0.225,0.825,0.18898815,0.18898809 +0.225,0.82500005,0.1336348,0.26726967 +0.225,0.825,0.2672696,0.1336348 +0.225,0.825,0.23811017,0.23811018 +0.225,0.825,0.1683693,0.3367386 +0.22500001,0.825,0.33673862,0.1683693 +0.22500001,0.875,0.15,0.14999998 +0.22500001,0.875,0.10606602,0.2121321 +0.225,0.875,0.21213202,0.10606599 +0.225,0.875,0.18898815,0.18898809 +0.225,0.875,0.1336348,0.2672696 +0.225,0.875,0.2672696,0.1336348 +0.225,0.875,0.23811017,0.23811018 +0.225,0.875,0.1683693,0.3367386 +0.22500001,0.875,0.33673862,0.1683693 +0.22500001,0.925,0.15,0.14999998 +0.22500001,0.925,0.10606602,0.2121321 +0.225,0.92499995,0.21213202,0.10606593 +0.225,0.925,0.18898815,0.18898809 +0.225,0.9250001,0.1336348,0.26726967 +0.225,0.92499995,0.2672696,0.13363475 +0.225,0.925,0.23811017,0.23811018 +0.225,0.92499995,0.1683693,0.33673853 +0.22500001,0.92499995,0.33673862,0.16836923 +0.22500001,0.97499996,0.15,0.14999998 +0.22500001,0.975,0.10606602,0.21213204 +0.225,0.975,0.21213202,0.10606599 +0.225,0.97499996,0.18898815,0.18898809 +0.225,0.975,0.1336348,0.26726967 +0.225,0.975,0.2672696,0.1336348 +0.225,0.975,0.23811017,0.23811013 +0.225,0.975,0.1683693,0.3367386 +0.22500001,0.975,0.33673862,0.1683693 +0.275,0.025,0.14999999,0.15 +0.275,0.024999995,0.10606605,0.21213204 +0.275,0.024999999,0.21213204,0.10606602 +0.275,0.024999999,0.18898816,0.18898816 +0.275,0.025000002,0.1336348,0.2672696 +0.275,0.024999999,0.2672696,0.1336348 +0.27499998,0.025000002,0.23811015,0.23811015 +0.275,0.024999999,0.16836931,0.3367386 +0.275,0.025000004,0.3367386,0.16836931 +0.275,0.075,0.14999999,0.15 +0.275,0.074999996,0.10606605,0.21213202 +0.275,0.075,0.21213204,0.10606602 +0.275,0.075,0.18898816,0.18898815 +0.275,0.075,0.1336348,0.2672696 +0.275,0.075,0.2672696,0.1336348 +0.27499998,0.075,0.23811015,0.23811015 +0.275,0.075,0.16836931,0.33673862 +0.275,0.075,0.3367386,0.16836932 +0.275,0.125,0.14999999,0.15 +0.275,0.125,0.10606605,0.21213204 +0.275,0.125,0.21213204,0.10606602 +0.275,0.125,0.18898816,0.18898815 +0.275,0.125,0.1336348,0.2672696 +0.275,0.125,0.2672696,0.1336348 +0.27499998,0.125,0.23811015,0.23811015 +0.275,0.125,0.16836931,0.33673865 +0.275,0.125,0.3367386,0.1683693 +0.275,0.175,0.14999999,0.15 +0.275,0.17499998,0.10606605,0.21213202 +0.275,0.17500001,0.21213204,0.106066026 +0.275,0.17500001,0.18898816,0.18898816 +0.275,0.17500001,0.1336348,0.2672696 +0.275,0.175,0.2672696,0.1336348 +0.27499998,0.175,0.23811015,0.23811015 +0.275,0.175,0.16836931,0.33673862 +0.275,0.17500001,0.3367386,0.16836931 +0.275,0.22500001,0.14999999,0.15 +0.275,0.225,0.10606605,0.21213202 +0.275,0.22500001,0.21213204,0.10606602 +0.275,0.225,0.18898816,0.18898815 +0.275,0.225,0.1336348,0.2672696 +0.275,0.225,0.2672696,0.1336348 +0.27499998,0.225,0.23811015,0.23811017 +0.275,0.22500001,0.16836931,0.33673862 +0.275,0.225,0.3367386,0.1683693 +0.275,0.275,0.14999999,0.14999999 +0.275,0.275,0.10606605,0.21213204 +0.275,0.275,0.21213204,0.10606605 +0.275,0.275,0.18898816,0.18898816 +0.275,0.275,0.1336348,0.2672696 +0.275,0.275,0.2672696,0.1336348 +0.27499998,0.27499998,0.23811015,0.23811015 +0.275,0.275,0.16836931,0.3367386 +0.275,0.275,0.3367386,0.16836931 +0.275,0.325,0.14999999,0.15 +0.275,0.32500002,0.10606605,0.21213205 +0.275,0.325,0.21213204,0.10606602 +0.275,0.325,0.18898816,0.18898815 +0.275,0.325,0.1336348,0.2672696 +0.275,0.325,0.2672696,0.1336348 +0.27499998,0.325,0.23811015,0.23811015 +0.275,0.325,0.16836931,0.3367386 +0.275,0.325,0.3367386,0.16836928 +0.275,0.375,0.14999999,0.14999998 +0.275,0.375,0.10606605,0.21213207 +0.275,0.375,0.21213204,0.10606605 +0.275,0.375,0.18898816,0.18898812 +0.275,0.375,0.1336348,0.2672696 +0.275,0.375,0.2672696,0.13363484 +0.27499998,0.375,0.23811015,0.23811018 +0.275,0.375,0.16836931,0.33673862 +0.275,0.375,0.3367386,0.1683693 +0.275,0.425,0.14999999,0.15 +0.275,0.425,0.10606605,0.21213207 +0.275,0.425,0.21213204,0.10606602 +0.275,0.42499998,0.18898816,0.18898815 +0.275,0.425,0.1336348,0.2672696 +0.275,0.425,0.2672696,0.1336348 +0.27499998,0.425,0.23811015,0.23811018 +0.275,0.425,0.16836931,0.33673862 +0.275,0.425,0.3367386,0.1683693 +0.275,0.47500002,0.14999999,0.15 +0.275,0.475,0.10606605,0.21213204 +0.275,0.475,0.21213204,0.10606605 +0.275,0.475,0.18898816,0.18898815 +0.275,0.47500002,0.1336348,0.26726964 +0.275,0.475,0.2672696,0.13363487 +0.27499998,0.475,0.23811015,0.23811013 +0.275,0.475,0.16836931,0.33673865 +0.275,0.47500002,0.3367386,0.16836932 +0.275,0.525,0.14999999,0.15000004 +0.275,0.525,0.10606605,0.21213207 +0.275,0.525,0.21213204,0.10606605 +0.275,0.525,0.18898816,0.18898815 +0.275,0.525,0.1336348,0.26726958 +0.275,0.525,0.2672696,0.13363487 +0.27499998,0.525,0.23811015,0.23811015 +0.275,0.525,0.16836931,0.3367386 +0.275,0.525,0.3367386,0.16836926 +0.275,0.575,0.14999999,0.14999998 +0.275,0.575,0.10606605,0.21213207 +0.275,0.57500005,0.21213204,0.10606605 +0.275,0.575,0.18898816,0.18898809 +0.275,0.575,0.1336348,0.2672696 +0.275,0.57500005,0.2672696,0.13363487 +0.27499998,0.575,0.23811015,0.23811015 +0.275,0.575,0.16836931,0.3367386 +0.275,0.575,0.3367386,0.1683693 +0.275,0.625,0.14999999,0.14999998 +0.275,0.625,0.10606605,0.2121321 +0.275,0.625,0.21213204,0.10606599 +0.275,0.625,0.18898816,0.18898809 +0.275,0.625,0.1336348,0.2672696 +0.275,0.625,0.2672696,0.1336348 +0.27499998,0.625,0.23811015,0.23811018 +0.275,0.625,0.16836931,0.3367386 +0.275,0.625,0.3367386,0.1683693 +0.275,0.675,0.14999999,0.14999998 +0.275,0.675,0.10606605,0.2121321 +0.275,0.67499995,0.21213204,0.10606605 +0.275,0.675,0.18898816,0.18898809 +0.275,0.6750001,0.1336348,0.26726967 +0.275,0.67499995,0.2672696,0.13363487 +0.27499998,0.675,0.23811015,0.23811018 +0.275,0.675,0.16836931,0.3367386 +0.275,0.675,0.3367386,0.1683693 +0.275,0.725,0.14999999,0.15000004 +0.275,0.725,0.10606605,0.21213204 +0.275,0.725,0.21213204,0.10606605 +0.275,0.725,0.18898816,0.18898815 +0.275,0.725,0.1336348,0.2672696 +0.275,0.725,0.2672696,0.13363487 +0.27499998,0.725,0.23811015,0.23811013 +0.275,0.725,0.16836931,0.3367386 +0.275,0.725,0.3367386,0.1683693 +0.275,0.775,0.14999999,0.15000004 +0.275,0.775,0.10606605,0.21213204 +0.275,0.775,0.21213204,0.10606599 +0.275,0.775,0.18898816,0.18898815 +0.275,0.775,0.1336348,0.26726967 +0.275,0.775,0.2672696,0.1336348 +0.27499998,0.775,0.23811015,0.23811013 +0.275,0.775,0.16836931,0.3367386 +0.275,0.775,0.3367386,0.1683693 +0.275,0.825,0.14999999,0.14999998 +0.275,0.825,0.10606605,0.2121321 +0.275,0.825,0.21213204,0.10606599 +0.275,0.825,0.18898816,0.18898809 +0.275,0.82500005,0.1336348,0.26726967 +0.275,0.825,0.2672696,0.1336348 +0.27499998,0.825,0.23811015,0.23811018 +0.275,0.825,0.16836931,0.3367386 +0.275,0.825,0.3367386,0.1683693 +0.275,0.875,0.14999999,0.14999998 +0.275,0.875,0.10606605,0.2121321 +0.275,0.875,0.21213204,0.10606599 +0.275,0.875,0.18898816,0.18898809 +0.275,0.875,0.1336348,0.2672696 +0.275,0.875,0.2672696,0.1336348 +0.27499998,0.875,0.23811015,0.23811018 +0.275,0.875,0.16836931,0.3367386 +0.275,0.875,0.3367386,0.1683693 +0.275,0.925,0.14999999,0.14999998 +0.275,0.925,0.10606605,0.2121321 +0.275,0.92499995,0.21213204,0.10606593 +0.275,0.925,0.18898816,0.18898809 +0.275,0.9250001,0.1336348,0.26726967 +0.275,0.92499995,0.2672696,0.13363475 +0.27499998,0.925,0.23811015,0.23811018 +0.275,0.92499995,0.16836931,0.33673853 +0.275,0.92499995,0.3367386,0.16836923 +0.275,0.97499996,0.14999999,0.14999998 +0.275,0.975,0.10606605,0.21213204 +0.275,0.975,0.21213204,0.10606599 +0.275,0.97499996,0.18898816,0.18898809 +0.275,0.975,0.1336348,0.26726967 +0.275,0.975,0.2672696,0.1336348 +0.27499998,0.975,0.23811015,0.23811013 +0.275,0.975,0.16836931,0.3367386 +0.275,0.975,0.3367386,0.1683693 +0.325,0.025,0.15,0.15 +0.325,0.024999995,0.10606602,0.21213204 +0.32500002,0.024999999,0.21213205,0.10606602 +0.325,0.024999999,0.18898815,0.18898816 +0.325,0.025000002,0.1336348,0.2672696 +0.325,0.024999999,0.2672696,0.1336348 +0.325,0.025000002,0.23811015,0.23811015 +0.325,0.024999999,0.16836928,0.3367386 +0.325,0.025000004,0.3367386,0.16836931 +0.325,0.075,0.15,0.15 +0.325,0.074999996,0.10606602,0.21213202 +0.32500002,0.075,0.21213205,0.10606602 +0.325,0.075,0.18898815,0.18898815 +0.325,0.075,0.1336348,0.2672696 +0.325,0.075,0.2672696,0.1336348 +0.325,0.075,0.23811015,0.23811015 +0.325,0.075,0.16836928,0.33673862 +0.325,0.075,0.3367386,0.16836932 +0.325,0.125,0.15,0.15 +0.325,0.125,0.10606602,0.21213204 +0.32500002,0.125,0.21213205,0.10606602 +0.325,0.125,0.18898815,0.18898815 +0.325,0.125,0.1336348,0.2672696 +0.325,0.125,0.2672696,0.1336348 +0.325,0.125,0.23811015,0.23811015 +0.325,0.125,0.16836928,0.33673865 +0.325,0.125,0.3367386,0.1683693 +0.325,0.175,0.15,0.15 +0.325,0.17499998,0.10606602,0.21213202 +0.32500002,0.17500001,0.21213205,0.106066026 +0.325,0.17500001,0.18898815,0.18898816 +0.325,0.17500001,0.1336348,0.2672696 +0.325,0.175,0.2672696,0.1336348 +0.325,0.175,0.23811015,0.23811015 +0.325,0.175,0.16836928,0.33673862 +0.325,0.17500001,0.3367386,0.16836931 +0.325,0.22500001,0.15,0.15 +0.325,0.225,0.10606602,0.21213202 +0.32500002,0.22500001,0.21213205,0.10606602 +0.325,0.225,0.18898815,0.18898815 +0.325,0.225,0.1336348,0.2672696 +0.325,0.225,0.2672696,0.1336348 +0.325,0.225,0.23811015,0.23811017 +0.325,0.22500001,0.16836928,0.33673862 +0.325,0.225,0.3367386,0.1683693 +0.325,0.275,0.15,0.14999999 +0.325,0.275,0.10606602,0.21213204 +0.32500002,0.275,0.21213205,0.10606605 +0.325,0.275,0.18898815,0.18898816 +0.325,0.275,0.1336348,0.2672696 +0.325,0.275,0.2672696,0.1336348 +0.325,0.27499998,0.23811015,0.23811015 +0.325,0.275,0.16836928,0.3367386 +0.325,0.275,0.3367386,0.16836931 +0.325,0.325,0.15,0.15 +0.325,0.32500002,0.10606602,0.21213205 +0.32500002,0.325,0.21213205,0.10606602 +0.325,0.325,0.18898815,0.18898815 +0.325,0.325,0.1336348,0.2672696 +0.325,0.325,0.2672696,0.1336348 +0.325,0.325,0.23811015,0.23811015 +0.325,0.325,0.16836928,0.3367386 +0.325,0.325,0.3367386,0.16836928 +0.325,0.375,0.15,0.14999998 +0.325,0.375,0.10606602,0.21213207 +0.32500002,0.375,0.21213205,0.10606605 +0.325,0.375,0.18898815,0.18898812 +0.325,0.375,0.1336348,0.2672696 +0.325,0.375,0.2672696,0.13363484 +0.325,0.375,0.23811015,0.23811018 +0.325,0.375,0.16836928,0.33673862 +0.325,0.375,0.3367386,0.1683693 +0.325,0.425,0.15,0.15 +0.325,0.425,0.10606602,0.21213207 +0.32500002,0.425,0.21213205,0.10606602 +0.325,0.42499998,0.18898815,0.18898815 +0.325,0.425,0.1336348,0.2672696 +0.325,0.425,0.2672696,0.1336348 +0.325,0.425,0.23811015,0.23811018 +0.325,0.425,0.16836928,0.33673862 +0.325,0.425,0.3367386,0.1683693 +0.325,0.47500002,0.15,0.15 +0.325,0.475,0.10606602,0.21213204 +0.32500002,0.475,0.21213205,0.10606605 +0.325,0.475,0.18898815,0.18898815 +0.325,0.47500002,0.1336348,0.26726964 +0.325,0.475,0.2672696,0.13363487 +0.325,0.475,0.23811015,0.23811013 +0.325,0.475,0.16836928,0.33673865 +0.325,0.47500002,0.3367386,0.16836932 +0.325,0.525,0.15,0.15000004 +0.325,0.525,0.10606602,0.21213207 +0.32500002,0.525,0.21213205,0.10606605 +0.325,0.525,0.18898815,0.18898815 +0.325,0.525,0.1336348,0.26726958 +0.325,0.525,0.2672696,0.13363487 +0.325,0.525,0.23811015,0.23811015 +0.325,0.525,0.16836928,0.3367386 +0.325,0.525,0.3367386,0.16836926 +0.325,0.575,0.15,0.14999998 +0.325,0.575,0.10606602,0.21213207 +0.32500002,0.57500005,0.21213205,0.10606605 +0.325,0.575,0.18898815,0.18898809 +0.325,0.575,0.1336348,0.2672696 +0.325,0.57500005,0.2672696,0.13363487 +0.325,0.575,0.23811015,0.23811015 +0.325,0.575,0.16836928,0.3367386 +0.325,0.575,0.3367386,0.1683693 +0.325,0.625,0.15,0.14999998 +0.325,0.625,0.10606602,0.2121321 +0.32500002,0.625,0.21213205,0.10606599 +0.325,0.625,0.18898815,0.18898809 +0.325,0.625,0.1336348,0.2672696 +0.325,0.625,0.2672696,0.1336348 +0.325,0.625,0.23811015,0.23811018 +0.325,0.625,0.16836928,0.3367386 +0.325,0.625,0.3367386,0.1683693 +0.325,0.675,0.15,0.14999998 +0.325,0.675,0.10606602,0.2121321 +0.32500002,0.67499995,0.21213205,0.10606605 +0.325,0.675,0.18898815,0.18898809 +0.325,0.6750001,0.1336348,0.26726967 +0.325,0.67499995,0.2672696,0.13363487 +0.325,0.675,0.23811015,0.23811018 +0.325,0.675,0.16836928,0.3367386 +0.325,0.675,0.3367386,0.1683693 +0.325,0.725,0.15,0.15000004 +0.325,0.725,0.10606602,0.21213204 +0.32500002,0.725,0.21213205,0.10606605 +0.325,0.725,0.18898815,0.18898815 +0.325,0.725,0.1336348,0.2672696 +0.325,0.725,0.2672696,0.13363487 +0.325,0.725,0.23811015,0.23811013 +0.325,0.725,0.16836928,0.3367386 +0.325,0.725,0.3367386,0.1683693 +0.325,0.775,0.15,0.15000004 +0.325,0.775,0.10606602,0.21213204 +0.32500002,0.775,0.21213205,0.10606599 +0.325,0.775,0.18898815,0.18898815 +0.325,0.775,0.1336348,0.26726967 +0.325,0.775,0.2672696,0.1336348 +0.325,0.775,0.23811015,0.23811013 +0.325,0.775,0.16836928,0.3367386 +0.325,0.775,0.3367386,0.1683693 +0.325,0.825,0.15,0.14999998 +0.325,0.825,0.10606602,0.2121321 +0.32500002,0.825,0.21213205,0.10606599 +0.325,0.825,0.18898815,0.18898809 +0.325,0.82500005,0.1336348,0.26726967 +0.325,0.825,0.2672696,0.1336348 +0.325,0.825,0.23811015,0.23811018 +0.325,0.825,0.16836928,0.3367386 +0.325,0.825,0.3367386,0.1683693 +0.325,0.875,0.15,0.14999998 +0.325,0.875,0.10606602,0.2121321 +0.32500002,0.875,0.21213205,0.10606599 +0.325,0.875,0.18898815,0.18898809 +0.325,0.875,0.1336348,0.2672696 +0.325,0.875,0.2672696,0.1336348 +0.325,0.875,0.23811015,0.23811018 +0.325,0.875,0.16836928,0.3367386 +0.325,0.875,0.3367386,0.1683693 +0.325,0.925,0.15,0.14999998 +0.325,0.925,0.10606602,0.2121321 +0.32500002,0.92499995,0.21213205,0.10606593 +0.325,0.925,0.18898815,0.18898809 +0.325,0.9250001,0.1336348,0.26726967 +0.325,0.92499995,0.2672696,0.13363475 +0.325,0.925,0.23811015,0.23811018 +0.325,0.92499995,0.16836928,0.33673853 +0.325,0.92499995,0.3367386,0.16836923 +0.325,0.97499996,0.15,0.14999998 +0.325,0.975,0.10606602,0.21213204 +0.32500002,0.975,0.21213205,0.10606599 +0.325,0.97499996,0.18898815,0.18898809 +0.325,0.975,0.1336348,0.26726967 +0.325,0.975,0.2672696,0.1336348 +0.325,0.975,0.23811015,0.23811013 +0.325,0.975,0.16836928,0.3367386 +0.325,0.975,0.3367386,0.1683693 +0.375,0.025,0.14999998,0.15 +0.375,0.024999995,0.10606605,0.21213204 +0.375,0.024999999,0.21213207,0.10606602 +0.375,0.024999999,0.18898812,0.18898816 +0.375,0.025000002,0.13363484,0.2672696 +0.375,0.024999999,0.2672696,0.1336348 +0.375,0.025000002,0.23811018,0.23811015 +0.375,0.024999999,0.1683693,0.3367386 +0.375,0.025000004,0.33673862,0.16836931 +0.375,0.075,0.14999998,0.15 +0.375,0.074999996,0.10606605,0.21213202 +0.375,0.075,0.21213207,0.10606602 +0.375,0.075,0.18898812,0.18898815 +0.375,0.075,0.13363484,0.2672696 +0.375,0.075,0.2672696,0.1336348 +0.375,0.075,0.23811018,0.23811015 +0.375,0.075,0.1683693,0.33673862 +0.375,0.075,0.33673862,0.16836932 +0.375,0.125,0.14999998,0.15 +0.375,0.125,0.10606605,0.21213204 +0.375,0.125,0.21213207,0.10606602 +0.375,0.125,0.18898812,0.18898815 +0.375,0.125,0.13363484,0.2672696 +0.375,0.125,0.2672696,0.1336348 +0.375,0.125,0.23811018,0.23811015 +0.375,0.125,0.1683693,0.33673865 +0.375,0.125,0.33673862,0.1683693 +0.375,0.175,0.14999998,0.15 +0.375,0.17499998,0.10606605,0.21213202 +0.375,0.17500001,0.21213207,0.106066026 +0.375,0.17500001,0.18898812,0.18898816 +0.375,0.17500001,0.13363484,0.2672696 +0.375,0.175,0.2672696,0.1336348 +0.375,0.175,0.23811018,0.23811015 +0.375,0.175,0.1683693,0.33673862 +0.375,0.17500001,0.33673862,0.16836931 +0.375,0.22500001,0.14999998,0.15 +0.375,0.225,0.10606605,0.21213202 +0.375,0.22500001,0.21213207,0.10606602 +0.375,0.225,0.18898812,0.18898815 +0.375,0.225,0.13363484,0.2672696 +0.375,0.225,0.2672696,0.1336348 +0.375,0.225,0.23811018,0.23811017 +0.375,0.22500001,0.1683693,0.33673862 +0.375,0.225,0.33673862,0.1683693 +0.375,0.275,0.14999998,0.14999999 +0.375,0.275,0.10606605,0.21213204 +0.375,0.275,0.21213207,0.10606605 +0.375,0.275,0.18898812,0.18898816 +0.375,0.275,0.13363484,0.2672696 +0.375,0.275,0.2672696,0.1336348 +0.375,0.27499998,0.23811018,0.23811015 +0.375,0.275,0.1683693,0.3367386 +0.375,0.275,0.33673862,0.16836931 +0.375,0.325,0.14999998,0.15 +0.375,0.32500002,0.10606605,0.21213205 +0.375,0.325,0.21213207,0.10606602 +0.375,0.325,0.18898812,0.18898815 +0.375,0.325,0.13363484,0.2672696 +0.375,0.325,0.2672696,0.1336348 +0.375,0.325,0.23811018,0.23811015 +0.375,0.325,0.1683693,0.3367386 +0.375,0.325,0.33673862,0.16836928 +0.375,0.375,0.14999998,0.14999998 +0.375,0.375,0.10606605,0.21213207 +0.375,0.375,0.21213207,0.10606605 +0.375,0.375,0.18898812,0.18898812 +0.375,0.375,0.13363484,0.2672696 +0.375,0.375,0.2672696,0.13363484 +0.375,0.375,0.23811018,0.23811018 +0.375,0.375,0.1683693,0.33673862 +0.375,0.375,0.33673862,0.1683693 +0.375,0.425,0.14999998,0.15 +0.375,0.425,0.10606605,0.21213207 +0.375,0.425,0.21213207,0.10606602 +0.375,0.42499998,0.18898812,0.18898815 +0.375,0.425,0.13363484,0.2672696 +0.375,0.425,0.2672696,0.1336348 +0.375,0.425,0.23811018,0.23811018 +0.375,0.425,0.1683693,0.33673862 +0.375,0.425,0.33673862,0.1683693 +0.375,0.47500002,0.14999998,0.15 +0.375,0.475,0.10606605,0.21213204 +0.375,0.475,0.21213207,0.10606605 +0.375,0.475,0.18898812,0.18898815 +0.375,0.47500002,0.13363484,0.26726964 +0.375,0.475,0.2672696,0.13363487 +0.375,0.475,0.23811018,0.23811013 +0.375,0.475,0.1683693,0.33673865 +0.375,0.47500002,0.33673862,0.16836932 +0.375,0.525,0.14999998,0.15000004 +0.375,0.525,0.10606605,0.21213207 +0.375,0.525,0.21213207,0.10606605 +0.375,0.525,0.18898812,0.18898815 +0.375,0.525,0.13363484,0.26726958 +0.375,0.525,0.2672696,0.13363487 +0.375,0.525,0.23811018,0.23811015 +0.375,0.525,0.1683693,0.3367386 +0.375,0.525,0.33673862,0.16836926 +0.375,0.575,0.14999998,0.14999998 +0.375,0.575,0.10606605,0.21213207 +0.375,0.57500005,0.21213207,0.10606605 +0.375,0.575,0.18898812,0.18898809 +0.375,0.575,0.13363484,0.2672696 +0.375,0.57500005,0.2672696,0.13363487 +0.375,0.575,0.23811018,0.23811015 +0.375,0.575,0.1683693,0.3367386 +0.375,0.575,0.33673862,0.1683693 +0.375,0.625,0.14999998,0.14999998 +0.375,0.625,0.10606605,0.2121321 +0.375,0.625,0.21213207,0.10606599 +0.375,0.625,0.18898812,0.18898809 +0.375,0.625,0.13363484,0.2672696 +0.375,0.625,0.2672696,0.1336348 +0.375,0.625,0.23811018,0.23811018 +0.375,0.625,0.1683693,0.3367386 +0.375,0.625,0.33673862,0.1683693 +0.375,0.675,0.14999998,0.14999998 +0.375,0.675,0.10606605,0.2121321 +0.375,0.67499995,0.21213207,0.10606605 +0.375,0.675,0.18898812,0.18898809 +0.375,0.6750001,0.13363484,0.26726967 +0.375,0.67499995,0.2672696,0.13363487 +0.375,0.675,0.23811018,0.23811018 +0.375,0.675,0.1683693,0.3367386 +0.375,0.675,0.33673862,0.1683693 +0.375,0.725,0.14999998,0.15000004 +0.375,0.725,0.10606605,0.21213204 +0.375,0.725,0.21213207,0.10606605 +0.375,0.725,0.18898812,0.18898815 +0.375,0.725,0.13363484,0.2672696 +0.375,0.725,0.2672696,0.13363487 +0.375,0.725,0.23811018,0.23811013 +0.375,0.725,0.1683693,0.3367386 +0.375,0.725,0.33673862,0.1683693 +0.375,0.775,0.14999998,0.15000004 +0.375,0.775,0.10606605,0.21213204 +0.375,0.775,0.21213207,0.10606599 +0.375,0.775,0.18898812,0.18898815 +0.375,0.775,0.13363484,0.26726967 +0.375,0.775,0.2672696,0.1336348 +0.375,0.775,0.23811018,0.23811013 +0.375,0.775,0.1683693,0.3367386 +0.375,0.775,0.33673862,0.1683693 +0.375,0.825,0.14999998,0.14999998 +0.375,0.825,0.10606605,0.2121321 +0.375,0.825,0.21213207,0.10606599 +0.375,0.825,0.18898812,0.18898809 +0.375,0.82500005,0.13363484,0.26726967 +0.375,0.825,0.2672696,0.1336348 +0.375,0.825,0.23811018,0.23811018 +0.375,0.825,0.1683693,0.3367386 +0.375,0.825,0.33673862,0.1683693 +0.375,0.875,0.14999998,0.14999998 +0.375,0.875,0.10606605,0.2121321 +0.375,0.875,0.21213207,0.10606599 +0.375,0.875,0.18898812,0.18898809 +0.375,0.875,0.13363484,0.2672696 +0.375,0.875,0.2672696,0.1336348 +0.375,0.875,0.23811018,0.23811018 +0.375,0.875,0.1683693,0.3367386 +0.375,0.875,0.33673862,0.1683693 +0.375,0.925,0.14999998,0.14999998 +0.375,0.925,0.10606605,0.2121321 +0.375,0.92499995,0.21213207,0.10606593 +0.375,0.925,0.18898812,0.18898809 +0.375,0.9250001,0.13363484,0.26726967 +0.375,0.92499995,0.2672696,0.13363475 +0.375,0.925,0.23811018,0.23811018 +0.375,0.92499995,0.1683693,0.33673853 +0.375,0.92499995,0.33673862,0.16836923 +0.375,0.97499996,0.14999998,0.14999998 +0.375,0.975,0.10606605,0.21213204 +0.375,0.975,0.21213207,0.10606599 +0.375,0.97499996,0.18898812,0.18898809 +0.375,0.975,0.13363484,0.26726967 +0.375,0.975,0.2672696,0.1336348 +0.375,0.975,0.23811018,0.23811013 +0.375,0.975,0.1683693,0.3367386 +0.375,0.975,0.33673862,0.1683693 +0.425,0.025,0.15,0.15 +0.425,0.024999995,0.10606602,0.21213204 +0.425,0.024999999,0.21213207,0.10606602 +0.42499998,0.024999999,0.18898815,0.18898816 +0.425,0.025000002,0.1336348,0.2672696 +0.425,0.024999999,0.2672696,0.1336348 +0.425,0.025000002,0.23811018,0.23811015 +0.425,0.024999999,0.1683693,0.3367386 +0.425,0.025000004,0.33673862,0.16836931 +0.425,0.075,0.15,0.15 +0.425,0.074999996,0.10606602,0.21213202 +0.425,0.075,0.21213207,0.10606602 +0.42499998,0.075,0.18898815,0.18898815 +0.425,0.075,0.1336348,0.2672696 +0.425,0.075,0.2672696,0.1336348 +0.425,0.075,0.23811018,0.23811015 +0.425,0.075,0.1683693,0.33673862 +0.425,0.075,0.33673862,0.16836932 +0.425,0.125,0.15,0.15 +0.425,0.125,0.10606602,0.21213204 +0.425,0.125,0.21213207,0.10606602 +0.42499998,0.125,0.18898815,0.18898815 +0.425,0.125,0.1336348,0.2672696 +0.425,0.125,0.2672696,0.1336348 +0.425,0.125,0.23811018,0.23811015 +0.425,0.125,0.1683693,0.33673865 +0.425,0.125,0.33673862,0.1683693 +0.425,0.175,0.15,0.15 +0.425,0.17499998,0.10606602,0.21213202 +0.425,0.17500001,0.21213207,0.106066026 +0.42499998,0.17500001,0.18898815,0.18898816 +0.425,0.17500001,0.1336348,0.2672696 +0.425,0.175,0.2672696,0.1336348 +0.425,0.175,0.23811018,0.23811015 +0.425,0.175,0.1683693,0.33673862 +0.425,0.17500001,0.33673862,0.16836931 +0.425,0.22500001,0.15,0.15 +0.425,0.225,0.10606602,0.21213202 +0.425,0.22500001,0.21213207,0.10606602 +0.42499998,0.225,0.18898815,0.18898815 +0.425,0.225,0.1336348,0.2672696 +0.425,0.225,0.2672696,0.1336348 +0.425,0.225,0.23811018,0.23811017 +0.425,0.22500001,0.1683693,0.33673862 +0.425,0.225,0.33673862,0.1683693 +0.425,0.275,0.15,0.14999999 +0.425,0.275,0.10606602,0.21213204 +0.425,0.275,0.21213207,0.10606605 +0.42499998,0.275,0.18898815,0.18898816 +0.425,0.275,0.1336348,0.2672696 +0.425,0.275,0.2672696,0.1336348 +0.425,0.27499998,0.23811018,0.23811015 +0.425,0.275,0.1683693,0.3367386 +0.425,0.275,0.33673862,0.16836931 +0.425,0.325,0.15,0.15 +0.425,0.32500002,0.10606602,0.21213205 +0.425,0.325,0.21213207,0.10606602 +0.42499998,0.325,0.18898815,0.18898815 +0.425,0.325,0.1336348,0.2672696 +0.425,0.325,0.2672696,0.1336348 +0.425,0.325,0.23811018,0.23811015 +0.425,0.325,0.1683693,0.3367386 +0.425,0.325,0.33673862,0.16836928 +0.425,0.375,0.15,0.14999998 +0.425,0.375,0.10606602,0.21213207 +0.425,0.375,0.21213207,0.10606605 +0.42499998,0.375,0.18898815,0.18898812 +0.425,0.375,0.1336348,0.2672696 +0.425,0.375,0.2672696,0.13363484 +0.425,0.375,0.23811018,0.23811018 +0.425,0.375,0.1683693,0.33673862 +0.425,0.375,0.33673862,0.1683693 +0.425,0.425,0.15,0.15 +0.425,0.425,0.10606602,0.21213207 +0.425,0.425,0.21213207,0.10606602 +0.42499998,0.42499998,0.18898815,0.18898815 +0.425,0.425,0.1336348,0.2672696 +0.425,0.425,0.2672696,0.1336348 +0.425,0.425,0.23811018,0.23811018 +0.425,0.425,0.1683693,0.33673862 +0.425,0.425,0.33673862,0.1683693 +0.425,0.47500002,0.15,0.15 +0.425,0.475,0.10606602,0.21213204 +0.425,0.475,0.21213207,0.10606605 +0.42499998,0.475,0.18898815,0.18898815 +0.425,0.47500002,0.1336348,0.26726964 +0.425,0.475,0.2672696,0.13363487 +0.425,0.475,0.23811018,0.23811013 +0.425,0.475,0.1683693,0.33673865 +0.425,0.47500002,0.33673862,0.16836932 +0.425,0.525,0.15,0.15000004 +0.425,0.525,0.10606602,0.21213207 +0.425,0.525,0.21213207,0.10606605 +0.42499998,0.525,0.18898815,0.18898815 +0.425,0.525,0.1336348,0.26726958 +0.425,0.525,0.2672696,0.13363487 +0.425,0.525,0.23811018,0.23811015 +0.425,0.525,0.1683693,0.3367386 +0.425,0.525,0.33673862,0.16836926 +0.425,0.575,0.15,0.14999998 +0.425,0.575,0.10606602,0.21213207 +0.425,0.57500005,0.21213207,0.10606605 +0.42499998,0.575,0.18898815,0.18898809 +0.425,0.575,0.1336348,0.2672696 +0.425,0.57500005,0.2672696,0.13363487 +0.425,0.575,0.23811018,0.23811015 +0.425,0.575,0.1683693,0.3367386 +0.425,0.575,0.33673862,0.1683693 +0.425,0.625,0.15,0.14999998 +0.425,0.625,0.10606602,0.2121321 +0.425,0.625,0.21213207,0.10606599 +0.42499998,0.625,0.18898815,0.18898809 +0.425,0.625,0.1336348,0.2672696 +0.425,0.625,0.2672696,0.1336348 +0.425,0.625,0.23811018,0.23811018 +0.425,0.625,0.1683693,0.3367386 +0.425,0.625,0.33673862,0.1683693 +0.425,0.675,0.15,0.14999998 +0.425,0.675,0.10606602,0.2121321 +0.425,0.67499995,0.21213207,0.10606605 +0.42499998,0.675,0.18898815,0.18898809 +0.425,0.6750001,0.1336348,0.26726967 +0.425,0.67499995,0.2672696,0.13363487 +0.425,0.675,0.23811018,0.23811018 +0.425,0.675,0.1683693,0.3367386 +0.425,0.675,0.33673862,0.1683693 +0.425,0.725,0.15,0.15000004 +0.425,0.725,0.10606602,0.21213204 +0.425,0.725,0.21213207,0.10606605 +0.42499998,0.725,0.18898815,0.18898815 +0.425,0.725,0.1336348,0.2672696 +0.425,0.725,0.2672696,0.13363487 +0.425,0.725,0.23811018,0.23811013 +0.425,0.725,0.1683693,0.3367386 +0.425,0.725,0.33673862,0.1683693 +0.425,0.775,0.15,0.15000004 +0.425,0.775,0.10606602,0.21213204 +0.425,0.775,0.21213207,0.10606599 +0.42499998,0.775,0.18898815,0.18898815 +0.425,0.775,0.1336348,0.26726967 +0.425,0.775,0.2672696,0.1336348 +0.425,0.775,0.23811018,0.23811013 +0.425,0.775,0.1683693,0.3367386 +0.425,0.775,0.33673862,0.1683693 +0.425,0.825,0.15,0.14999998 +0.425,0.825,0.10606602,0.2121321 +0.425,0.825,0.21213207,0.10606599 +0.42499998,0.825,0.18898815,0.18898809 +0.425,0.82500005,0.1336348,0.26726967 +0.425,0.825,0.2672696,0.1336348 +0.425,0.825,0.23811018,0.23811018 +0.425,0.825,0.1683693,0.3367386 +0.425,0.825,0.33673862,0.1683693 +0.425,0.875,0.15,0.14999998 +0.425,0.875,0.10606602,0.2121321 +0.425,0.875,0.21213207,0.10606599 +0.42499998,0.875,0.18898815,0.18898809 +0.425,0.875,0.1336348,0.2672696 +0.425,0.875,0.2672696,0.1336348 +0.425,0.875,0.23811018,0.23811018 +0.425,0.875,0.1683693,0.3367386 +0.425,0.875,0.33673862,0.1683693 +0.425,0.925,0.15,0.14999998 +0.425,0.925,0.10606602,0.2121321 +0.425,0.92499995,0.21213207,0.10606593 +0.42499998,0.925,0.18898815,0.18898809 +0.425,0.9250001,0.1336348,0.26726967 +0.425,0.92499995,0.2672696,0.13363475 +0.425,0.925,0.23811018,0.23811018 +0.425,0.92499995,0.1683693,0.33673853 +0.425,0.92499995,0.33673862,0.16836923 +0.425,0.97499996,0.15,0.14999998 +0.425,0.975,0.10606602,0.21213204 +0.425,0.975,0.21213207,0.10606599 +0.42499998,0.97499996,0.18898815,0.18898809 +0.425,0.975,0.1336348,0.26726967 +0.425,0.975,0.2672696,0.1336348 +0.425,0.975,0.23811018,0.23811013 +0.425,0.975,0.1683693,0.3367386 +0.425,0.975,0.33673862,0.1683693 +0.47500002,0.025,0.15,0.15 +0.475,0.024999995,0.10606605,0.21213204 +0.475,0.024999999,0.21213204,0.10606602 +0.475,0.024999999,0.18898815,0.18898816 +0.475,0.025000002,0.13363487,0.2672696 +0.47500002,0.024999999,0.26726964,0.1336348 +0.475,0.025000002,0.23811013,0.23811015 +0.47500002,0.024999999,0.16836932,0.3367386 +0.475,0.025000004,0.33673865,0.16836931 +0.47500002,0.075,0.15,0.15 +0.475,0.074999996,0.10606605,0.21213202 +0.475,0.075,0.21213204,0.10606602 +0.475,0.075,0.18898815,0.18898815 +0.475,0.075,0.13363487,0.2672696 +0.47500002,0.075,0.26726964,0.1336348 +0.475,0.075,0.23811013,0.23811015 +0.47500002,0.075,0.16836932,0.33673862 +0.475,0.075,0.33673865,0.16836932 +0.47500002,0.125,0.15,0.15 +0.475,0.125,0.10606605,0.21213204 +0.475,0.125,0.21213204,0.10606602 +0.475,0.125,0.18898815,0.18898815 +0.475,0.125,0.13363487,0.2672696 +0.47500002,0.125,0.26726964,0.1336348 +0.475,0.125,0.23811013,0.23811015 +0.47500002,0.125,0.16836932,0.33673865 +0.475,0.125,0.33673865,0.1683693 +0.47500002,0.175,0.15,0.15 +0.475,0.17499998,0.10606605,0.21213202 +0.475,0.17500001,0.21213204,0.106066026 +0.475,0.17500001,0.18898815,0.18898816 +0.475,0.17500001,0.13363487,0.2672696 +0.47500002,0.175,0.26726964,0.1336348 +0.475,0.175,0.23811013,0.23811015 +0.47500002,0.175,0.16836932,0.33673862 +0.475,0.17500001,0.33673865,0.16836931 +0.47500002,0.22500001,0.15,0.15 +0.475,0.225,0.10606605,0.21213202 +0.475,0.22500001,0.21213204,0.10606602 +0.475,0.225,0.18898815,0.18898815 +0.475,0.225,0.13363487,0.2672696 +0.47500002,0.225,0.26726964,0.1336348 +0.475,0.225,0.23811013,0.23811017 +0.47500002,0.22500001,0.16836932,0.33673862 +0.475,0.225,0.33673865,0.1683693 +0.47500002,0.275,0.15,0.14999999 +0.475,0.275,0.10606605,0.21213204 +0.475,0.275,0.21213204,0.10606605 +0.475,0.275,0.18898815,0.18898816 +0.475,0.275,0.13363487,0.2672696 +0.47500002,0.275,0.26726964,0.1336348 +0.475,0.27499998,0.23811013,0.23811015 +0.47500002,0.275,0.16836932,0.3367386 +0.475,0.275,0.33673865,0.16836931 +0.47500002,0.325,0.15,0.15 +0.475,0.32500002,0.10606605,0.21213205 +0.475,0.325,0.21213204,0.10606602 +0.475,0.325,0.18898815,0.18898815 +0.475,0.325,0.13363487,0.2672696 +0.47500002,0.325,0.26726964,0.1336348 +0.475,0.325,0.23811013,0.23811015 +0.47500002,0.325,0.16836932,0.3367386 +0.475,0.325,0.33673865,0.16836928 +0.47500002,0.375,0.15,0.14999998 +0.475,0.375,0.10606605,0.21213207 +0.475,0.375,0.21213204,0.10606605 +0.475,0.375,0.18898815,0.18898812 +0.475,0.375,0.13363487,0.2672696 +0.47500002,0.375,0.26726964,0.13363484 +0.475,0.375,0.23811013,0.23811018 +0.47500002,0.375,0.16836932,0.33673862 +0.475,0.375,0.33673865,0.1683693 +0.47500002,0.425,0.15,0.15 +0.475,0.425,0.10606605,0.21213207 +0.475,0.425,0.21213204,0.10606602 +0.475,0.42499998,0.18898815,0.18898815 +0.475,0.425,0.13363487,0.2672696 +0.47500002,0.425,0.26726964,0.1336348 +0.475,0.425,0.23811013,0.23811018 +0.47500002,0.425,0.16836932,0.33673862 +0.475,0.425,0.33673865,0.1683693 +0.47500002,0.47500002,0.15,0.15 +0.475,0.475,0.10606605,0.21213204 +0.475,0.475,0.21213204,0.10606605 +0.475,0.475,0.18898815,0.18898815 +0.475,0.47500002,0.13363487,0.26726964 +0.47500002,0.475,0.26726964,0.13363487 +0.475,0.475,0.23811013,0.23811013 +0.47500002,0.475,0.16836932,0.33673865 +0.475,0.47500002,0.33673865,0.16836932 +0.47500002,0.525,0.15,0.15000004 +0.475,0.525,0.10606605,0.21213207 +0.475,0.525,0.21213204,0.10606605 +0.475,0.525,0.18898815,0.18898815 +0.475,0.525,0.13363487,0.26726958 +0.47500002,0.525,0.26726964,0.13363487 +0.475,0.525,0.23811013,0.23811015 +0.47500002,0.525,0.16836932,0.3367386 +0.475,0.525,0.33673865,0.16836926 +0.47500002,0.575,0.15,0.14999998 +0.475,0.575,0.10606605,0.21213207 +0.475,0.57500005,0.21213204,0.10606605 +0.475,0.575,0.18898815,0.18898809 +0.475,0.575,0.13363487,0.2672696 +0.47500002,0.57500005,0.26726964,0.13363487 +0.475,0.575,0.23811013,0.23811015 +0.47500002,0.575,0.16836932,0.3367386 +0.475,0.575,0.33673865,0.1683693 +0.47500002,0.625,0.15,0.14999998 +0.475,0.625,0.10606605,0.2121321 +0.475,0.625,0.21213204,0.10606599 +0.475,0.625,0.18898815,0.18898809 +0.475,0.625,0.13363487,0.2672696 +0.47500002,0.625,0.26726964,0.1336348 +0.475,0.625,0.23811013,0.23811018 +0.47500002,0.625,0.16836932,0.3367386 +0.475,0.625,0.33673865,0.1683693 +0.47500002,0.675,0.15,0.14999998 +0.475,0.675,0.10606605,0.2121321 +0.475,0.67499995,0.21213204,0.10606605 +0.475,0.675,0.18898815,0.18898809 +0.475,0.6750001,0.13363487,0.26726967 +0.47500002,0.67499995,0.26726964,0.13363487 +0.475,0.675,0.23811013,0.23811018 +0.47500002,0.675,0.16836932,0.3367386 +0.475,0.675,0.33673865,0.1683693 +0.47500002,0.725,0.15,0.15000004 +0.475,0.725,0.10606605,0.21213204 +0.475,0.725,0.21213204,0.10606605 +0.475,0.725,0.18898815,0.18898815 +0.475,0.725,0.13363487,0.2672696 +0.47500002,0.725,0.26726964,0.13363487 +0.475,0.725,0.23811013,0.23811013 +0.47500002,0.725,0.16836932,0.3367386 +0.475,0.725,0.33673865,0.1683693 +0.47500002,0.775,0.15,0.15000004 +0.475,0.775,0.10606605,0.21213204 +0.475,0.775,0.21213204,0.10606599 +0.475,0.775,0.18898815,0.18898815 +0.475,0.775,0.13363487,0.26726967 +0.47500002,0.775,0.26726964,0.1336348 +0.475,0.775,0.23811013,0.23811013 +0.47500002,0.775,0.16836932,0.3367386 +0.475,0.775,0.33673865,0.1683693 +0.47500002,0.825,0.15,0.14999998 +0.475,0.825,0.10606605,0.2121321 +0.475,0.825,0.21213204,0.10606599 +0.475,0.825,0.18898815,0.18898809 +0.475,0.82500005,0.13363487,0.26726967 +0.47500002,0.825,0.26726964,0.1336348 +0.475,0.825,0.23811013,0.23811018 +0.47500002,0.825,0.16836932,0.3367386 +0.475,0.825,0.33673865,0.1683693 +0.47500002,0.875,0.15,0.14999998 +0.475,0.875,0.10606605,0.2121321 +0.475,0.875,0.21213204,0.10606599 +0.475,0.875,0.18898815,0.18898809 +0.475,0.875,0.13363487,0.2672696 +0.47500002,0.875,0.26726964,0.1336348 +0.475,0.875,0.23811013,0.23811018 +0.47500002,0.875,0.16836932,0.3367386 +0.475,0.875,0.33673865,0.1683693 +0.47500002,0.925,0.15,0.14999998 +0.475,0.925,0.10606605,0.2121321 +0.475,0.92499995,0.21213204,0.10606593 +0.475,0.925,0.18898815,0.18898809 +0.475,0.9250001,0.13363487,0.26726967 +0.47500002,0.92499995,0.26726964,0.13363475 +0.475,0.925,0.23811013,0.23811018 +0.47500002,0.92499995,0.16836932,0.33673853 +0.475,0.92499995,0.33673865,0.16836923 +0.47500002,0.97499996,0.15,0.14999998 +0.475,0.975,0.10606605,0.21213204 +0.475,0.975,0.21213204,0.10606599 +0.475,0.97499996,0.18898815,0.18898809 +0.475,0.975,0.13363487,0.26726967 +0.47500002,0.975,0.26726964,0.1336348 +0.475,0.975,0.23811013,0.23811013 +0.47500002,0.975,0.16836932,0.3367386 +0.475,0.975,0.33673865,0.1683693 +0.525,0.025,0.15000004,0.15 +0.525,0.024999995,0.10606605,0.21213204 +0.525,0.024999999,0.21213207,0.10606602 +0.525,0.024999999,0.18898815,0.18898816 +0.525,0.025000002,0.13363487,0.2672696 +0.525,0.024999999,0.26726958,0.1336348 +0.525,0.025000002,0.23811015,0.23811015 +0.525,0.024999999,0.16836926,0.3367386 +0.525,0.025000004,0.3367386,0.16836931 +0.525,0.075,0.15000004,0.15 +0.525,0.074999996,0.10606605,0.21213202 +0.525,0.075,0.21213207,0.10606602 +0.525,0.075,0.18898815,0.18898815 +0.525,0.075,0.13363487,0.2672696 +0.525,0.075,0.26726958,0.1336348 +0.525,0.075,0.23811015,0.23811015 +0.525,0.075,0.16836926,0.33673862 +0.525,0.075,0.3367386,0.16836932 +0.525,0.125,0.15000004,0.15 +0.525,0.125,0.10606605,0.21213204 +0.525,0.125,0.21213207,0.10606602 +0.525,0.125,0.18898815,0.18898815 +0.525,0.125,0.13363487,0.2672696 +0.525,0.125,0.26726958,0.1336348 +0.525,0.125,0.23811015,0.23811015 +0.525,0.125,0.16836926,0.33673865 +0.525,0.125,0.3367386,0.1683693 +0.525,0.175,0.15000004,0.15 +0.525,0.17499998,0.10606605,0.21213202 +0.525,0.17500001,0.21213207,0.106066026 +0.525,0.17500001,0.18898815,0.18898816 +0.525,0.17500001,0.13363487,0.2672696 +0.525,0.175,0.26726958,0.1336348 +0.525,0.175,0.23811015,0.23811015 +0.525,0.175,0.16836926,0.33673862 +0.525,0.17500001,0.3367386,0.16836931 +0.525,0.22500001,0.15000004,0.15 +0.525,0.225,0.10606605,0.21213202 +0.525,0.22500001,0.21213207,0.10606602 +0.525,0.225,0.18898815,0.18898815 +0.525,0.225,0.13363487,0.2672696 +0.525,0.225,0.26726958,0.1336348 +0.525,0.225,0.23811015,0.23811017 +0.525,0.22500001,0.16836926,0.33673862 +0.525,0.225,0.3367386,0.1683693 +0.525,0.275,0.15000004,0.14999999 +0.525,0.275,0.10606605,0.21213204 +0.525,0.275,0.21213207,0.10606605 +0.525,0.275,0.18898815,0.18898816 +0.525,0.275,0.13363487,0.2672696 +0.525,0.275,0.26726958,0.1336348 +0.525,0.27499998,0.23811015,0.23811015 +0.525,0.275,0.16836926,0.3367386 +0.525,0.275,0.3367386,0.16836931 +0.525,0.325,0.15000004,0.15 +0.525,0.32500002,0.10606605,0.21213205 +0.525,0.325,0.21213207,0.10606602 +0.525,0.325,0.18898815,0.18898815 +0.525,0.325,0.13363487,0.2672696 +0.525,0.325,0.26726958,0.1336348 +0.525,0.325,0.23811015,0.23811015 +0.525,0.325,0.16836926,0.3367386 +0.525,0.325,0.3367386,0.16836928 +0.525,0.375,0.15000004,0.14999998 +0.525,0.375,0.10606605,0.21213207 +0.525,0.375,0.21213207,0.10606605 +0.525,0.375,0.18898815,0.18898812 +0.525,0.375,0.13363487,0.2672696 +0.525,0.375,0.26726958,0.13363484 +0.525,0.375,0.23811015,0.23811018 +0.525,0.375,0.16836926,0.33673862 +0.525,0.375,0.3367386,0.1683693 +0.525,0.425,0.15000004,0.15 +0.525,0.425,0.10606605,0.21213207 +0.525,0.425,0.21213207,0.10606602 +0.525,0.42499998,0.18898815,0.18898815 +0.525,0.425,0.13363487,0.2672696 +0.525,0.425,0.26726958,0.1336348 +0.525,0.425,0.23811015,0.23811018 +0.525,0.425,0.16836926,0.33673862 +0.525,0.425,0.3367386,0.1683693 +0.525,0.47500002,0.15000004,0.15 +0.525,0.475,0.10606605,0.21213204 +0.525,0.475,0.21213207,0.10606605 +0.525,0.475,0.18898815,0.18898815 +0.525,0.47500002,0.13363487,0.26726964 +0.525,0.475,0.26726958,0.13363487 +0.525,0.475,0.23811015,0.23811013 +0.525,0.475,0.16836926,0.33673865 +0.525,0.47500002,0.3367386,0.16836932 +0.525,0.525,0.15000004,0.15000004 +0.525,0.525,0.10606605,0.21213207 +0.525,0.525,0.21213207,0.10606605 +0.525,0.525,0.18898815,0.18898815 +0.525,0.525,0.13363487,0.26726958 +0.525,0.525,0.26726958,0.13363487 +0.525,0.525,0.23811015,0.23811015 +0.525,0.525,0.16836926,0.3367386 +0.525,0.525,0.3367386,0.16836926 +0.525,0.575,0.15000004,0.14999998 +0.525,0.575,0.10606605,0.21213207 +0.525,0.57500005,0.21213207,0.10606605 +0.525,0.575,0.18898815,0.18898809 +0.525,0.575,0.13363487,0.2672696 +0.525,0.57500005,0.26726958,0.13363487 +0.525,0.575,0.23811015,0.23811015 +0.525,0.575,0.16836926,0.3367386 +0.525,0.575,0.3367386,0.1683693 +0.525,0.625,0.15000004,0.14999998 +0.525,0.625,0.10606605,0.2121321 +0.525,0.625,0.21213207,0.10606599 +0.525,0.625,0.18898815,0.18898809 +0.525,0.625,0.13363487,0.2672696 +0.525,0.625,0.26726958,0.1336348 +0.525,0.625,0.23811015,0.23811018 +0.525,0.625,0.16836926,0.3367386 +0.525,0.625,0.3367386,0.1683693 +0.525,0.675,0.15000004,0.14999998 +0.525,0.675,0.10606605,0.2121321 +0.525,0.67499995,0.21213207,0.10606605 +0.525,0.675,0.18898815,0.18898809 +0.525,0.6750001,0.13363487,0.26726967 +0.525,0.67499995,0.26726958,0.13363487 +0.525,0.675,0.23811015,0.23811018 +0.525,0.675,0.16836926,0.3367386 +0.525,0.675,0.3367386,0.1683693 +0.525,0.725,0.15000004,0.15000004 +0.525,0.725,0.10606605,0.21213204 +0.525,0.725,0.21213207,0.10606605 +0.525,0.725,0.18898815,0.18898815 +0.525,0.725,0.13363487,0.2672696 +0.525,0.725,0.26726958,0.13363487 +0.525,0.725,0.23811015,0.23811013 +0.525,0.725,0.16836926,0.3367386 +0.525,0.725,0.3367386,0.1683693 +0.525,0.775,0.15000004,0.15000004 +0.525,0.775,0.10606605,0.21213204 +0.525,0.775,0.21213207,0.10606599 +0.525,0.775,0.18898815,0.18898815 +0.525,0.775,0.13363487,0.26726967 +0.525,0.775,0.26726958,0.1336348 +0.525,0.775,0.23811015,0.23811013 +0.525,0.775,0.16836926,0.3367386 +0.525,0.775,0.3367386,0.1683693 +0.525,0.825,0.15000004,0.14999998 +0.525,0.825,0.10606605,0.2121321 +0.525,0.825,0.21213207,0.10606599 +0.525,0.825,0.18898815,0.18898809 +0.525,0.82500005,0.13363487,0.26726967 +0.525,0.825,0.26726958,0.1336348 +0.525,0.825,0.23811015,0.23811018 +0.525,0.825,0.16836926,0.3367386 +0.525,0.825,0.3367386,0.1683693 +0.525,0.875,0.15000004,0.14999998 +0.525,0.875,0.10606605,0.2121321 +0.525,0.875,0.21213207,0.10606599 +0.525,0.875,0.18898815,0.18898809 +0.525,0.875,0.13363487,0.2672696 +0.525,0.875,0.26726958,0.1336348 +0.525,0.875,0.23811015,0.23811018 +0.525,0.875,0.16836926,0.3367386 +0.525,0.875,0.3367386,0.1683693 +0.525,0.925,0.15000004,0.14999998 +0.525,0.925,0.10606605,0.2121321 +0.525,0.92499995,0.21213207,0.10606593 +0.525,0.925,0.18898815,0.18898809 +0.525,0.9250001,0.13363487,0.26726967 +0.525,0.92499995,0.26726958,0.13363475 +0.525,0.925,0.23811015,0.23811018 +0.525,0.92499995,0.16836926,0.33673853 +0.525,0.92499995,0.3367386,0.16836923 +0.525,0.97499996,0.15000004,0.14999998 +0.525,0.975,0.10606605,0.21213204 +0.525,0.975,0.21213207,0.10606599 +0.525,0.97499996,0.18898815,0.18898809 +0.525,0.975,0.13363487,0.26726967 +0.525,0.975,0.26726958,0.1336348 +0.525,0.975,0.23811015,0.23811013 +0.525,0.975,0.16836926,0.3367386 +0.525,0.975,0.3367386,0.1683693 +0.575,0.025,0.14999998,0.15 +0.57500005,0.024999995,0.10606605,0.21213204 +0.575,0.024999999,0.21213207,0.10606602 +0.575,0.024999999,0.18898809,0.18898816 +0.57500005,0.025000002,0.13363487,0.2672696 +0.575,0.024999999,0.2672696,0.1336348 +0.575,0.025000002,0.23811015,0.23811015 +0.575,0.024999999,0.1683693,0.3367386 +0.575,0.025000004,0.3367386,0.16836931 +0.575,0.075,0.14999998,0.15 +0.57500005,0.074999996,0.10606605,0.21213202 +0.575,0.075,0.21213207,0.10606602 +0.575,0.075,0.18898809,0.18898815 +0.57500005,0.075,0.13363487,0.2672696 +0.575,0.075,0.2672696,0.1336348 +0.575,0.075,0.23811015,0.23811015 +0.575,0.075,0.1683693,0.33673862 +0.575,0.075,0.3367386,0.16836932 +0.575,0.125,0.14999998,0.15 +0.57500005,0.125,0.10606605,0.21213204 +0.575,0.125,0.21213207,0.10606602 +0.575,0.125,0.18898809,0.18898815 +0.57500005,0.125,0.13363487,0.2672696 +0.575,0.125,0.2672696,0.1336348 +0.575,0.125,0.23811015,0.23811015 +0.575,0.125,0.1683693,0.33673865 +0.575,0.125,0.3367386,0.1683693 +0.575,0.175,0.14999998,0.15 +0.57500005,0.17499998,0.10606605,0.21213202 +0.575,0.17500001,0.21213207,0.106066026 +0.575,0.17500001,0.18898809,0.18898816 +0.57500005,0.17500001,0.13363487,0.2672696 +0.575,0.175,0.2672696,0.1336348 +0.575,0.175,0.23811015,0.23811015 +0.575,0.175,0.1683693,0.33673862 +0.575,0.17500001,0.3367386,0.16836931 +0.575,0.22500001,0.14999998,0.15 +0.57500005,0.225,0.10606605,0.21213202 +0.575,0.22500001,0.21213207,0.10606602 +0.575,0.225,0.18898809,0.18898815 +0.57500005,0.225,0.13363487,0.2672696 +0.575,0.225,0.2672696,0.1336348 +0.575,0.225,0.23811015,0.23811017 +0.575,0.22500001,0.1683693,0.33673862 +0.575,0.225,0.3367386,0.1683693 +0.575,0.275,0.14999998,0.14999999 +0.57500005,0.275,0.10606605,0.21213204 +0.575,0.275,0.21213207,0.10606605 +0.575,0.275,0.18898809,0.18898816 +0.57500005,0.275,0.13363487,0.2672696 +0.575,0.275,0.2672696,0.1336348 +0.575,0.27499998,0.23811015,0.23811015 +0.575,0.275,0.1683693,0.3367386 +0.575,0.275,0.3367386,0.16836931 +0.575,0.325,0.14999998,0.15 +0.57500005,0.32500002,0.10606605,0.21213205 +0.575,0.325,0.21213207,0.10606602 +0.575,0.325,0.18898809,0.18898815 +0.57500005,0.325,0.13363487,0.2672696 +0.575,0.325,0.2672696,0.1336348 +0.575,0.325,0.23811015,0.23811015 +0.575,0.325,0.1683693,0.3367386 +0.575,0.325,0.3367386,0.16836928 +0.575,0.375,0.14999998,0.14999998 +0.57500005,0.375,0.10606605,0.21213207 +0.575,0.375,0.21213207,0.10606605 +0.575,0.375,0.18898809,0.18898812 +0.57500005,0.375,0.13363487,0.2672696 +0.575,0.375,0.2672696,0.13363484 +0.575,0.375,0.23811015,0.23811018 +0.575,0.375,0.1683693,0.33673862 +0.575,0.375,0.3367386,0.1683693 +0.575,0.425,0.14999998,0.15 +0.57500005,0.425,0.10606605,0.21213207 +0.575,0.425,0.21213207,0.10606602 +0.575,0.42499998,0.18898809,0.18898815 +0.57500005,0.425,0.13363487,0.2672696 +0.575,0.425,0.2672696,0.1336348 +0.575,0.425,0.23811015,0.23811018 +0.575,0.425,0.1683693,0.33673862 +0.575,0.425,0.3367386,0.1683693 +0.575,0.47500002,0.14999998,0.15 +0.57500005,0.475,0.10606605,0.21213204 +0.575,0.475,0.21213207,0.10606605 +0.575,0.475,0.18898809,0.18898815 +0.57500005,0.47500002,0.13363487,0.26726964 +0.575,0.475,0.2672696,0.13363487 +0.575,0.475,0.23811015,0.23811013 +0.575,0.475,0.1683693,0.33673865 +0.575,0.47500002,0.3367386,0.16836932 +0.575,0.525,0.14999998,0.15000004 +0.57500005,0.525,0.10606605,0.21213207 +0.575,0.525,0.21213207,0.10606605 +0.575,0.525,0.18898809,0.18898815 +0.57500005,0.525,0.13363487,0.26726958 +0.575,0.525,0.2672696,0.13363487 +0.575,0.525,0.23811015,0.23811015 +0.575,0.525,0.1683693,0.3367386 +0.575,0.525,0.3367386,0.16836926 +0.575,0.575,0.14999998,0.14999998 +0.57500005,0.575,0.10606605,0.21213207 +0.575,0.57500005,0.21213207,0.10606605 +0.575,0.575,0.18898809,0.18898809 +0.57500005,0.575,0.13363487,0.2672696 +0.575,0.57500005,0.2672696,0.13363487 +0.575,0.575,0.23811015,0.23811015 +0.575,0.575,0.1683693,0.3367386 +0.575,0.575,0.3367386,0.1683693 +0.575,0.625,0.14999998,0.14999998 +0.57500005,0.625,0.10606605,0.2121321 +0.575,0.625,0.21213207,0.10606599 +0.575,0.625,0.18898809,0.18898809 +0.57500005,0.625,0.13363487,0.2672696 +0.575,0.625,0.2672696,0.1336348 +0.575,0.625,0.23811015,0.23811018 +0.575,0.625,0.1683693,0.3367386 +0.575,0.625,0.3367386,0.1683693 +0.575,0.675,0.14999998,0.14999998 +0.57500005,0.675,0.10606605,0.2121321 +0.575,0.67499995,0.21213207,0.10606605 +0.575,0.675,0.18898809,0.18898809 +0.57500005,0.6750001,0.13363487,0.26726967 +0.575,0.67499995,0.2672696,0.13363487 +0.575,0.675,0.23811015,0.23811018 +0.575,0.675,0.1683693,0.3367386 +0.575,0.675,0.3367386,0.1683693 +0.575,0.725,0.14999998,0.15000004 +0.57500005,0.725,0.10606605,0.21213204 +0.575,0.725,0.21213207,0.10606605 +0.575,0.725,0.18898809,0.18898815 +0.57500005,0.725,0.13363487,0.2672696 +0.575,0.725,0.2672696,0.13363487 +0.575,0.725,0.23811015,0.23811013 +0.575,0.725,0.1683693,0.3367386 +0.575,0.725,0.3367386,0.1683693 +0.575,0.775,0.14999998,0.15000004 +0.57500005,0.775,0.10606605,0.21213204 +0.575,0.775,0.21213207,0.10606599 +0.575,0.775,0.18898809,0.18898815 +0.57500005,0.775,0.13363487,0.26726967 +0.575,0.775,0.2672696,0.1336348 +0.575,0.775,0.23811015,0.23811013 +0.575,0.775,0.1683693,0.3367386 +0.575,0.775,0.3367386,0.1683693 +0.575,0.825,0.14999998,0.14999998 +0.57500005,0.825,0.10606605,0.2121321 +0.575,0.825,0.21213207,0.10606599 +0.575,0.825,0.18898809,0.18898809 +0.57500005,0.82500005,0.13363487,0.26726967 +0.575,0.825,0.2672696,0.1336348 +0.575,0.825,0.23811015,0.23811018 +0.575,0.825,0.1683693,0.3367386 +0.575,0.825,0.3367386,0.1683693 +0.575,0.875,0.14999998,0.14999998 +0.57500005,0.875,0.10606605,0.2121321 +0.575,0.875,0.21213207,0.10606599 +0.575,0.875,0.18898809,0.18898809 +0.57500005,0.875,0.13363487,0.2672696 +0.575,0.875,0.2672696,0.1336348 +0.575,0.875,0.23811015,0.23811018 +0.575,0.875,0.1683693,0.3367386 +0.575,0.875,0.3367386,0.1683693 +0.575,0.925,0.14999998,0.14999998 +0.57500005,0.925,0.10606605,0.2121321 +0.575,0.92499995,0.21213207,0.10606593 +0.575,0.925,0.18898809,0.18898809 +0.57500005,0.9250001,0.13363487,0.26726967 +0.575,0.92499995,0.2672696,0.13363475 +0.575,0.925,0.23811015,0.23811018 +0.575,0.92499995,0.1683693,0.33673853 +0.575,0.92499995,0.3367386,0.16836923 +0.575,0.97499996,0.14999998,0.14999998 +0.57500005,0.975,0.10606605,0.21213204 +0.575,0.975,0.21213207,0.10606599 +0.575,0.97499996,0.18898809,0.18898809 +0.57500005,0.975,0.13363487,0.26726967 +0.575,0.975,0.2672696,0.1336348 +0.575,0.975,0.23811015,0.23811013 +0.575,0.975,0.1683693,0.3367386 +0.575,0.975,0.3367386,0.1683693 +0.625,0.025,0.14999998,0.15 +0.625,0.024999995,0.10606599,0.21213204 +0.625,0.024999999,0.2121321,0.10606602 +0.625,0.024999999,0.18898809,0.18898816 +0.625,0.025000002,0.1336348,0.2672696 +0.625,0.024999999,0.2672696,0.1336348 +0.625,0.025000002,0.23811018,0.23811015 +0.625,0.024999999,0.1683693,0.3367386 +0.625,0.025000004,0.3367386,0.16836931 +0.625,0.075,0.14999998,0.15 +0.625,0.074999996,0.10606599,0.21213202 +0.625,0.075,0.2121321,0.10606602 +0.625,0.075,0.18898809,0.18898815 +0.625,0.075,0.1336348,0.2672696 +0.625,0.075,0.2672696,0.1336348 +0.625,0.075,0.23811018,0.23811015 +0.625,0.075,0.1683693,0.33673862 +0.625,0.075,0.3367386,0.16836932 +0.625,0.125,0.14999998,0.15 +0.625,0.125,0.10606599,0.21213204 +0.625,0.125,0.2121321,0.10606602 +0.625,0.125,0.18898809,0.18898815 +0.625,0.125,0.1336348,0.2672696 +0.625,0.125,0.2672696,0.1336348 +0.625,0.125,0.23811018,0.23811015 +0.625,0.125,0.1683693,0.33673865 +0.625,0.125,0.3367386,0.1683693 +0.625,0.175,0.14999998,0.15 +0.625,0.17499998,0.10606599,0.21213202 +0.625,0.17500001,0.2121321,0.106066026 +0.625,0.17500001,0.18898809,0.18898816 +0.625,0.17500001,0.1336348,0.2672696 +0.625,0.175,0.2672696,0.1336348 +0.625,0.175,0.23811018,0.23811015 +0.625,0.175,0.1683693,0.33673862 +0.625,0.17500001,0.3367386,0.16836931 +0.625,0.22500001,0.14999998,0.15 +0.625,0.225,0.10606599,0.21213202 +0.625,0.22500001,0.2121321,0.10606602 +0.625,0.225,0.18898809,0.18898815 +0.625,0.225,0.1336348,0.2672696 +0.625,0.225,0.2672696,0.1336348 +0.625,0.225,0.23811018,0.23811017 +0.625,0.22500001,0.1683693,0.33673862 +0.625,0.225,0.3367386,0.1683693 +0.625,0.275,0.14999998,0.14999999 +0.625,0.275,0.10606599,0.21213204 +0.625,0.275,0.2121321,0.10606605 +0.625,0.275,0.18898809,0.18898816 +0.625,0.275,0.1336348,0.2672696 +0.625,0.275,0.2672696,0.1336348 +0.625,0.27499998,0.23811018,0.23811015 +0.625,0.275,0.1683693,0.3367386 +0.625,0.275,0.3367386,0.16836931 +0.625,0.325,0.14999998,0.15 +0.625,0.32500002,0.10606599,0.21213205 +0.625,0.325,0.2121321,0.10606602 +0.625,0.325,0.18898809,0.18898815 +0.625,0.325,0.1336348,0.2672696 +0.625,0.325,0.2672696,0.1336348 +0.625,0.325,0.23811018,0.23811015 +0.625,0.325,0.1683693,0.3367386 +0.625,0.325,0.3367386,0.16836928 +0.625,0.375,0.14999998,0.14999998 +0.625,0.375,0.10606599,0.21213207 +0.625,0.375,0.2121321,0.10606605 +0.625,0.375,0.18898809,0.18898812 +0.625,0.375,0.1336348,0.2672696 +0.625,0.375,0.2672696,0.13363484 +0.625,0.375,0.23811018,0.23811018 +0.625,0.375,0.1683693,0.33673862 +0.625,0.375,0.3367386,0.1683693 +0.625,0.425,0.14999998,0.15 +0.625,0.425,0.10606599,0.21213207 +0.625,0.425,0.2121321,0.10606602 +0.625,0.42499998,0.18898809,0.18898815 +0.625,0.425,0.1336348,0.2672696 +0.625,0.425,0.2672696,0.1336348 +0.625,0.425,0.23811018,0.23811018 +0.625,0.425,0.1683693,0.33673862 +0.625,0.425,0.3367386,0.1683693 +0.625,0.47500002,0.14999998,0.15 +0.625,0.475,0.10606599,0.21213204 +0.625,0.475,0.2121321,0.10606605 +0.625,0.475,0.18898809,0.18898815 +0.625,0.47500002,0.1336348,0.26726964 +0.625,0.475,0.2672696,0.13363487 +0.625,0.475,0.23811018,0.23811013 +0.625,0.475,0.1683693,0.33673865 +0.625,0.47500002,0.3367386,0.16836932 +0.625,0.525,0.14999998,0.15000004 +0.625,0.525,0.10606599,0.21213207 +0.625,0.525,0.2121321,0.10606605 +0.625,0.525,0.18898809,0.18898815 +0.625,0.525,0.1336348,0.26726958 +0.625,0.525,0.2672696,0.13363487 +0.625,0.525,0.23811018,0.23811015 +0.625,0.525,0.1683693,0.3367386 +0.625,0.525,0.3367386,0.16836926 +0.625,0.575,0.14999998,0.14999998 +0.625,0.575,0.10606599,0.21213207 +0.625,0.57500005,0.2121321,0.10606605 +0.625,0.575,0.18898809,0.18898809 +0.625,0.575,0.1336348,0.2672696 +0.625,0.57500005,0.2672696,0.13363487 +0.625,0.575,0.23811018,0.23811015 +0.625,0.575,0.1683693,0.3367386 +0.625,0.575,0.3367386,0.1683693 +0.625,0.625,0.14999998,0.14999998 +0.625,0.625,0.10606599,0.2121321 +0.625,0.625,0.2121321,0.10606599 +0.625,0.625,0.18898809,0.18898809 +0.625,0.625,0.1336348,0.2672696 +0.625,0.625,0.2672696,0.1336348 +0.625,0.625,0.23811018,0.23811018 +0.625,0.625,0.1683693,0.3367386 +0.625,0.625,0.3367386,0.1683693 +0.625,0.675,0.14999998,0.14999998 +0.625,0.675,0.10606599,0.2121321 +0.625,0.67499995,0.2121321,0.10606605 +0.625,0.675,0.18898809,0.18898809 +0.625,0.6750001,0.1336348,0.26726967 +0.625,0.67499995,0.2672696,0.13363487 +0.625,0.675,0.23811018,0.23811018 +0.625,0.675,0.1683693,0.3367386 +0.625,0.675,0.3367386,0.1683693 +0.625,0.725,0.14999998,0.15000004 +0.625,0.725,0.10606599,0.21213204 +0.625,0.725,0.2121321,0.10606605 +0.625,0.725,0.18898809,0.18898815 +0.625,0.725,0.1336348,0.2672696 +0.625,0.725,0.2672696,0.13363487 +0.625,0.725,0.23811018,0.23811013 +0.625,0.725,0.1683693,0.3367386 +0.625,0.725,0.3367386,0.1683693 +0.625,0.775,0.14999998,0.15000004 +0.625,0.775,0.10606599,0.21213204 +0.625,0.775,0.2121321,0.10606599 +0.625,0.775,0.18898809,0.18898815 +0.625,0.775,0.1336348,0.26726967 +0.625,0.775,0.2672696,0.1336348 +0.625,0.775,0.23811018,0.23811013 +0.625,0.775,0.1683693,0.3367386 +0.625,0.775,0.3367386,0.1683693 +0.625,0.825,0.14999998,0.14999998 +0.625,0.825,0.10606599,0.2121321 +0.625,0.825,0.2121321,0.10606599 +0.625,0.825,0.18898809,0.18898809 +0.625,0.82500005,0.1336348,0.26726967 +0.625,0.825,0.2672696,0.1336348 +0.625,0.825,0.23811018,0.23811018 +0.625,0.825,0.1683693,0.3367386 +0.625,0.825,0.3367386,0.1683693 +0.625,0.875,0.14999998,0.14999998 +0.625,0.875,0.10606599,0.2121321 +0.625,0.875,0.2121321,0.10606599 +0.625,0.875,0.18898809,0.18898809 +0.625,0.875,0.1336348,0.2672696 +0.625,0.875,0.2672696,0.1336348 +0.625,0.875,0.23811018,0.23811018 +0.625,0.875,0.1683693,0.3367386 +0.625,0.875,0.3367386,0.1683693 +0.625,0.925,0.14999998,0.14999998 +0.625,0.925,0.10606599,0.2121321 +0.625,0.92499995,0.2121321,0.10606593 +0.625,0.925,0.18898809,0.18898809 +0.625,0.9250001,0.1336348,0.26726967 +0.625,0.92499995,0.2672696,0.13363475 +0.625,0.925,0.23811018,0.23811018 +0.625,0.92499995,0.1683693,0.33673853 +0.625,0.92499995,0.3367386,0.16836923 +0.625,0.97499996,0.14999998,0.14999998 +0.625,0.975,0.10606599,0.21213204 +0.625,0.975,0.2121321,0.10606599 +0.625,0.97499996,0.18898809,0.18898809 +0.625,0.975,0.1336348,0.26726967 +0.625,0.975,0.2672696,0.1336348 +0.625,0.975,0.23811018,0.23811013 +0.625,0.975,0.1683693,0.3367386 +0.625,0.975,0.3367386,0.1683693 +0.675,0.025,0.14999998,0.15 +0.67499995,0.024999995,0.10606605,0.21213204 +0.675,0.024999999,0.2121321,0.10606602 +0.675,0.024999999,0.18898809,0.18898816 +0.67499995,0.025000002,0.13363487,0.2672696 +0.6750001,0.024999999,0.26726967,0.1336348 +0.675,0.025000002,0.23811018,0.23811015 +0.675,0.024999999,0.1683693,0.3367386 +0.675,0.025000004,0.3367386,0.16836931 +0.675,0.075,0.14999998,0.15 +0.67499995,0.074999996,0.10606605,0.21213202 +0.675,0.075,0.2121321,0.10606602 +0.675,0.075,0.18898809,0.18898815 +0.67499995,0.075,0.13363487,0.2672696 +0.6750001,0.075,0.26726967,0.1336348 +0.675,0.075,0.23811018,0.23811015 +0.675,0.075,0.1683693,0.33673862 +0.675,0.075,0.3367386,0.16836932 +0.675,0.125,0.14999998,0.15 +0.67499995,0.125,0.10606605,0.21213204 +0.675,0.125,0.2121321,0.10606602 +0.675,0.125,0.18898809,0.18898815 +0.67499995,0.125,0.13363487,0.2672696 +0.6750001,0.125,0.26726967,0.1336348 +0.675,0.125,0.23811018,0.23811015 +0.675,0.125,0.1683693,0.33673865 +0.675,0.125,0.3367386,0.1683693 +0.675,0.175,0.14999998,0.15 +0.67499995,0.17499998,0.10606605,0.21213202 +0.675,0.17500001,0.2121321,0.106066026 +0.675,0.17500001,0.18898809,0.18898816 +0.67499995,0.17500001,0.13363487,0.2672696 +0.6750001,0.175,0.26726967,0.1336348 +0.675,0.175,0.23811018,0.23811015 +0.675,0.175,0.1683693,0.33673862 +0.675,0.17500001,0.3367386,0.16836931 +0.675,0.22500001,0.14999998,0.15 +0.67499995,0.225,0.10606605,0.21213202 +0.675,0.22500001,0.2121321,0.10606602 +0.675,0.225,0.18898809,0.18898815 +0.67499995,0.225,0.13363487,0.2672696 +0.6750001,0.225,0.26726967,0.1336348 +0.675,0.225,0.23811018,0.23811017 +0.675,0.22500001,0.1683693,0.33673862 +0.675,0.225,0.3367386,0.1683693 +0.675,0.275,0.14999998,0.14999999 +0.67499995,0.275,0.10606605,0.21213204 +0.675,0.275,0.2121321,0.10606605 +0.675,0.275,0.18898809,0.18898816 +0.67499995,0.275,0.13363487,0.2672696 +0.6750001,0.275,0.26726967,0.1336348 +0.675,0.27499998,0.23811018,0.23811015 +0.675,0.275,0.1683693,0.3367386 +0.675,0.275,0.3367386,0.16836931 +0.675,0.325,0.14999998,0.15 +0.67499995,0.32500002,0.10606605,0.21213205 +0.675,0.325,0.2121321,0.10606602 +0.675,0.325,0.18898809,0.18898815 +0.67499995,0.325,0.13363487,0.2672696 +0.6750001,0.325,0.26726967,0.1336348 +0.675,0.325,0.23811018,0.23811015 +0.675,0.325,0.1683693,0.3367386 +0.675,0.325,0.3367386,0.16836928 +0.675,0.375,0.14999998,0.14999998 +0.67499995,0.375,0.10606605,0.21213207 +0.675,0.375,0.2121321,0.10606605 +0.675,0.375,0.18898809,0.18898812 +0.67499995,0.375,0.13363487,0.2672696 +0.6750001,0.375,0.26726967,0.13363484 +0.675,0.375,0.23811018,0.23811018 +0.675,0.375,0.1683693,0.33673862 +0.675,0.375,0.3367386,0.1683693 +0.675,0.425,0.14999998,0.15 +0.67499995,0.425,0.10606605,0.21213207 +0.675,0.425,0.2121321,0.10606602 +0.675,0.42499998,0.18898809,0.18898815 +0.67499995,0.425,0.13363487,0.2672696 +0.6750001,0.425,0.26726967,0.1336348 +0.675,0.425,0.23811018,0.23811018 +0.675,0.425,0.1683693,0.33673862 +0.675,0.425,0.3367386,0.1683693 +0.675,0.47500002,0.14999998,0.15 +0.67499995,0.475,0.10606605,0.21213204 +0.675,0.475,0.2121321,0.10606605 +0.675,0.475,0.18898809,0.18898815 +0.67499995,0.47500002,0.13363487,0.26726964 +0.6750001,0.475,0.26726967,0.13363487 +0.675,0.475,0.23811018,0.23811013 +0.675,0.475,0.1683693,0.33673865 +0.675,0.47500002,0.3367386,0.16836932 +0.675,0.525,0.14999998,0.15000004 +0.67499995,0.525,0.10606605,0.21213207 +0.675,0.525,0.2121321,0.10606605 +0.675,0.525,0.18898809,0.18898815 +0.67499995,0.525,0.13363487,0.26726958 +0.6750001,0.525,0.26726967,0.13363487 +0.675,0.525,0.23811018,0.23811015 +0.675,0.525,0.1683693,0.3367386 +0.675,0.525,0.3367386,0.16836926 +0.675,0.575,0.14999998,0.14999998 +0.67499995,0.575,0.10606605,0.21213207 +0.675,0.57500005,0.2121321,0.10606605 +0.675,0.575,0.18898809,0.18898809 +0.67499995,0.575,0.13363487,0.2672696 +0.6750001,0.57500005,0.26726967,0.13363487 +0.675,0.575,0.23811018,0.23811015 +0.675,0.575,0.1683693,0.3367386 +0.675,0.575,0.3367386,0.1683693 +0.675,0.625,0.14999998,0.14999998 +0.67499995,0.625,0.10606605,0.2121321 +0.675,0.625,0.2121321,0.10606599 +0.675,0.625,0.18898809,0.18898809 +0.67499995,0.625,0.13363487,0.2672696 +0.6750001,0.625,0.26726967,0.1336348 +0.675,0.625,0.23811018,0.23811018 +0.675,0.625,0.1683693,0.3367386 +0.675,0.625,0.3367386,0.1683693 +0.675,0.675,0.14999998,0.14999998 +0.67499995,0.675,0.10606605,0.2121321 +0.675,0.67499995,0.2121321,0.10606605 +0.675,0.675,0.18898809,0.18898809 +0.67499995,0.6750001,0.13363487,0.26726967 +0.6750001,0.67499995,0.26726967,0.13363487 +0.675,0.675,0.23811018,0.23811018 +0.675,0.675,0.1683693,0.3367386 +0.675,0.675,0.3367386,0.1683693 +0.675,0.725,0.14999998,0.15000004 +0.67499995,0.725,0.10606605,0.21213204 +0.675,0.725,0.2121321,0.10606605 +0.675,0.725,0.18898809,0.18898815 +0.67499995,0.725,0.13363487,0.2672696 +0.6750001,0.725,0.26726967,0.13363487 +0.675,0.725,0.23811018,0.23811013 +0.675,0.725,0.1683693,0.3367386 +0.675,0.725,0.3367386,0.1683693 +0.675,0.775,0.14999998,0.15000004 +0.67499995,0.775,0.10606605,0.21213204 +0.675,0.775,0.2121321,0.10606599 +0.675,0.775,0.18898809,0.18898815 +0.67499995,0.775,0.13363487,0.26726967 +0.6750001,0.775,0.26726967,0.1336348 +0.675,0.775,0.23811018,0.23811013 +0.675,0.775,0.1683693,0.3367386 +0.675,0.775,0.3367386,0.1683693 +0.675,0.825,0.14999998,0.14999998 +0.67499995,0.825,0.10606605,0.2121321 +0.675,0.825,0.2121321,0.10606599 +0.675,0.825,0.18898809,0.18898809 +0.67499995,0.82500005,0.13363487,0.26726967 +0.6750001,0.825,0.26726967,0.1336348 +0.675,0.825,0.23811018,0.23811018 +0.675,0.825,0.1683693,0.3367386 +0.675,0.825,0.3367386,0.1683693 +0.675,0.875,0.14999998,0.14999998 +0.67499995,0.875,0.10606605,0.2121321 +0.675,0.875,0.2121321,0.10606599 +0.675,0.875,0.18898809,0.18898809 +0.67499995,0.875,0.13363487,0.2672696 +0.6750001,0.875,0.26726967,0.1336348 +0.675,0.875,0.23811018,0.23811018 +0.675,0.875,0.1683693,0.3367386 +0.675,0.875,0.3367386,0.1683693 +0.675,0.925,0.14999998,0.14999998 +0.67499995,0.925,0.10606605,0.2121321 +0.675,0.92499995,0.2121321,0.10606593 +0.675,0.925,0.18898809,0.18898809 +0.67499995,0.9250001,0.13363487,0.26726967 +0.6750001,0.92499995,0.26726967,0.13363475 +0.675,0.925,0.23811018,0.23811018 +0.675,0.92499995,0.1683693,0.33673853 +0.675,0.92499995,0.3367386,0.16836923 +0.675,0.97499996,0.14999998,0.14999998 +0.67499995,0.975,0.10606605,0.21213204 +0.675,0.975,0.2121321,0.10606599 +0.675,0.97499996,0.18898809,0.18898809 +0.67499995,0.975,0.13363487,0.26726967 +0.6750001,0.975,0.26726967,0.1336348 +0.675,0.975,0.23811018,0.23811013 +0.675,0.975,0.1683693,0.3367386 +0.675,0.975,0.3367386,0.1683693 +0.725,0.025,0.15000004,0.15 +0.725,0.024999995,0.10606605,0.21213204 +0.725,0.024999999,0.21213204,0.10606602 +0.725,0.024999999,0.18898815,0.18898816 +0.725,0.025000002,0.13363487,0.2672696 +0.725,0.024999999,0.2672696,0.1336348 +0.725,0.025000002,0.23811013,0.23811015 +0.725,0.024999999,0.1683693,0.3367386 +0.725,0.025000004,0.3367386,0.16836931 +0.725,0.075,0.15000004,0.15 +0.725,0.074999996,0.10606605,0.21213202 +0.725,0.075,0.21213204,0.10606602 +0.725,0.075,0.18898815,0.18898815 +0.725,0.075,0.13363487,0.2672696 +0.725,0.075,0.2672696,0.1336348 +0.725,0.075,0.23811013,0.23811015 +0.725,0.075,0.1683693,0.33673862 +0.725,0.075,0.3367386,0.16836932 +0.725,0.125,0.15000004,0.15 +0.725,0.125,0.10606605,0.21213204 +0.725,0.125,0.21213204,0.10606602 +0.725,0.125,0.18898815,0.18898815 +0.725,0.125,0.13363487,0.2672696 +0.725,0.125,0.2672696,0.1336348 +0.725,0.125,0.23811013,0.23811015 +0.725,0.125,0.1683693,0.33673865 +0.725,0.125,0.3367386,0.1683693 +0.725,0.175,0.15000004,0.15 +0.725,0.17499998,0.10606605,0.21213202 +0.725,0.17500001,0.21213204,0.106066026 +0.725,0.17500001,0.18898815,0.18898816 +0.725,0.17500001,0.13363487,0.2672696 +0.725,0.175,0.2672696,0.1336348 +0.725,0.175,0.23811013,0.23811015 +0.725,0.175,0.1683693,0.33673862 +0.725,0.17500001,0.3367386,0.16836931 +0.725,0.22500001,0.15000004,0.15 +0.725,0.225,0.10606605,0.21213202 +0.725,0.22500001,0.21213204,0.10606602 +0.725,0.225,0.18898815,0.18898815 +0.725,0.225,0.13363487,0.2672696 +0.725,0.225,0.2672696,0.1336348 +0.725,0.225,0.23811013,0.23811017 +0.725,0.22500001,0.1683693,0.33673862 +0.725,0.225,0.3367386,0.1683693 +0.725,0.275,0.15000004,0.14999999 +0.725,0.275,0.10606605,0.21213204 +0.725,0.275,0.21213204,0.10606605 +0.725,0.275,0.18898815,0.18898816 +0.725,0.275,0.13363487,0.2672696 +0.725,0.275,0.2672696,0.1336348 +0.725,0.27499998,0.23811013,0.23811015 +0.725,0.275,0.1683693,0.3367386 +0.725,0.275,0.3367386,0.16836931 +0.725,0.325,0.15000004,0.15 +0.725,0.32500002,0.10606605,0.21213205 +0.725,0.325,0.21213204,0.10606602 +0.725,0.325,0.18898815,0.18898815 +0.725,0.325,0.13363487,0.2672696 +0.725,0.325,0.2672696,0.1336348 +0.725,0.325,0.23811013,0.23811015 +0.725,0.325,0.1683693,0.3367386 +0.725,0.325,0.3367386,0.16836928 +0.725,0.375,0.15000004,0.14999998 +0.725,0.375,0.10606605,0.21213207 +0.725,0.375,0.21213204,0.10606605 +0.725,0.375,0.18898815,0.18898812 +0.725,0.375,0.13363487,0.2672696 +0.725,0.375,0.2672696,0.13363484 +0.725,0.375,0.23811013,0.23811018 +0.725,0.375,0.1683693,0.33673862 +0.725,0.375,0.3367386,0.1683693 +0.725,0.425,0.15000004,0.15 +0.725,0.425,0.10606605,0.21213207 +0.725,0.425,0.21213204,0.10606602 +0.725,0.42499998,0.18898815,0.18898815 +0.725,0.425,0.13363487,0.2672696 +0.725,0.425,0.2672696,0.1336348 +0.725,0.425,0.23811013,0.23811018 +0.725,0.425,0.1683693,0.33673862 +0.725,0.425,0.3367386,0.1683693 +0.725,0.47500002,0.15000004,0.15 +0.725,0.475,0.10606605,0.21213204 +0.725,0.475,0.21213204,0.10606605 +0.725,0.475,0.18898815,0.18898815 +0.725,0.47500002,0.13363487,0.26726964 +0.725,0.475,0.2672696,0.13363487 +0.725,0.475,0.23811013,0.23811013 +0.725,0.475,0.1683693,0.33673865 +0.725,0.47500002,0.3367386,0.16836932 +0.725,0.525,0.15000004,0.15000004 +0.725,0.525,0.10606605,0.21213207 +0.725,0.525,0.21213204,0.10606605 +0.725,0.525,0.18898815,0.18898815 +0.725,0.525,0.13363487,0.26726958 +0.725,0.525,0.2672696,0.13363487 +0.725,0.525,0.23811013,0.23811015 +0.725,0.525,0.1683693,0.3367386 +0.725,0.525,0.3367386,0.16836926 +0.725,0.575,0.15000004,0.14999998 +0.725,0.575,0.10606605,0.21213207 +0.725,0.57500005,0.21213204,0.10606605 +0.725,0.575,0.18898815,0.18898809 +0.725,0.575,0.13363487,0.2672696 +0.725,0.57500005,0.2672696,0.13363487 +0.725,0.575,0.23811013,0.23811015 +0.725,0.575,0.1683693,0.3367386 +0.725,0.575,0.3367386,0.1683693 +0.725,0.625,0.15000004,0.14999998 +0.725,0.625,0.10606605,0.2121321 +0.725,0.625,0.21213204,0.10606599 +0.725,0.625,0.18898815,0.18898809 +0.725,0.625,0.13363487,0.2672696 +0.725,0.625,0.2672696,0.1336348 +0.725,0.625,0.23811013,0.23811018 +0.725,0.625,0.1683693,0.3367386 +0.725,0.625,0.3367386,0.1683693 +0.725,0.675,0.15000004,0.14999998 +0.725,0.675,0.10606605,0.2121321 +0.725,0.67499995,0.21213204,0.10606605 +0.725,0.675,0.18898815,0.18898809 +0.725,0.6750001,0.13363487,0.26726967 +0.725,0.67499995,0.2672696,0.13363487 +0.725,0.675,0.23811013,0.23811018 +0.725,0.675,0.1683693,0.3367386 +0.725,0.675,0.3367386,0.1683693 +0.725,0.725,0.15000004,0.15000004 +0.725,0.725,0.10606605,0.21213204 +0.725,0.725,0.21213204,0.10606605 +0.725,0.725,0.18898815,0.18898815 +0.725,0.725,0.13363487,0.2672696 +0.725,0.725,0.2672696,0.13363487 +0.725,0.725,0.23811013,0.23811013 +0.725,0.725,0.1683693,0.3367386 +0.725,0.725,0.3367386,0.1683693 +0.725,0.775,0.15000004,0.15000004 +0.725,0.775,0.10606605,0.21213204 +0.725,0.775,0.21213204,0.10606599 +0.725,0.775,0.18898815,0.18898815 +0.725,0.775,0.13363487,0.26726967 +0.725,0.775,0.2672696,0.1336348 +0.725,0.775,0.23811013,0.23811013 +0.725,0.775,0.1683693,0.3367386 +0.725,0.775,0.3367386,0.1683693 +0.725,0.825,0.15000004,0.14999998 +0.725,0.825,0.10606605,0.2121321 +0.725,0.825,0.21213204,0.10606599 +0.725,0.825,0.18898815,0.18898809 +0.725,0.82500005,0.13363487,0.26726967 +0.725,0.825,0.2672696,0.1336348 +0.725,0.825,0.23811013,0.23811018 +0.725,0.825,0.1683693,0.3367386 +0.725,0.825,0.3367386,0.1683693 +0.725,0.875,0.15000004,0.14999998 +0.725,0.875,0.10606605,0.2121321 +0.725,0.875,0.21213204,0.10606599 +0.725,0.875,0.18898815,0.18898809 +0.725,0.875,0.13363487,0.2672696 +0.725,0.875,0.2672696,0.1336348 +0.725,0.875,0.23811013,0.23811018 +0.725,0.875,0.1683693,0.3367386 +0.725,0.875,0.3367386,0.1683693 +0.725,0.925,0.15000004,0.14999998 +0.725,0.925,0.10606605,0.2121321 +0.725,0.92499995,0.21213204,0.10606593 +0.725,0.925,0.18898815,0.18898809 +0.725,0.9250001,0.13363487,0.26726967 +0.725,0.92499995,0.2672696,0.13363475 +0.725,0.925,0.23811013,0.23811018 +0.725,0.92499995,0.1683693,0.33673853 +0.725,0.92499995,0.3367386,0.16836923 +0.725,0.97499996,0.15000004,0.14999998 +0.725,0.975,0.10606605,0.21213204 +0.725,0.975,0.21213204,0.10606599 +0.725,0.97499996,0.18898815,0.18898809 +0.725,0.975,0.13363487,0.26726967 +0.725,0.975,0.2672696,0.1336348 +0.725,0.975,0.23811013,0.23811013 +0.725,0.975,0.1683693,0.3367386 +0.725,0.975,0.3367386,0.1683693 +0.775,0.025,0.15000004,0.15 +0.775,0.024999995,0.10606599,0.21213204 +0.775,0.024999999,0.21213204,0.10606602 +0.775,0.024999999,0.18898815,0.18898816 +0.775,0.025000002,0.1336348,0.2672696 +0.775,0.024999999,0.26726967,0.1336348 +0.775,0.025000002,0.23811013,0.23811015 +0.775,0.024999999,0.1683693,0.3367386 +0.775,0.025000004,0.3367386,0.16836931 +0.775,0.075,0.15000004,0.15 +0.775,0.074999996,0.10606599,0.21213202 +0.775,0.075,0.21213204,0.10606602 +0.775,0.075,0.18898815,0.18898815 +0.775,0.075,0.1336348,0.2672696 +0.775,0.075,0.26726967,0.1336348 +0.775,0.075,0.23811013,0.23811015 +0.775,0.075,0.1683693,0.33673862 +0.775,0.075,0.3367386,0.16836932 +0.775,0.125,0.15000004,0.15 +0.775,0.125,0.10606599,0.21213204 +0.775,0.125,0.21213204,0.10606602 +0.775,0.125,0.18898815,0.18898815 +0.775,0.125,0.1336348,0.2672696 +0.775,0.125,0.26726967,0.1336348 +0.775,0.125,0.23811013,0.23811015 +0.775,0.125,0.1683693,0.33673865 +0.775,0.125,0.3367386,0.1683693 +0.775,0.175,0.15000004,0.15 +0.775,0.17499998,0.10606599,0.21213202 +0.775,0.17500001,0.21213204,0.106066026 +0.775,0.17500001,0.18898815,0.18898816 +0.775,0.17500001,0.1336348,0.2672696 +0.775,0.175,0.26726967,0.1336348 +0.775,0.175,0.23811013,0.23811015 +0.775,0.175,0.1683693,0.33673862 +0.775,0.17500001,0.3367386,0.16836931 +0.775,0.22500001,0.15000004,0.15 +0.775,0.225,0.10606599,0.21213202 +0.775,0.22500001,0.21213204,0.10606602 +0.775,0.225,0.18898815,0.18898815 +0.775,0.225,0.1336348,0.2672696 +0.775,0.225,0.26726967,0.1336348 +0.775,0.225,0.23811013,0.23811017 +0.775,0.22500001,0.1683693,0.33673862 +0.775,0.225,0.3367386,0.1683693 +0.775,0.275,0.15000004,0.14999999 +0.775,0.275,0.10606599,0.21213204 +0.775,0.275,0.21213204,0.10606605 +0.775,0.275,0.18898815,0.18898816 +0.775,0.275,0.1336348,0.2672696 +0.775,0.275,0.26726967,0.1336348 +0.775,0.27499998,0.23811013,0.23811015 +0.775,0.275,0.1683693,0.3367386 +0.775,0.275,0.3367386,0.16836931 +0.775,0.325,0.15000004,0.15 +0.775,0.32500002,0.10606599,0.21213205 +0.775,0.325,0.21213204,0.10606602 +0.775,0.325,0.18898815,0.18898815 +0.775,0.325,0.1336348,0.2672696 +0.775,0.325,0.26726967,0.1336348 +0.775,0.325,0.23811013,0.23811015 +0.775,0.325,0.1683693,0.3367386 +0.775,0.325,0.3367386,0.16836928 +0.775,0.375,0.15000004,0.14999998 +0.775,0.375,0.10606599,0.21213207 +0.775,0.375,0.21213204,0.10606605 +0.775,0.375,0.18898815,0.18898812 +0.775,0.375,0.1336348,0.2672696 +0.775,0.375,0.26726967,0.13363484 +0.775,0.375,0.23811013,0.23811018 +0.775,0.375,0.1683693,0.33673862 +0.775,0.375,0.3367386,0.1683693 +0.775,0.425,0.15000004,0.15 +0.775,0.425,0.10606599,0.21213207 +0.775,0.425,0.21213204,0.10606602 +0.775,0.42499998,0.18898815,0.18898815 +0.775,0.425,0.1336348,0.2672696 +0.775,0.425,0.26726967,0.1336348 +0.775,0.425,0.23811013,0.23811018 +0.775,0.425,0.1683693,0.33673862 +0.775,0.425,0.3367386,0.1683693 +0.775,0.47500002,0.15000004,0.15 +0.775,0.475,0.10606599,0.21213204 +0.775,0.475,0.21213204,0.10606605 +0.775,0.475,0.18898815,0.18898815 +0.775,0.47500002,0.1336348,0.26726964 +0.775,0.475,0.26726967,0.13363487 +0.775,0.475,0.23811013,0.23811013 +0.775,0.475,0.1683693,0.33673865 +0.775,0.47500002,0.3367386,0.16836932 +0.775,0.525,0.15000004,0.15000004 +0.775,0.525,0.10606599,0.21213207 +0.775,0.525,0.21213204,0.10606605 +0.775,0.525,0.18898815,0.18898815 +0.775,0.525,0.1336348,0.26726958 +0.775,0.525,0.26726967,0.13363487 +0.775,0.525,0.23811013,0.23811015 +0.775,0.525,0.1683693,0.3367386 +0.775,0.525,0.3367386,0.16836926 +0.775,0.575,0.15000004,0.14999998 +0.775,0.575,0.10606599,0.21213207 +0.775,0.57500005,0.21213204,0.10606605 +0.775,0.575,0.18898815,0.18898809 +0.775,0.575,0.1336348,0.2672696 +0.775,0.57500005,0.26726967,0.13363487 +0.775,0.575,0.23811013,0.23811015 +0.775,0.575,0.1683693,0.3367386 +0.775,0.575,0.3367386,0.1683693 +0.775,0.625,0.15000004,0.14999998 +0.775,0.625,0.10606599,0.2121321 +0.775,0.625,0.21213204,0.10606599 +0.775,0.625,0.18898815,0.18898809 +0.775,0.625,0.1336348,0.2672696 +0.775,0.625,0.26726967,0.1336348 +0.775,0.625,0.23811013,0.23811018 +0.775,0.625,0.1683693,0.3367386 +0.775,0.625,0.3367386,0.1683693 +0.775,0.675,0.15000004,0.14999998 +0.775,0.675,0.10606599,0.2121321 +0.775,0.67499995,0.21213204,0.10606605 +0.775,0.675,0.18898815,0.18898809 +0.775,0.6750001,0.1336348,0.26726967 +0.775,0.67499995,0.26726967,0.13363487 +0.775,0.675,0.23811013,0.23811018 +0.775,0.675,0.1683693,0.3367386 +0.775,0.675,0.3367386,0.1683693 +0.775,0.725,0.15000004,0.15000004 +0.775,0.725,0.10606599,0.21213204 +0.775,0.725,0.21213204,0.10606605 +0.775,0.725,0.18898815,0.18898815 +0.775,0.725,0.1336348,0.2672696 +0.775,0.725,0.26726967,0.13363487 +0.775,0.725,0.23811013,0.23811013 +0.775,0.725,0.1683693,0.3367386 +0.775,0.725,0.3367386,0.1683693 +0.775,0.775,0.15000004,0.15000004 +0.775,0.775,0.10606599,0.21213204 +0.775,0.775,0.21213204,0.10606599 +0.775,0.775,0.18898815,0.18898815 +0.775,0.775,0.1336348,0.26726967 +0.775,0.775,0.26726967,0.1336348 +0.775,0.775,0.23811013,0.23811013 +0.775,0.775,0.1683693,0.3367386 +0.775,0.775,0.3367386,0.1683693 +0.775,0.825,0.15000004,0.14999998 +0.775,0.825,0.10606599,0.2121321 +0.775,0.825,0.21213204,0.10606599 +0.775,0.825,0.18898815,0.18898809 +0.775,0.82500005,0.1336348,0.26726967 +0.775,0.825,0.26726967,0.1336348 +0.775,0.825,0.23811013,0.23811018 +0.775,0.825,0.1683693,0.3367386 +0.775,0.825,0.3367386,0.1683693 +0.775,0.875,0.15000004,0.14999998 +0.775,0.875,0.10606599,0.2121321 +0.775,0.875,0.21213204,0.10606599 +0.775,0.875,0.18898815,0.18898809 +0.775,0.875,0.1336348,0.2672696 +0.775,0.875,0.26726967,0.1336348 +0.775,0.875,0.23811013,0.23811018 +0.775,0.875,0.1683693,0.3367386 +0.775,0.875,0.3367386,0.1683693 +0.775,0.925,0.15000004,0.14999998 +0.775,0.925,0.10606599,0.2121321 +0.775,0.92499995,0.21213204,0.10606593 +0.775,0.925,0.18898815,0.18898809 +0.775,0.9250001,0.1336348,0.26726967 +0.775,0.92499995,0.26726967,0.13363475 +0.775,0.925,0.23811013,0.23811018 +0.775,0.92499995,0.1683693,0.33673853 +0.775,0.92499995,0.3367386,0.16836923 +0.775,0.97499996,0.15000004,0.14999998 +0.775,0.975,0.10606599,0.21213204 +0.775,0.975,0.21213204,0.10606599 +0.775,0.97499996,0.18898815,0.18898809 +0.775,0.975,0.1336348,0.26726967 +0.775,0.975,0.26726967,0.1336348 +0.775,0.975,0.23811013,0.23811013 +0.775,0.975,0.1683693,0.3367386 +0.775,0.975,0.3367386,0.1683693 +0.825,0.025,0.14999998,0.15 +0.825,0.024999995,0.10606599,0.21213204 +0.825,0.024999999,0.2121321,0.10606602 +0.825,0.024999999,0.18898809,0.18898816 +0.825,0.025000002,0.1336348,0.2672696 +0.82500005,0.024999999,0.26726967,0.1336348 +0.825,0.025000002,0.23811018,0.23811015 +0.825,0.024999999,0.1683693,0.3367386 +0.825,0.025000004,0.3367386,0.16836931 +0.825,0.075,0.14999998,0.15 +0.825,0.074999996,0.10606599,0.21213202 +0.825,0.075,0.2121321,0.10606602 +0.825,0.075,0.18898809,0.18898815 +0.825,0.075,0.1336348,0.2672696 +0.82500005,0.075,0.26726967,0.1336348 +0.825,0.075,0.23811018,0.23811015 +0.825,0.075,0.1683693,0.33673862 +0.825,0.075,0.3367386,0.16836932 +0.825,0.125,0.14999998,0.15 +0.825,0.125,0.10606599,0.21213204 +0.825,0.125,0.2121321,0.10606602 +0.825,0.125,0.18898809,0.18898815 +0.825,0.125,0.1336348,0.2672696 +0.82500005,0.125,0.26726967,0.1336348 +0.825,0.125,0.23811018,0.23811015 +0.825,0.125,0.1683693,0.33673865 +0.825,0.125,0.3367386,0.1683693 +0.825,0.175,0.14999998,0.15 +0.825,0.17499998,0.10606599,0.21213202 +0.825,0.17500001,0.2121321,0.106066026 +0.825,0.17500001,0.18898809,0.18898816 +0.825,0.17500001,0.1336348,0.2672696 +0.82500005,0.175,0.26726967,0.1336348 +0.825,0.175,0.23811018,0.23811015 +0.825,0.175,0.1683693,0.33673862 +0.825,0.17500001,0.3367386,0.16836931 +0.825,0.22500001,0.14999998,0.15 +0.825,0.225,0.10606599,0.21213202 +0.825,0.22500001,0.2121321,0.10606602 +0.825,0.225,0.18898809,0.18898815 +0.825,0.225,0.1336348,0.2672696 +0.82500005,0.225,0.26726967,0.1336348 +0.825,0.225,0.23811018,0.23811017 +0.825,0.22500001,0.1683693,0.33673862 +0.825,0.225,0.3367386,0.1683693 +0.825,0.275,0.14999998,0.14999999 +0.825,0.275,0.10606599,0.21213204 +0.825,0.275,0.2121321,0.10606605 +0.825,0.275,0.18898809,0.18898816 +0.825,0.275,0.1336348,0.2672696 +0.82500005,0.275,0.26726967,0.1336348 +0.825,0.27499998,0.23811018,0.23811015 +0.825,0.275,0.1683693,0.3367386 +0.825,0.275,0.3367386,0.16836931 +0.825,0.325,0.14999998,0.15 +0.825,0.32500002,0.10606599,0.21213205 +0.825,0.325,0.2121321,0.10606602 +0.825,0.325,0.18898809,0.18898815 +0.825,0.325,0.1336348,0.2672696 +0.82500005,0.325,0.26726967,0.1336348 +0.825,0.325,0.23811018,0.23811015 +0.825,0.325,0.1683693,0.3367386 +0.825,0.325,0.3367386,0.16836928 +0.825,0.375,0.14999998,0.14999998 +0.825,0.375,0.10606599,0.21213207 +0.825,0.375,0.2121321,0.10606605 +0.825,0.375,0.18898809,0.18898812 +0.825,0.375,0.1336348,0.2672696 +0.82500005,0.375,0.26726967,0.13363484 +0.825,0.375,0.23811018,0.23811018 +0.825,0.375,0.1683693,0.33673862 +0.825,0.375,0.3367386,0.1683693 +0.825,0.425,0.14999998,0.15 +0.825,0.425,0.10606599,0.21213207 +0.825,0.425,0.2121321,0.10606602 +0.825,0.42499998,0.18898809,0.18898815 +0.825,0.425,0.1336348,0.2672696 +0.82500005,0.425,0.26726967,0.1336348 +0.825,0.425,0.23811018,0.23811018 +0.825,0.425,0.1683693,0.33673862 +0.825,0.425,0.3367386,0.1683693 +0.825,0.47500002,0.14999998,0.15 +0.825,0.475,0.10606599,0.21213204 +0.825,0.475,0.2121321,0.10606605 +0.825,0.475,0.18898809,0.18898815 +0.825,0.47500002,0.1336348,0.26726964 +0.82500005,0.475,0.26726967,0.13363487 +0.825,0.475,0.23811018,0.23811013 +0.825,0.475,0.1683693,0.33673865 +0.825,0.47500002,0.3367386,0.16836932 +0.825,0.525,0.14999998,0.15000004 +0.825,0.525,0.10606599,0.21213207 +0.825,0.525,0.2121321,0.10606605 +0.825,0.525,0.18898809,0.18898815 +0.825,0.525,0.1336348,0.26726958 +0.82500005,0.525,0.26726967,0.13363487 +0.825,0.525,0.23811018,0.23811015 +0.825,0.525,0.1683693,0.3367386 +0.825,0.525,0.3367386,0.16836926 +0.825,0.575,0.14999998,0.14999998 +0.825,0.575,0.10606599,0.21213207 +0.825,0.57500005,0.2121321,0.10606605 +0.825,0.575,0.18898809,0.18898809 +0.825,0.575,0.1336348,0.2672696 +0.82500005,0.57500005,0.26726967,0.13363487 +0.825,0.575,0.23811018,0.23811015 +0.825,0.575,0.1683693,0.3367386 +0.825,0.575,0.3367386,0.1683693 +0.825,0.625,0.14999998,0.14999998 +0.825,0.625,0.10606599,0.2121321 +0.825,0.625,0.2121321,0.10606599 +0.825,0.625,0.18898809,0.18898809 +0.825,0.625,0.1336348,0.2672696 +0.82500005,0.625,0.26726967,0.1336348 +0.825,0.625,0.23811018,0.23811018 +0.825,0.625,0.1683693,0.3367386 +0.825,0.625,0.3367386,0.1683693 +0.825,0.675,0.14999998,0.14999998 +0.825,0.675,0.10606599,0.2121321 +0.825,0.67499995,0.2121321,0.10606605 +0.825,0.675,0.18898809,0.18898809 +0.825,0.6750001,0.1336348,0.26726967 +0.82500005,0.67499995,0.26726967,0.13363487 +0.825,0.675,0.23811018,0.23811018 +0.825,0.675,0.1683693,0.3367386 +0.825,0.675,0.3367386,0.1683693 +0.825,0.725,0.14999998,0.15000004 +0.825,0.725,0.10606599,0.21213204 +0.825,0.725,0.2121321,0.10606605 +0.825,0.725,0.18898809,0.18898815 +0.825,0.725,0.1336348,0.2672696 +0.82500005,0.725,0.26726967,0.13363487 +0.825,0.725,0.23811018,0.23811013 +0.825,0.725,0.1683693,0.3367386 +0.825,0.725,0.3367386,0.1683693 +0.825,0.775,0.14999998,0.15000004 +0.825,0.775,0.10606599,0.21213204 +0.825,0.775,0.2121321,0.10606599 +0.825,0.775,0.18898809,0.18898815 +0.825,0.775,0.1336348,0.26726967 +0.82500005,0.775,0.26726967,0.1336348 +0.825,0.775,0.23811018,0.23811013 +0.825,0.775,0.1683693,0.3367386 +0.825,0.775,0.3367386,0.1683693 +0.825,0.825,0.14999998,0.14999998 +0.825,0.825,0.10606599,0.2121321 +0.825,0.825,0.2121321,0.10606599 +0.825,0.825,0.18898809,0.18898809 +0.825,0.82500005,0.1336348,0.26726967 +0.82500005,0.825,0.26726967,0.1336348 +0.825,0.825,0.23811018,0.23811018 +0.825,0.825,0.1683693,0.3367386 +0.825,0.825,0.3367386,0.1683693 +0.825,0.875,0.14999998,0.14999998 +0.825,0.875,0.10606599,0.2121321 +0.825,0.875,0.2121321,0.10606599 +0.825,0.875,0.18898809,0.18898809 +0.825,0.875,0.1336348,0.2672696 +0.82500005,0.875,0.26726967,0.1336348 +0.825,0.875,0.23811018,0.23811018 +0.825,0.875,0.1683693,0.3367386 +0.825,0.875,0.3367386,0.1683693 +0.825,0.925,0.14999998,0.14999998 +0.825,0.925,0.10606599,0.2121321 +0.825,0.92499995,0.2121321,0.10606593 +0.825,0.925,0.18898809,0.18898809 +0.825,0.9250001,0.1336348,0.26726967 +0.82500005,0.92499995,0.26726967,0.13363475 +0.825,0.925,0.23811018,0.23811018 +0.825,0.92499995,0.1683693,0.33673853 +0.825,0.92499995,0.3367386,0.16836923 +0.825,0.97499996,0.14999998,0.14999998 +0.825,0.975,0.10606599,0.21213204 +0.825,0.975,0.2121321,0.10606599 +0.825,0.97499996,0.18898809,0.18898809 +0.825,0.975,0.1336348,0.26726967 +0.82500005,0.975,0.26726967,0.1336348 +0.825,0.975,0.23811018,0.23811013 +0.825,0.975,0.1683693,0.3367386 +0.825,0.975,0.3367386,0.1683693 +0.875,0.025,0.14999998,0.15 +0.875,0.024999995,0.10606599,0.21213204 +0.875,0.024999999,0.2121321,0.10606602 +0.875,0.024999999,0.18898809,0.18898816 +0.875,0.025000002,0.1336348,0.2672696 +0.875,0.024999999,0.2672696,0.1336348 +0.875,0.025000002,0.23811018,0.23811015 +0.875,0.024999999,0.1683693,0.3367386 +0.875,0.025000004,0.3367386,0.16836931 +0.875,0.075,0.14999998,0.15 +0.875,0.074999996,0.10606599,0.21213202 +0.875,0.075,0.2121321,0.10606602 +0.875,0.075,0.18898809,0.18898815 +0.875,0.075,0.1336348,0.2672696 +0.875,0.075,0.2672696,0.1336348 +0.875,0.075,0.23811018,0.23811015 +0.875,0.075,0.1683693,0.33673862 +0.875,0.075,0.3367386,0.16836932 +0.875,0.125,0.14999998,0.15 +0.875,0.125,0.10606599,0.21213204 +0.875,0.125,0.2121321,0.10606602 +0.875,0.125,0.18898809,0.18898815 +0.875,0.125,0.1336348,0.2672696 +0.875,0.125,0.2672696,0.1336348 +0.875,0.125,0.23811018,0.23811015 +0.875,0.125,0.1683693,0.33673865 +0.875,0.125,0.3367386,0.1683693 +0.875,0.175,0.14999998,0.15 +0.875,0.17499998,0.10606599,0.21213202 +0.875,0.17500001,0.2121321,0.106066026 +0.875,0.17500001,0.18898809,0.18898816 +0.875,0.17500001,0.1336348,0.2672696 +0.875,0.175,0.2672696,0.1336348 +0.875,0.175,0.23811018,0.23811015 +0.875,0.175,0.1683693,0.33673862 +0.875,0.17500001,0.3367386,0.16836931 +0.875,0.22500001,0.14999998,0.15 +0.875,0.225,0.10606599,0.21213202 +0.875,0.22500001,0.2121321,0.10606602 +0.875,0.225,0.18898809,0.18898815 +0.875,0.225,0.1336348,0.2672696 +0.875,0.225,0.2672696,0.1336348 +0.875,0.225,0.23811018,0.23811017 +0.875,0.22500001,0.1683693,0.33673862 +0.875,0.225,0.3367386,0.1683693 +0.875,0.275,0.14999998,0.14999999 +0.875,0.275,0.10606599,0.21213204 +0.875,0.275,0.2121321,0.10606605 +0.875,0.275,0.18898809,0.18898816 +0.875,0.275,0.1336348,0.2672696 +0.875,0.275,0.2672696,0.1336348 +0.875,0.27499998,0.23811018,0.23811015 +0.875,0.275,0.1683693,0.3367386 +0.875,0.275,0.3367386,0.16836931 +0.875,0.325,0.14999998,0.15 +0.875,0.32500002,0.10606599,0.21213205 +0.875,0.325,0.2121321,0.10606602 +0.875,0.325,0.18898809,0.18898815 +0.875,0.325,0.1336348,0.2672696 +0.875,0.325,0.2672696,0.1336348 +0.875,0.325,0.23811018,0.23811015 +0.875,0.325,0.1683693,0.3367386 +0.875,0.325,0.3367386,0.16836928 +0.875,0.375,0.14999998,0.14999998 +0.875,0.375,0.10606599,0.21213207 +0.875,0.375,0.2121321,0.10606605 +0.875,0.375,0.18898809,0.18898812 +0.875,0.375,0.1336348,0.2672696 +0.875,0.375,0.2672696,0.13363484 +0.875,0.375,0.23811018,0.23811018 +0.875,0.375,0.1683693,0.33673862 +0.875,0.375,0.3367386,0.1683693 +0.875,0.425,0.14999998,0.15 +0.875,0.425,0.10606599,0.21213207 +0.875,0.425,0.2121321,0.10606602 +0.875,0.42499998,0.18898809,0.18898815 +0.875,0.425,0.1336348,0.2672696 +0.875,0.425,0.2672696,0.1336348 +0.875,0.425,0.23811018,0.23811018 +0.875,0.425,0.1683693,0.33673862 +0.875,0.425,0.3367386,0.1683693 +0.875,0.47500002,0.14999998,0.15 +0.875,0.475,0.10606599,0.21213204 +0.875,0.475,0.2121321,0.10606605 +0.875,0.475,0.18898809,0.18898815 +0.875,0.47500002,0.1336348,0.26726964 +0.875,0.475,0.2672696,0.13363487 +0.875,0.475,0.23811018,0.23811013 +0.875,0.475,0.1683693,0.33673865 +0.875,0.47500002,0.3367386,0.16836932 +0.875,0.525,0.14999998,0.15000004 +0.875,0.525,0.10606599,0.21213207 +0.875,0.525,0.2121321,0.10606605 +0.875,0.525,0.18898809,0.18898815 +0.875,0.525,0.1336348,0.26726958 +0.875,0.525,0.2672696,0.13363487 +0.875,0.525,0.23811018,0.23811015 +0.875,0.525,0.1683693,0.3367386 +0.875,0.525,0.3367386,0.16836926 +0.875,0.575,0.14999998,0.14999998 +0.875,0.575,0.10606599,0.21213207 +0.875,0.57500005,0.2121321,0.10606605 +0.875,0.575,0.18898809,0.18898809 +0.875,0.575,0.1336348,0.2672696 +0.875,0.57500005,0.2672696,0.13363487 +0.875,0.575,0.23811018,0.23811015 +0.875,0.575,0.1683693,0.3367386 +0.875,0.575,0.3367386,0.1683693 +0.875,0.625,0.14999998,0.14999998 +0.875,0.625,0.10606599,0.2121321 +0.875,0.625,0.2121321,0.10606599 +0.875,0.625,0.18898809,0.18898809 +0.875,0.625,0.1336348,0.2672696 +0.875,0.625,0.2672696,0.1336348 +0.875,0.625,0.23811018,0.23811018 +0.875,0.625,0.1683693,0.3367386 +0.875,0.625,0.3367386,0.1683693 +0.875,0.675,0.14999998,0.14999998 +0.875,0.675,0.10606599,0.2121321 +0.875,0.67499995,0.2121321,0.10606605 +0.875,0.675,0.18898809,0.18898809 +0.875,0.6750001,0.1336348,0.26726967 +0.875,0.67499995,0.2672696,0.13363487 +0.875,0.675,0.23811018,0.23811018 +0.875,0.675,0.1683693,0.3367386 +0.875,0.675,0.3367386,0.1683693 +0.875,0.725,0.14999998,0.15000004 +0.875,0.725,0.10606599,0.21213204 +0.875,0.725,0.2121321,0.10606605 +0.875,0.725,0.18898809,0.18898815 +0.875,0.725,0.1336348,0.2672696 +0.875,0.725,0.2672696,0.13363487 +0.875,0.725,0.23811018,0.23811013 +0.875,0.725,0.1683693,0.3367386 +0.875,0.725,0.3367386,0.1683693 +0.875,0.775,0.14999998,0.15000004 +0.875,0.775,0.10606599,0.21213204 +0.875,0.775,0.2121321,0.10606599 +0.875,0.775,0.18898809,0.18898815 +0.875,0.775,0.1336348,0.26726967 +0.875,0.775,0.2672696,0.1336348 +0.875,0.775,0.23811018,0.23811013 +0.875,0.775,0.1683693,0.3367386 +0.875,0.775,0.3367386,0.1683693 +0.875,0.825,0.14999998,0.14999998 +0.875,0.825,0.10606599,0.2121321 +0.875,0.825,0.2121321,0.10606599 +0.875,0.825,0.18898809,0.18898809 +0.875,0.82500005,0.1336348,0.26726967 +0.875,0.825,0.2672696,0.1336348 +0.875,0.825,0.23811018,0.23811018 +0.875,0.825,0.1683693,0.3367386 +0.875,0.825,0.3367386,0.1683693 +0.875,0.875,0.14999998,0.14999998 +0.875,0.875,0.10606599,0.2121321 +0.875,0.875,0.2121321,0.10606599 +0.875,0.875,0.18898809,0.18898809 +0.875,0.875,0.1336348,0.2672696 +0.875,0.875,0.2672696,0.1336348 +0.875,0.875,0.23811018,0.23811018 +0.875,0.875,0.1683693,0.3367386 +0.875,0.875,0.3367386,0.1683693 +0.875,0.925,0.14999998,0.14999998 +0.875,0.925,0.10606599,0.2121321 +0.875,0.92499995,0.2121321,0.10606593 +0.875,0.925,0.18898809,0.18898809 +0.875,0.9250001,0.1336348,0.26726967 +0.875,0.92499995,0.2672696,0.13363475 +0.875,0.925,0.23811018,0.23811018 +0.875,0.92499995,0.1683693,0.33673853 +0.875,0.92499995,0.3367386,0.16836923 +0.875,0.97499996,0.14999998,0.14999998 +0.875,0.975,0.10606599,0.21213204 +0.875,0.975,0.2121321,0.10606599 +0.875,0.97499996,0.18898809,0.18898809 +0.875,0.975,0.1336348,0.26726967 +0.875,0.975,0.2672696,0.1336348 +0.875,0.975,0.23811018,0.23811013 +0.875,0.975,0.1683693,0.3367386 +0.875,0.975,0.3367386,0.1683693 +0.925,0.025,0.14999998,0.15 +0.92499995,0.024999995,0.10606593,0.21213204 +0.925,0.024999999,0.2121321,0.10606602 +0.925,0.024999999,0.18898809,0.18898816 +0.92499995,0.025000002,0.13363475,0.2672696 +0.9250001,0.024999999,0.26726967,0.1336348 +0.925,0.025000002,0.23811018,0.23811015 +0.92499995,0.024999999,0.16836923,0.3367386 +0.92499995,0.025000004,0.33673853,0.16836931 +0.925,0.075,0.14999998,0.15 +0.92499995,0.074999996,0.10606593,0.21213202 +0.925,0.075,0.2121321,0.10606602 +0.925,0.075,0.18898809,0.18898815 +0.92499995,0.075,0.13363475,0.2672696 +0.9250001,0.075,0.26726967,0.1336348 +0.925,0.075,0.23811018,0.23811015 +0.92499995,0.075,0.16836923,0.33673862 +0.92499995,0.075,0.33673853,0.16836932 +0.925,0.125,0.14999998,0.15 +0.92499995,0.125,0.10606593,0.21213204 +0.925,0.125,0.2121321,0.10606602 +0.925,0.125,0.18898809,0.18898815 +0.92499995,0.125,0.13363475,0.2672696 +0.9250001,0.125,0.26726967,0.1336348 +0.925,0.125,0.23811018,0.23811015 +0.92499995,0.125,0.16836923,0.33673865 +0.92499995,0.125,0.33673853,0.1683693 +0.925,0.175,0.14999998,0.15 +0.92499995,0.17499998,0.10606593,0.21213202 +0.925,0.17500001,0.2121321,0.106066026 +0.925,0.17500001,0.18898809,0.18898816 +0.92499995,0.17500001,0.13363475,0.2672696 +0.9250001,0.175,0.26726967,0.1336348 +0.925,0.175,0.23811018,0.23811015 +0.92499995,0.175,0.16836923,0.33673862 +0.92499995,0.17500001,0.33673853,0.16836931 +0.925,0.22500001,0.14999998,0.15 +0.92499995,0.225,0.10606593,0.21213202 +0.925,0.22500001,0.2121321,0.10606602 +0.925,0.225,0.18898809,0.18898815 +0.92499995,0.225,0.13363475,0.2672696 +0.9250001,0.225,0.26726967,0.1336348 +0.925,0.225,0.23811018,0.23811017 +0.92499995,0.22500001,0.16836923,0.33673862 +0.92499995,0.225,0.33673853,0.1683693 +0.925,0.275,0.14999998,0.14999999 +0.92499995,0.275,0.10606593,0.21213204 +0.925,0.275,0.2121321,0.10606605 +0.925,0.275,0.18898809,0.18898816 +0.92499995,0.275,0.13363475,0.2672696 +0.9250001,0.275,0.26726967,0.1336348 +0.925,0.27499998,0.23811018,0.23811015 +0.92499995,0.275,0.16836923,0.3367386 +0.92499995,0.275,0.33673853,0.16836931 +0.925,0.325,0.14999998,0.15 +0.92499995,0.32500002,0.10606593,0.21213205 +0.925,0.325,0.2121321,0.10606602 +0.925,0.325,0.18898809,0.18898815 +0.92499995,0.325,0.13363475,0.2672696 +0.9250001,0.325,0.26726967,0.1336348 +0.925,0.325,0.23811018,0.23811015 +0.92499995,0.325,0.16836923,0.3367386 +0.92499995,0.325,0.33673853,0.16836928 +0.925,0.375,0.14999998,0.14999998 +0.92499995,0.375,0.10606593,0.21213207 +0.925,0.375,0.2121321,0.10606605 +0.925,0.375,0.18898809,0.18898812 +0.92499995,0.375,0.13363475,0.2672696 +0.9250001,0.375,0.26726967,0.13363484 +0.925,0.375,0.23811018,0.23811018 +0.92499995,0.375,0.16836923,0.33673862 +0.92499995,0.375,0.33673853,0.1683693 +0.925,0.425,0.14999998,0.15 +0.92499995,0.425,0.10606593,0.21213207 +0.925,0.425,0.2121321,0.10606602 +0.925,0.42499998,0.18898809,0.18898815 +0.92499995,0.425,0.13363475,0.2672696 +0.9250001,0.425,0.26726967,0.1336348 +0.925,0.425,0.23811018,0.23811018 +0.92499995,0.425,0.16836923,0.33673862 +0.92499995,0.425,0.33673853,0.1683693 +0.925,0.47500002,0.14999998,0.15 +0.92499995,0.475,0.10606593,0.21213204 +0.925,0.475,0.2121321,0.10606605 +0.925,0.475,0.18898809,0.18898815 +0.92499995,0.47500002,0.13363475,0.26726964 +0.9250001,0.475,0.26726967,0.13363487 +0.925,0.475,0.23811018,0.23811013 +0.92499995,0.475,0.16836923,0.33673865 +0.92499995,0.47500002,0.33673853,0.16836932 +0.925,0.525,0.14999998,0.15000004 +0.92499995,0.525,0.10606593,0.21213207 +0.925,0.525,0.2121321,0.10606605 +0.925,0.525,0.18898809,0.18898815 +0.92499995,0.525,0.13363475,0.26726958 +0.9250001,0.525,0.26726967,0.13363487 +0.925,0.525,0.23811018,0.23811015 +0.92499995,0.525,0.16836923,0.3367386 +0.92499995,0.525,0.33673853,0.16836926 +0.925,0.575,0.14999998,0.14999998 +0.92499995,0.575,0.10606593,0.21213207 +0.925,0.57500005,0.2121321,0.10606605 +0.925,0.575,0.18898809,0.18898809 +0.92499995,0.575,0.13363475,0.2672696 +0.9250001,0.57500005,0.26726967,0.13363487 +0.925,0.575,0.23811018,0.23811015 +0.92499995,0.575,0.16836923,0.3367386 +0.92499995,0.575,0.33673853,0.1683693 +0.925,0.625,0.14999998,0.14999998 +0.92499995,0.625,0.10606593,0.2121321 +0.925,0.625,0.2121321,0.10606599 +0.925,0.625,0.18898809,0.18898809 +0.92499995,0.625,0.13363475,0.2672696 +0.9250001,0.625,0.26726967,0.1336348 +0.925,0.625,0.23811018,0.23811018 +0.92499995,0.625,0.16836923,0.3367386 +0.92499995,0.625,0.33673853,0.1683693 +0.925,0.675,0.14999998,0.14999998 +0.92499995,0.675,0.10606593,0.2121321 +0.925,0.67499995,0.2121321,0.10606605 +0.925,0.675,0.18898809,0.18898809 +0.92499995,0.6750001,0.13363475,0.26726967 +0.9250001,0.67499995,0.26726967,0.13363487 +0.925,0.675,0.23811018,0.23811018 +0.92499995,0.675,0.16836923,0.3367386 +0.92499995,0.675,0.33673853,0.1683693 +0.925,0.725,0.14999998,0.15000004 +0.92499995,0.725,0.10606593,0.21213204 +0.925,0.725,0.2121321,0.10606605 +0.925,0.725,0.18898809,0.18898815 +0.92499995,0.725,0.13363475,0.2672696 +0.9250001,0.725,0.26726967,0.13363487 +0.925,0.725,0.23811018,0.23811013 +0.92499995,0.725,0.16836923,0.3367386 +0.92499995,0.725,0.33673853,0.1683693 +0.925,0.775,0.14999998,0.15000004 +0.92499995,0.775,0.10606593,0.21213204 +0.925,0.775,0.2121321,0.10606599 +0.925,0.775,0.18898809,0.18898815 +0.92499995,0.775,0.13363475,0.26726967 +0.9250001,0.775,0.26726967,0.1336348 +0.925,0.775,0.23811018,0.23811013 +0.92499995,0.775,0.16836923,0.3367386 +0.92499995,0.775,0.33673853,0.1683693 +0.925,0.825,0.14999998,0.14999998 +0.92499995,0.825,0.10606593,0.2121321 +0.925,0.825,0.2121321,0.10606599 +0.925,0.825,0.18898809,0.18898809 +0.92499995,0.82500005,0.13363475,0.26726967 +0.9250001,0.825,0.26726967,0.1336348 +0.925,0.825,0.23811018,0.23811018 +0.92499995,0.825,0.16836923,0.3367386 +0.92499995,0.825,0.33673853,0.1683693 +0.925,0.875,0.14999998,0.14999998 +0.92499995,0.875,0.10606593,0.2121321 +0.925,0.875,0.2121321,0.10606599 +0.925,0.875,0.18898809,0.18898809 +0.92499995,0.875,0.13363475,0.2672696 +0.9250001,0.875,0.26726967,0.1336348 +0.925,0.875,0.23811018,0.23811018 +0.92499995,0.875,0.16836923,0.3367386 +0.92499995,0.875,0.33673853,0.1683693 +0.925,0.925,0.14999998,0.14999998 +0.92499995,0.925,0.10606593,0.2121321 +0.925,0.92499995,0.2121321,0.10606593 +0.925,0.925,0.18898809,0.18898809 +0.92499995,0.9250001,0.13363475,0.26726967 +0.9250001,0.92499995,0.26726967,0.13363475 +0.925,0.925,0.23811018,0.23811018 +0.92499995,0.92499995,0.16836923,0.33673853 +0.92499995,0.92499995,0.33673853,0.16836923 +0.925,0.97499996,0.14999998,0.14999998 +0.92499995,0.975,0.10606593,0.21213204 +0.925,0.975,0.2121321,0.10606599 +0.925,0.97499996,0.18898809,0.18898809 +0.92499995,0.975,0.13363475,0.26726967 +0.9250001,0.975,0.26726967,0.1336348 +0.925,0.975,0.23811018,0.23811013 +0.92499995,0.975,0.16836923,0.3367386 +0.92499995,0.975,0.33673853,0.1683693 +0.97499996,0.025,0.14999998,0.15 +0.975,0.024999995,0.10606599,0.21213204 +0.975,0.024999999,0.21213204,0.10606602 +0.97499996,0.024999999,0.18898809,0.18898816 +0.975,0.025000002,0.1336348,0.2672696 +0.975,0.024999999,0.26726967,0.1336348 +0.975,0.025000002,0.23811013,0.23811015 +0.975,0.024999999,0.1683693,0.3367386 +0.975,0.025000004,0.3367386,0.16836931 +0.97499996,0.075,0.14999998,0.15 +0.975,0.074999996,0.10606599,0.21213202 +0.975,0.075,0.21213204,0.10606602 +0.97499996,0.075,0.18898809,0.18898815 +0.975,0.075,0.1336348,0.2672696 +0.975,0.075,0.26726967,0.1336348 +0.975,0.075,0.23811013,0.23811015 +0.975,0.075,0.1683693,0.33673862 +0.975,0.075,0.3367386,0.16836932 +0.97499996,0.125,0.14999998,0.15 +0.975,0.125,0.10606599,0.21213204 +0.975,0.125,0.21213204,0.10606602 +0.97499996,0.125,0.18898809,0.18898815 +0.975,0.125,0.1336348,0.2672696 +0.975,0.125,0.26726967,0.1336348 +0.975,0.125,0.23811013,0.23811015 +0.975,0.125,0.1683693,0.33673865 +0.975,0.125,0.3367386,0.1683693 +0.97499996,0.175,0.14999998,0.15 +0.975,0.17499998,0.10606599,0.21213202 +0.975,0.17500001,0.21213204,0.106066026 +0.97499996,0.17500001,0.18898809,0.18898816 +0.975,0.17500001,0.1336348,0.2672696 +0.975,0.175,0.26726967,0.1336348 +0.975,0.175,0.23811013,0.23811015 +0.975,0.175,0.1683693,0.33673862 +0.975,0.17500001,0.3367386,0.16836931 +0.97499996,0.22500001,0.14999998,0.15 +0.975,0.225,0.10606599,0.21213202 +0.975,0.22500001,0.21213204,0.10606602 +0.97499996,0.225,0.18898809,0.18898815 +0.975,0.225,0.1336348,0.2672696 +0.975,0.225,0.26726967,0.1336348 +0.975,0.225,0.23811013,0.23811017 +0.975,0.22500001,0.1683693,0.33673862 +0.975,0.225,0.3367386,0.1683693 +0.97499996,0.275,0.14999998,0.14999999 +0.975,0.275,0.10606599,0.21213204 +0.975,0.275,0.21213204,0.10606605 +0.97499996,0.275,0.18898809,0.18898816 +0.975,0.275,0.1336348,0.2672696 +0.975,0.275,0.26726967,0.1336348 +0.975,0.27499998,0.23811013,0.23811015 +0.975,0.275,0.1683693,0.3367386 +0.975,0.275,0.3367386,0.16836931 +0.97499996,0.325,0.14999998,0.15 +0.975,0.32500002,0.10606599,0.21213205 +0.975,0.325,0.21213204,0.10606602 +0.97499996,0.325,0.18898809,0.18898815 +0.975,0.325,0.1336348,0.2672696 +0.975,0.325,0.26726967,0.1336348 +0.975,0.325,0.23811013,0.23811015 +0.975,0.325,0.1683693,0.3367386 +0.975,0.325,0.3367386,0.16836928 +0.97499996,0.375,0.14999998,0.14999998 +0.975,0.375,0.10606599,0.21213207 +0.975,0.375,0.21213204,0.10606605 +0.97499996,0.375,0.18898809,0.18898812 +0.975,0.375,0.1336348,0.2672696 +0.975,0.375,0.26726967,0.13363484 +0.975,0.375,0.23811013,0.23811018 +0.975,0.375,0.1683693,0.33673862 +0.975,0.375,0.3367386,0.1683693 +0.97499996,0.425,0.14999998,0.15 +0.975,0.425,0.10606599,0.21213207 +0.975,0.425,0.21213204,0.10606602 +0.97499996,0.42499998,0.18898809,0.18898815 +0.975,0.425,0.1336348,0.2672696 +0.975,0.425,0.26726967,0.1336348 +0.975,0.425,0.23811013,0.23811018 +0.975,0.425,0.1683693,0.33673862 +0.975,0.425,0.3367386,0.1683693 +0.97499996,0.47500002,0.14999998,0.15 +0.975,0.475,0.10606599,0.21213204 +0.975,0.475,0.21213204,0.10606605 +0.97499996,0.475,0.18898809,0.18898815 +0.975,0.47500002,0.1336348,0.26726964 +0.975,0.475,0.26726967,0.13363487 +0.975,0.475,0.23811013,0.23811013 +0.975,0.475,0.1683693,0.33673865 +0.975,0.47500002,0.3367386,0.16836932 +0.97499996,0.525,0.14999998,0.15000004 +0.975,0.525,0.10606599,0.21213207 +0.975,0.525,0.21213204,0.10606605 +0.97499996,0.525,0.18898809,0.18898815 +0.975,0.525,0.1336348,0.26726958 +0.975,0.525,0.26726967,0.13363487 +0.975,0.525,0.23811013,0.23811015 +0.975,0.525,0.1683693,0.3367386 +0.975,0.525,0.3367386,0.16836926 +0.97499996,0.575,0.14999998,0.14999998 +0.975,0.575,0.10606599,0.21213207 +0.975,0.57500005,0.21213204,0.10606605 +0.97499996,0.575,0.18898809,0.18898809 +0.975,0.575,0.1336348,0.2672696 +0.975,0.57500005,0.26726967,0.13363487 +0.975,0.575,0.23811013,0.23811015 +0.975,0.575,0.1683693,0.3367386 +0.975,0.575,0.3367386,0.1683693 +0.97499996,0.625,0.14999998,0.14999998 +0.975,0.625,0.10606599,0.2121321 +0.975,0.625,0.21213204,0.10606599 +0.97499996,0.625,0.18898809,0.18898809 +0.975,0.625,0.1336348,0.2672696 +0.975,0.625,0.26726967,0.1336348 +0.975,0.625,0.23811013,0.23811018 +0.975,0.625,0.1683693,0.3367386 +0.975,0.625,0.3367386,0.1683693 +0.97499996,0.675,0.14999998,0.14999998 +0.975,0.675,0.10606599,0.2121321 +0.975,0.67499995,0.21213204,0.10606605 +0.97499996,0.675,0.18898809,0.18898809 +0.975,0.6750001,0.1336348,0.26726967 +0.975,0.67499995,0.26726967,0.13363487 +0.975,0.675,0.23811013,0.23811018 +0.975,0.675,0.1683693,0.3367386 +0.975,0.675,0.3367386,0.1683693 +0.97499996,0.725,0.14999998,0.15000004 +0.975,0.725,0.10606599,0.21213204 +0.975,0.725,0.21213204,0.10606605 +0.97499996,0.725,0.18898809,0.18898815 +0.975,0.725,0.1336348,0.2672696 +0.975,0.725,0.26726967,0.13363487 +0.975,0.725,0.23811013,0.23811013 +0.975,0.725,0.1683693,0.3367386 +0.975,0.725,0.3367386,0.1683693 +0.97499996,0.775,0.14999998,0.15000004 +0.975,0.775,0.10606599,0.21213204 +0.975,0.775,0.21213204,0.10606599 +0.97499996,0.775,0.18898809,0.18898815 +0.975,0.775,0.1336348,0.26726967 +0.975,0.775,0.26726967,0.1336348 +0.975,0.775,0.23811013,0.23811013 +0.975,0.775,0.1683693,0.3367386 +0.975,0.775,0.3367386,0.1683693 +0.97499996,0.825,0.14999998,0.14999998 +0.975,0.825,0.10606599,0.2121321 +0.975,0.825,0.21213204,0.10606599 +0.97499996,0.825,0.18898809,0.18898809 +0.975,0.82500005,0.1336348,0.26726967 +0.975,0.825,0.26726967,0.1336348 +0.975,0.825,0.23811013,0.23811018 +0.975,0.825,0.1683693,0.3367386 +0.975,0.825,0.3367386,0.1683693 +0.97499996,0.875,0.14999998,0.14999998 +0.975,0.875,0.10606599,0.2121321 +0.975,0.875,0.21213204,0.10606599 +0.97499996,0.875,0.18898809,0.18898809 +0.975,0.875,0.1336348,0.2672696 +0.975,0.875,0.26726967,0.1336348 +0.975,0.875,0.23811013,0.23811018 +0.975,0.875,0.1683693,0.3367386 +0.975,0.875,0.3367386,0.1683693 +0.97499996,0.925,0.14999998,0.14999998 +0.975,0.925,0.10606599,0.2121321 +0.975,0.92499995,0.21213204,0.10606593 +0.97499996,0.925,0.18898809,0.18898809 +0.975,0.9250001,0.1336348,0.26726967 +0.975,0.92499995,0.26726967,0.13363475 +0.975,0.925,0.23811013,0.23811018 +0.975,0.92499995,0.1683693,0.33673853 +0.975,0.92499995,0.3367386,0.16836923 +0.97499996,0.97499996,0.14999998,0.14999998 +0.975,0.975,0.10606599,0.21213204 +0.975,0.975,0.21213204,0.10606599 +0.97499996,0.97499996,0.18898809,0.18898809 +0.975,0.975,0.1336348,0.26726967 +0.975,0.975,0.26726967,0.1336348 +0.975,0.975,0.23811013,0.23811013 +0.975,0.975,0.1683693,0.3367386 +0.975,0.975,0.3367386,0.1683693 +0.05,0.05,0.3,0.3 +0.049999997,0.04999999,0.21213204,0.42426407 +0.04999999,0.049999997,0.42426407,0.21213204 +0.049999997,0.049999997,0.37797633,0.37797633 +0.049999997,0.050000004,0.2672696,0.5345392 +0.050000004,0.049999997,0.5345392,0.2672696 +0.050000004,0.050000004,0.4762203,0.4762203 +0.05000001,0.049999997,0.33673862,0.6734772 +0.049999997,0.05000001,0.6734772,0.33673862 +0.05,0.15,0.3,0.3 +0.049999997,0.14999999,0.21213204,0.42426404 +0.04999999,0.15,0.42426407,0.21213204 +0.049999997,0.15,0.37797633,0.3779763 +0.049999997,0.15,0.2672696,0.5345392 +0.050000004,0.15,0.5345392,0.2672696 +0.050000004,0.15,0.4762203,0.4762203 +0.05000001,0.15,0.33673862,0.67347723 +0.049999997,0.15,0.6734772,0.33673865 +0.05,0.25,0.3,0.3 +0.049999997,0.25,0.21213204,0.42426407 +0.04999999,0.25,0.42426407,0.21213204 +0.049999997,0.25,0.37797633,0.3779763 +0.049999997,0.25,0.2672696,0.5345392 +0.050000004,0.25,0.5345392,0.2672696 +0.050000004,0.25,0.4762203,0.4762203 +0.05000001,0.25,0.33673862,0.6734773 +0.049999997,0.25,0.6734772,0.3367386 +0.05,0.35,0.3,0.3 +0.049999997,0.34999996,0.21213204,0.42426404 +0.04999999,0.35000002,0.42426407,0.21213205 +0.049999997,0.35000002,0.37797633,0.37797633 +0.049999997,0.35000002,0.2672696,0.5345392 +0.050000004,0.35,0.5345392,0.2672696 +0.050000004,0.35,0.4762203,0.4762203 +0.05000001,0.35,0.33673862,0.67347723 +0.049999997,0.35000002,0.6734772,0.33673862 +0.05,0.45000002,0.3,0.3 +0.049999997,0.45,0.21213204,0.42426404 +0.04999999,0.45000002,0.42426407,0.21213204 +0.049999997,0.45,0.37797633,0.3779763 +0.049999997,0.45,0.2672696,0.5345392 +0.050000004,0.45,0.5345392,0.2672696 +0.050000004,0.45,0.4762203,0.47622034 +0.05000001,0.45000002,0.33673862,0.67347723 +0.049999997,0.45,0.6734772,0.3367386 +0.05,0.55,0.3,0.29999998 +0.049999997,0.55,0.21213204,0.42426407 +0.04999999,0.55,0.42426407,0.2121321 +0.049999997,0.55,0.37797633,0.37797633 +0.049999997,0.55,0.2672696,0.5345392 +0.050000004,0.55,0.5345392,0.2672696 +0.050000004,0.54999995,0.4762203,0.4762203 +0.05000001,0.55,0.33673862,0.6734772 +0.049999997,0.55,0.6734772,0.33673862 +0.05,0.65,0.3,0.3 +0.049999997,0.65000004,0.21213204,0.4242641 +0.04999999,0.65,0.42426407,0.21213204 +0.049999997,0.65,0.37797633,0.3779763 +0.049999997,0.65,0.2672696,0.5345392 +0.050000004,0.65,0.5345392,0.2672696 +0.050000004,0.65,0.4762203,0.4762203 +0.05000001,0.65,0.33673862,0.6734772 +0.049999997,0.65,0.6734772,0.33673856 +0.05,0.75,0.3,0.29999995 +0.049999997,0.75,0.21213204,0.42426413 +0.04999999,0.75,0.42426407,0.2121321 +0.049999997,0.75,0.37797633,0.37797624 +0.049999997,0.75,0.2672696,0.5345392 +0.050000004,0.75,0.5345392,0.26726967 +0.050000004,0.75,0.4762203,0.47622037 +0.05000001,0.75,0.33673862,0.67347723 +0.049999997,0.75,0.6734772,0.3367386 +0.05,0.85,0.3,0.3 +0.049999997,0.85,0.21213204,0.42426413 +0.04999999,0.85,0.42426407,0.21213204 +0.049999997,0.84999996,0.37797633,0.3779763 +0.049999997,0.85,0.2672696,0.5345392 +0.050000004,0.85,0.5345392,0.2672696 +0.050000004,0.85,0.4762203,0.47622037 +0.05000001,0.85,0.33673862,0.67347723 +0.049999997,0.85,0.6734772,0.3367386 +0.05,0.95000005,0.3,0.3 +0.049999997,0.95,0.21213204,0.42426407 +0.04999999,0.95,0.42426407,0.2121321 +0.049999997,0.95,0.37797633,0.3779763 +0.049999997,0.95000005,0.2672696,0.5345393 +0.050000004,0.95,0.5345392,0.26726973 +0.050000004,0.95,0.4762203,0.47622025 +0.05000001,0.95,0.33673862,0.6734773 +0.049999997,0.95000005,0.6734772,0.33673865 +0.15,0.05,0.3,0.3 +0.15,0.04999999,0.21213204,0.42426407 +0.14999999,0.049999997,0.42426404,0.21213204 +0.15,0.049999997,0.3779763,0.37797633 +0.15,0.050000004,0.2672696,0.5345392 +0.15,0.049999997,0.5345392,0.2672696 +0.15,0.050000004,0.4762203,0.4762203 +0.15,0.049999997,0.33673865,0.6734772 +0.15,0.05000001,0.67347723,0.33673862 +0.15,0.15,0.3,0.3 +0.15,0.14999999,0.21213204,0.42426404 +0.14999999,0.15,0.42426404,0.21213204 +0.15,0.15,0.3779763,0.3779763 +0.15,0.15,0.2672696,0.5345392 +0.15,0.15,0.5345392,0.2672696 +0.15,0.15,0.4762203,0.4762203 +0.15,0.15,0.33673865,0.67347723 +0.15,0.15,0.67347723,0.33673865 +0.15,0.25,0.3,0.3 +0.15,0.25,0.21213204,0.42426407 +0.14999999,0.25,0.42426404,0.21213204 +0.15,0.25,0.3779763,0.3779763 +0.15,0.25,0.2672696,0.5345392 +0.15,0.25,0.5345392,0.2672696 +0.15,0.25,0.4762203,0.4762203 +0.15,0.25,0.33673865,0.6734773 +0.15,0.25,0.67347723,0.3367386 +0.15,0.35,0.3,0.3 +0.15,0.34999996,0.21213204,0.42426404 +0.14999999,0.35000002,0.42426404,0.21213205 +0.15,0.35000002,0.3779763,0.37797633 +0.15,0.35000002,0.2672696,0.5345392 +0.15,0.35,0.5345392,0.2672696 +0.15,0.35,0.4762203,0.4762203 +0.15,0.35,0.33673865,0.67347723 +0.15,0.35000002,0.67347723,0.33673862 +0.15,0.45000002,0.3,0.3 +0.15,0.45,0.21213204,0.42426404 +0.14999999,0.45000002,0.42426404,0.21213204 +0.15,0.45,0.3779763,0.3779763 +0.15,0.45,0.2672696,0.5345392 +0.15,0.45,0.5345392,0.2672696 +0.15,0.45,0.4762203,0.47622034 +0.15,0.45000002,0.33673865,0.67347723 +0.15,0.45,0.67347723,0.3367386 +0.15,0.55,0.3,0.29999998 +0.15,0.55,0.21213204,0.42426407 +0.14999999,0.55,0.42426404,0.2121321 +0.15,0.55,0.3779763,0.37797633 +0.15,0.55,0.2672696,0.5345392 +0.15,0.55,0.5345392,0.2672696 +0.15,0.54999995,0.4762203,0.4762203 +0.15,0.55,0.33673865,0.6734772 +0.15,0.55,0.67347723,0.33673862 +0.15,0.65,0.3,0.3 +0.15,0.65000004,0.21213204,0.4242641 +0.14999999,0.65,0.42426404,0.21213204 +0.15,0.65,0.3779763,0.3779763 +0.15,0.65,0.2672696,0.5345392 +0.15,0.65,0.5345392,0.2672696 +0.15,0.65,0.4762203,0.4762203 +0.15,0.65,0.33673865,0.6734772 +0.15,0.65,0.67347723,0.33673856 +0.15,0.75,0.3,0.29999995 +0.15,0.75,0.21213204,0.42426413 +0.14999999,0.75,0.42426404,0.2121321 +0.15,0.75,0.3779763,0.37797624 +0.15,0.75,0.2672696,0.5345392 +0.15,0.75,0.5345392,0.26726967 +0.15,0.75,0.4762203,0.47622037 +0.15,0.75,0.33673865,0.67347723 +0.15,0.75,0.67347723,0.3367386 +0.15,0.85,0.3,0.3 +0.15,0.85,0.21213204,0.42426413 +0.14999999,0.85,0.42426404,0.21213204 +0.15,0.84999996,0.3779763,0.3779763 +0.15,0.85,0.2672696,0.5345392 +0.15,0.85,0.5345392,0.2672696 +0.15,0.85,0.4762203,0.47622037 +0.15,0.85,0.33673865,0.67347723 +0.15,0.85,0.67347723,0.3367386 +0.15,0.95000005,0.3,0.3 +0.15,0.95,0.21213204,0.42426407 +0.14999999,0.95,0.42426404,0.2121321 +0.15,0.95,0.3779763,0.3779763 +0.15,0.95000005,0.2672696,0.5345393 +0.15,0.95,0.5345392,0.26726973 +0.15,0.95,0.4762203,0.47622025 +0.15,0.95,0.33673865,0.6734773 +0.15,0.95000005,0.67347723,0.33673865 +0.25,0.05,0.3,0.3 +0.25,0.04999999,0.21213204,0.42426407 +0.25,0.049999997,0.42426407,0.21213204 +0.25,0.049999997,0.3779763,0.37797633 +0.25,0.050000004,0.2672696,0.5345392 +0.25,0.049999997,0.5345392,0.2672696 +0.25,0.050000004,0.4762203,0.4762203 +0.25,0.049999997,0.3367386,0.6734772 +0.25,0.05000001,0.6734773,0.33673862 +0.25,0.15,0.3,0.3 +0.25,0.14999999,0.21213204,0.42426404 +0.25,0.15,0.42426407,0.21213204 +0.25,0.15,0.3779763,0.3779763 +0.25,0.15,0.2672696,0.5345392 +0.25,0.15,0.5345392,0.2672696 +0.25,0.15,0.4762203,0.4762203 +0.25,0.15,0.3367386,0.67347723 +0.25,0.15,0.6734773,0.33673865 +0.25,0.25,0.3,0.3 +0.25,0.25,0.21213204,0.42426407 +0.25,0.25,0.42426407,0.21213204 +0.25,0.25,0.3779763,0.3779763 +0.25,0.25,0.2672696,0.5345392 +0.25,0.25,0.5345392,0.2672696 +0.25,0.25,0.4762203,0.4762203 +0.25,0.25,0.3367386,0.6734773 +0.25,0.25,0.6734773,0.3367386 +0.25,0.35,0.3,0.3 +0.25,0.34999996,0.21213204,0.42426404 +0.25,0.35000002,0.42426407,0.21213205 +0.25,0.35000002,0.3779763,0.37797633 +0.25,0.35000002,0.2672696,0.5345392 +0.25,0.35,0.5345392,0.2672696 +0.25,0.35,0.4762203,0.4762203 +0.25,0.35,0.3367386,0.67347723 +0.25,0.35000002,0.6734773,0.33673862 +0.25,0.45000002,0.3,0.3 +0.25,0.45,0.21213204,0.42426404 +0.25,0.45000002,0.42426407,0.21213204 +0.25,0.45,0.3779763,0.3779763 +0.25,0.45,0.2672696,0.5345392 +0.25,0.45,0.5345392,0.2672696 +0.25,0.45,0.4762203,0.47622034 +0.25,0.45000002,0.3367386,0.67347723 +0.25,0.45,0.6734773,0.3367386 +0.25,0.55,0.3,0.29999998 +0.25,0.55,0.21213204,0.42426407 +0.25,0.55,0.42426407,0.2121321 +0.25,0.55,0.3779763,0.37797633 +0.25,0.55,0.2672696,0.5345392 +0.25,0.55,0.5345392,0.2672696 +0.25,0.54999995,0.4762203,0.4762203 +0.25,0.55,0.3367386,0.6734772 +0.25,0.55,0.6734773,0.33673862 +0.25,0.65,0.3,0.3 +0.25,0.65000004,0.21213204,0.4242641 +0.25,0.65,0.42426407,0.21213204 +0.25,0.65,0.3779763,0.3779763 +0.25,0.65,0.2672696,0.5345392 +0.25,0.65,0.5345392,0.2672696 +0.25,0.65,0.4762203,0.4762203 +0.25,0.65,0.3367386,0.6734772 +0.25,0.65,0.6734773,0.33673856 +0.25,0.75,0.3,0.29999995 +0.25,0.75,0.21213204,0.42426413 +0.25,0.75,0.42426407,0.2121321 +0.25,0.75,0.3779763,0.37797624 +0.25,0.75,0.2672696,0.5345392 +0.25,0.75,0.5345392,0.26726967 +0.25,0.75,0.4762203,0.47622037 +0.25,0.75,0.3367386,0.67347723 +0.25,0.75,0.6734773,0.3367386 +0.25,0.85,0.3,0.3 +0.25,0.85,0.21213204,0.42426413 +0.25,0.85,0.42426407,0.21213204 +0.25,0.84999996,0.3779763,0.3779763 +0.25,0.85,0.2672696,0.5345392 +0.25,0.85,0.5345392,0.2672696 +0.25,0.85,0.4762203,0.47622037 +0.25,0.85,0.3367386,0.67347723 +0.25,0.85,0.6734773,0.3367386 +0.25,0.95000005,0.3,0.3 +0.25,0.95,0.21213204,0.42426407 +0.25,0.95,0.42426407,0.2121321 +0.25,0.95,0.3779763,0.3779763 +0.25,0.95000005,0.2672696,0.5345393 +0.25,0.95,0.5345392,0.26726973 +0.25,0.95,0.4762203,0.47622025 +0.25,0.95,0.3367386,0.6734773 +0.25,0.95000005,0.6734773,0.33673865 +0.35,0.05,0.3,0.3 +0.35000002,0.04999999,0.21213205,0.42426407 +0.34999996,0.049999997,0.42426404,0.21213204 +0.35000002,0.049999997,0.37797633,0.37797633 +0.35,0.050000004,0.2672696,0.5345392 +0.35000002,0.049999997,0.5345392,0.2672696 +0.35,0.050000004,0.4762203,0.4762203 +0.35000002,0.049999997,0.33673862,0.6734772 +0.35,0.05000001,0.67347723,0.33673862 +0.35,0.15,0.3,0.3 +0.35000002,0.14999999,0.21213205,0.42426404 +0.34999996,0.15,0.42426404,0.21213204 +0.35000002,0.15,0.37797633,0.3779763 +0.35,0.15,0.2672696,0.5345392 +0.35000002,0.15,0.5345392,0.2672696 +0.35,0.15,0.4762203,0.4762203 +0.35000002,0.15,0.33673862,0.67347723 +0.35,0.15,0.67347723,0.33673865 +0.35,0.25,0.3,0.3 +0.35000002,0.25,0.21213205,0.42426407 +0.34999996,0.25,0.42426404,0.21213204 +0.35000002,0.25,0.37797633,0.3779763 +0.35,0.25,0.2672696,0.5345392 +0.35000002,0.25,0.5345392,0.2672696 +0.35,0.25,0.4762203,0.4762203 +0.35000002,0.25,0.33673862,0.6734773 +0.35,0.25,0.67347723,0.3367386 +0.35,0.35,0.3,0.3 +0.35000002,0.34999996,0.21213205,0.42426404 +0.34999996,0.35000002,0.42426404,0.21213205 +0.35000002,0.35000002,0.37797633,0.37797633 +0.35,0.35000002,0.2672696,0.5345392 +0.35000002,0.35,0.5345392,0.2672696 +0.35,0.35,0.4762203,0.4762203 +0.35000002,0.35,0.33673862,0.67347723 +0.35,0.35000002,0.67347723,0.33673862 +0.35,0.45000002,0.3,0.3 +0.35000002,0.45,0.21213205,0.42426404 +0.34999996,0.45000002,0.42426404,0.21213204 +0.35000002,0.45,0.37797633,0.3779763 +0.35,0.45,0.2672696,0.5345392 +0.35000002,0.45,0.5345392,0.2672696 +0.35,0.45,0.4762203,0.47622034 +0.35000002,0.45000002,0.33673862,0.67347723 +0.35,0.45,0.67347723,0.3367386 +0.35,0.55,0.3,0.29999998 +0.35000002,0.55,0.21213205,0.42426407 +0.34999996,0.55,0.42426404,0.2121321 +0.35000002,0.55,0.37797633,0.37797633 +0.35,0.55,0.2672696,0.5345392 +0.35000002,0.55,0.5345392,0.2672696 +0.35,0.54999995,0.4762203,0.4762203 +0.35000002,0.55,0.33673862,0.6734772 +0.35,0.55,0.67347723,0.33673862 +0.35,0.65,0.3,0.3 +0.35000002,0.65000004,0.21213205,0.4242641 +0.34999996,0.65,0.42426404,0.21213204 +0.35000002,0.65,0.37797633,0.3779763 +0.35,0.65,0.2672696,0.5345392 +0.35000002,0.65,0.5345392,0.2672696 +0.35,0.65,0.4762203,0.4762203 +0.35000002,0.65,0.33673862,0.6734772 +0.35,0.65,0.67347723,0.33673856 +0.35,0.75,0.3,0.29999995 +0.35000002,0.75,0.21213205,0.42426413 +0.34999996,0.75,0.42426404,0.2121321 +0.35000002,0.75,0.37797633,0.37797624 +0.35,0.75,0.2672696,0.5345392 +0.35000002,0.75,0.5345392,0.26726967 +0.35,0.75,0.4762203,0.47622037 +0.35000002,0.75,0.33673862,0.67347723 +0.35,0.75,0.67347723,0.3367386 +0.35,0.85,0.3,0.3 +0.35000002,0.85,0.21213205,0.42426413 +0.34999996,0.85,0.42426404,0.21213204 +0.35000002,0.84999996,0.37797633,0.3779763 +0.35,0.85,0.2672696,0.5345392 +0.35000002,0.85,0.5345392,0.2672696 +0.35,0.85,0.4762203,0.47622037 +0.35000002,0.85,0.33673862,0.67347723 +0.35,0.85,0.67347723,0.3367386 +0.35,0.95000005,0.3,0.3 +0.35000002,0.95,0.21213205,0.42426407 +0.34999996,0.95,0.42426404,0.2121321 +0.35000002,0.95,0.37797633,0.3779763 +0.35,0.95000005,0.2672696,0.5345393 +0.35000002,0.95,0.5345392,0.26726973 +0.35,0.95,0.4762203,0.47622025 +0.35000002,0.95,0.33673862,0.6734773 +0.35,0.95000005,0.67347723,0.33673865 +0.45000002,0.05,0.3,0.3 +0.45000002,0.04999999,0.21213204,0.42426407 +0.45,0.049999997,0.42426404,0.21213204 +0.45,0.049999997,0.3779763,0.37797633 +0.45,0.050000004,0.2672696,0.5345392 +0.45,0.049999997,0.5345392,0.2672696 +0.45,0.050000004,0.47622034,0.4762203 +0.45,0.049999997,0.3367386,0.6734772 +0.45000002,0.05000001,0.67347723,0.33673862 +0.45000002,0.15,0.3,0.3 +0.45000002,0.14999999,0.21213204,0.42426404 +0.45,0.15,0.42426404,0.21213204 +0.45,0.15,0.3779763,0.3779763 +0.45,0.15,0.2672696,0.5345392 +0.45,0.15,0.5345392,0.2672696 +0.45,0.15,0.47622034,0.4762203 +0.45,0.15,0.3367386,0.67347723 +0.45000002,0.15,0.67347723,0.33673865 +0.45000002,0.25,0.3,0.3 +0.45000002,0.25,0.21213204,0.42426407 +0.45,0.25,0.42426404,0.21213204 +0.45,0.25,0.3779763,0.3779763 +0.45,0.25,0.2672696,0.5345392 +0.45,0.25,0.5345392,0.2672696 +0.45,0.25,0.47622034,0.4762203 +0.45,0.25,0.3367386,0.6734773 +0.45000002,0.25,0.67347723,0.3367386 +0.45000002,0.35,0.3,0.3 +0.45000002,0.34999996,0.21213204,0.42426404 +0.45,0.35000002,0.42426404,0.21213205 +0.45,0.35000002,0.3779763,0.37797633 +0.45,0.35000002,0.2672696,0.5345392 +0.45,0.35,0.5345392,0.2672696 +0.45,0.35,0.47622034,0.4762203 +0.45,0.35,0.3367386,0.67347723 +0.45000002,0.35000002,0.67347723,0.33673862 +0.45000002,0.45000002,0.3,0.3 +0.45000002,0.45,0.21213204,0.42426404 +0.45,0.45000002,0.42426404,0.21213204 +0.45,0.45,0.3779763,0.3779763 +0.45,0.45,0.2672696,0.5345392 +0.45,0.45,0.5345392,0.2672696 +0.45,0.45,0.47622034,0.47622034 +0.45,0.45000002,0.3367386,0.67347723 +0.45000002,0.45,0.67347723,0.3367386 +0.45000002,0.55,0.3,0.29999998 +0.45000002,0.55,0.21213204,0.42426407 +0.45,0.55,0.42426404,0.2121321 +0.45,0.55,0.3779763,0.37797633 +0.45,0.55,0.2672696,0.5345392 +0.45,0.55,0.5345392,0.2672696 +0.45,0.54999995,0.47622034,0.4762203 +0.45,0.55,0.3367386,0.6734772 +0.45000002,0.55,0.67347723,0.33673862 +0.45000002,0.65,0.3,0.3 +0.45000002,0.65000004,0.21213204,0.4242641 +0.45,0.65,0.42426404,0.21213204 +0.45,0.65,0.3779763,0.3779763 +0.45,0.65,0.2672696,0.5345392 +0.45,0.65,0.5345392,0.2672696 +0.45,0.65,0.47622034,0.4762203 +0.45,0.65,0.3367386,0.6734772 +0.45000002,0.65,0.67347723,0.33673856 +0.45000002,0.75,0.3,0.29999995 +0.45000002,0.75,0.21213204,0.42426413 +0.45,0.75,0.42426404,0.2121321 +0.45,0.75,0.3779763,0.37797624 +0.45,0.75,0.2672696,0.5345392 +0.45,0.75,0.5345392,0.26726967 +0.45,0.75,0.47622034,0.47622037 +0.45,0.75,0.3367386,0.67347723 +0.45000002,0.75,0.67347723,0.3367386 +0.45000002,0.85,0.3,0.3 +0.45000002,0.85,0.21213204,0.42426413 +0.45,0.85,0.42426404,0.21213204 +0.45,0.84999996,0.3779763,0.3779763 +0.45,0.85,0.2672696,0.5345392 +0.45,0.85,0.5345392,0.2672696 +0.45,0.85,0.47622034,0.47622037 +0.45,0.85,0.3367386,0.67347723 +0.45000002,0.85,0.67347723,0.3367386 +0.45000002,0.95000005,0.3,0.3 +0.45000002,0.95,0.21213204,0.42426407 +0.45,0.95,0.42426404,0.2121321 +0.45,0.95,0.3779763,0.3779763 +0.45,0.95000005,0.2672696,0.5345393 +0.45,0.95,0.5345392,0.26726973 +0.45,0.95,0.47622034,0.47622025 +0.45,0.95,0.3367386,0.6734773 +0.45000002,0.95000005,0.67347723,0.33673865 +0.55,0.05,0.29999998,0.3 +0.55,0.04999999,0.2121321,0.42426407 +0.55,0.049999997,0.42426407,0.21213204 +0.55,0.049999997,0.37797633,0.37797633 +0.55,0.050000004,0.2672696,0.5345392 +0.55,0.049999997,0.5345392,0.2672696 +0.54999995,0.050000004,0.4762203,0.4762203 +0.55,0.049999997,0.33673862,0.6734772 +0.55,0.05000001,0.6734772,0.33673862 +0.55,0.15,0.29999998,0.3 +0.55,0.14999999,0.2121321,0.42426404 +0.55,0.15,0.42426407,0.21213204 +0.55,0.15,0.37797633,0.3779763 +0.55,0.15,0.2672696,0.5345392 +0.55,0.15,0.5345392,0.2672696 +0.54999995,0.15,0.4762203,0.4762203 +0.55,0.15,0.33673862,0.67347723 +0.55,0.15,0.6734772,0.33673865 +0.55,0.25,0.29999998,0.3 +0.55,0.25,0.2121321,0.42426407 +0.55,0.25,0.42426407,0.21213204 +0.55,0.25,0.37797633,0.3779763 +0.55,0.25,0.2672696,0.5345392 +0.55,0.25,0.5345392,0.2672696 +0.54999995,0.25,0.4762203,0.4762203 +0.55,0.25,0.33673862,0.6734773 +0.55,0.25,0.6734772,0.3367386 +0.55,0.35,0.29999998,0.3 +0.55,0.34999996,0.2121321,0.42426404 +0.55,0.35000002,0.42426407,0.21213205 +0.55,0.35000002,0.37797633,0.37797633 +0.55,0.35000002,0.2672696,0.5345392 +0.55,0.35,0.5345392,0.2672696 +0.54999995,0.35,0.4762203,0.4762203 +0.55,0.35,0.33673862,0.67347723 +0.55,0.35000002,0.6734772,0.33673862 +0.55,0.45000002,0.29999998,0.3 +0.55,0.45,0.2121321,0.42426404 +0.55,0.45000002,0.42426407,0.21213204 +0.55,0.45,0.37797633,0.3779763 +0.55,0.45,0.2672696,0.5345392 +0.55,0.45,0.5345392,0.2672696 +0.54999995,0.45,0.4762203,0.47622034 +0.55,0.45000002,0.33673862,0.67347723 +0.55,0.45,0.6734772,0.3367386 +0.55,0.55,0.29999998,0.29999998 +0.55,0.55,0.2121321,0.42426407 +0.55,0.55,0.42426407,0.2121321 +0.55,0.55,0.37797633,0.37797633 +0.55,0.55,0.2672696,0.5345392 +0.55,0.55,0.5345392,0.2672696 +0.54999995,0.54999995,0.4762203,0.4762203 +0.55,0.55,0.33673862,0.6734772 +0.55,0.55,0.6734772,0.33673862 +0.55,0.65,0.29999998,0.3 +0.55,0.65000004,0.2121321,0.4242641 +0.55,0.65,0.42426407,0.21213204 +0.55,0.65,0.37797633,0.3779763 +0.55,0.65,0.2672696,0.5345392 +0.55,0.65,0.5345392,0.2672696 +0.54999995,0.65,0.4762203,0.4762203 +0.55,0.65,0.33673862,0.6734772 +0.55,0.65,0.6734772,0.33673856 +0.55,0.75,0.29999998,0.29999995 +0.55,0.75,0.2121321,0.42426413 +0.55,0.75,0.42426407,0.2121321 +0.55,0.75,0.37797633,0.37797624 +0.55,0.75,0.2672696,0.5345392 +0.55,0.75,0.5345392,0.26726967 +0.54999995,0.75,0.4762203,0.47622037 +0.55,0.75,0.33673862,0.67347723 +0.55,0.75,0.6734772,0.3367386 +0.55,0.85,0.29999998,0.3 +0.55,0.85,0.2121321,0.42426413 +0.55,0.85,0.42426407,0.21213204 +0.55,0.84999996,0.37797633,0.3779763 +0.55,0.85,0.2672696,0.5345392 +0.55,0.85,0.5345392,0.2672696 +0.54999995,0.85,0.4762203,0.47622037 +0.55,0.85,0.33673862,0.67347723 +0.55,0.85,0.6734772,0.3367386 +0.55,0.95000005,0.29999998,0.3 +0.55,0.95,0.2121321,0.42426407 +0.55,0.95,0.42426407,0.2121321 +0.55,0.95,0.37797633,0.3779763 +0.55,0.95000005,0.2672696,0.5345393 +0.55,0.95,0.5345392,0.26726973 +0.54999995,0.95,0.4762203,0.47622025 +0.55,0.95,0.33673862,0.6734773 +0.55,0.95000005,0.6734772,0.33673865 +0.65,0.05,0.3,0.3 +0.65,0.04999999,0.21213204,0.42426407 +0.65000004,0.049999997,0.4242641,0.21213204 +0.65,0.049999997,0.3779763,0.37797633 +0.65,0.050000004,0.2672696,0.5345392 +0.65,0.049999997,0.5345392,0.2672696 +0.65,0.050000004,0.4762203,0.4762203 +0.65,0.049999997,0.33673856,0.6734772 +0.65,0.05000001,0.6734772,0.33673862 +0.65,0.15,0.3,0.3 +0.65,0.14999999,0.21213204,0.42426404 +0.65000004,0.15,0.4242641,0.21213204 +0.65,0.15,0.3779763,0.3779763 +0.65,0.15,0.2672696,0.5345392 +0.65,0.15,0.5345392,0.2672696 +0.65,0.15,0.4762203,0.4762203 +0.65,0.15,0.33673856,0.67347723 +0.65,0.15,0.6734772,0.33673865 +0.65,0.25,0.3,0.3 +0.65,0.25,0.21213204,0.42426407 +0.65000004,0.25,0.4242641,0.21213204 +0.65,0.25,0.3779763,0.3779763 +0.65,0.25,0.2672696,0.5345392 +0.65,0.25,0.5345392,0.2672696 +0.65,0.25,0.4762203,0.4762203 +0.65,0.25,0.33673856,0.6734773 +0.65,0.25,0.6734772,0.3367386 +0.65,0.35,0.3,0.3 +0.65,0.34999996,0.21213204,0.42426404 +0.65000004,0.35000002,0.4242641,0.21213205 +0.65,0.35000002,0.3779763,0.37797633 +0.65,0.35000002,0.2672696,0.5345392 +0.65,0.35,0.5345392,0.2672696 +0.65,0.35,0.4762203,0.4762203 +0.65,0.35,0.33673856,0.67347723 +0.65,0.35000002,0.6734772,0.33673862 +0.65,0.45000002,0.3,0.3 +0.65,0.45,0.21213204,0.42426404 +0.65000004,0.45000002,0.4242641,0.21213204 +0.65,0.45,0.3779763,0.3779763 +0.65,0.45,0.2672696,0.5345392 +0.65,0.45,0.5345392,0.2672696 +0.65,0.45,0.4762203,0.47622034 +0.65,0.45000002,0.33673856,0.67347723 +0.65,0.45,0.6734772,0.3367386 +0.65,0.55,0.3,0.29999998 +0.65,0.55,0.21213204,0.42426407 +0.65000004,0.55,0.4242641,0.2121321 +0.65,0.55,0.3779763,0.37797633 +0.65,0.55,0.2672696,0.5345392 +0.65,0.55,0.5345392,0.2672696 +0.65,0.54999995,0.4762203,0.4762203 +0.65,0.55,0.33673856,0.6734772 +0.65,0.55,0.6734772,0.33673862 +0.65,0.65,0.3,0.3 +0.65,0.65000004,0.21213204,0.4242641 +0.65000004,0.65,0.4242641,0.21213204 +0.65,0.65,0.3779763,0.3779763 +0.65,0.65,0.2672696,0.5345392 +0.65,0.65,0.5345392,0.2672696 +0.65,0.65,0.4762203,0.4762203 +0.65,0.65,0.33673856,0.6734772 +0.65,0.65,0.6734772,0.33673856 +0.65,0.75,0.3,0.29999995 +0.65,0.75,0.21213204,0.42426413 +0.65000004,0.75,0.4242641,0.2121321 +0.65,0.75,0.3779763,0.37797624 +0.65,0.75,0.2672696,0.5345392 +0.65,0.75,0.5345392,0.26726967 +0.65,0.75,0.4762203,0.47622037 +0.65,0.75,0.33673856,0.67347723 +0.65,0.75,0.6734772,0.3367386 +0.65,0.85,0.3,0.3 +0.65,0.85,0.21213204,0.42426413 +0.65000004,0.85,0.4242641,0.21213204 +0.65,0.84999996,0.3779763,0.3779763 +0.65,0.85,0.2672696,0.5345392 +0.65,0.85,0.5345392,0.2672696 +0.65,0.85,0.4762203,0.47622037 +0.65,0.85,0.33673856,0.67347723 +0.65,0.85,0.6734772,0.3367386 +0.65,0.95000005,0.3,0.3 +0.65,0.95,0.21213204,0.42426407 +0.65000004,0.95,0.4242641,0.2121321 +0.65,0.95,0.3779763,0.3779763 +0.65,0.95000005,0.2672696,0.5345393 +0.65,0.95,0.5345392,0.26726973 +0.65,0.95,0.4762203,0.47622025 +0.65,0.95,0.33673856,0.6734773 +0.65,0.95000005,0.6734772,0.33673865 +0.75,0.05,0.29999995,0.3 +0.75,0.04999999,0.2121321,0.42426407 +0.75,0.049999997,0.42426413,0.21213204 +0.75,0.049999997,0.37797624,0.37797633 +0.75,0.050000004,0.26726967,0.5345392 +0.75,0.049999997,0.5345392,0.2672696 +0.75,0.050000004,0.47622037,0.4762203 +0.75,0.049999997,0.3367386,0.6734772 +0.75,0.05000001,0.67347723,0.33673862 +0.75,0.15,0.29999995,0.3 +0.75,0.14999999,0.2121321,0.42426404 +0.75,0.15,0.42426413,0.21213204 +0.75,0.15,0.37797624,0.3779763 +0.75,0.15,0.26726967,0.5345392 +0.75,0.15,0.5345392,0.2672696 +0.75,0.15,0.47622037,0.4762203 +0.75,0.15,0.3367386,0.67347723 +0.75,0.15,0.67347723,0.33673865 +0.75,0.25,0.29999995,0.3 +0.75,0.25,0.2121321,0.42426407 +0.75,0.25,0.42426413,0.21213204 +0.75,0.25,0.37797624,0.3779763 +0.75,0.25,0.26726967,0.5345392 +0.75,0.25,0.5345392,0.2672696 +0.75,0.25,0.47622037,0.4762203 +0.75,0.25,0.3367386,0.6734773 +0.75,0.25,0.67347723,0.3367386 +0.75,0.35,0.29999995,0.3 +0.75,0.34999996,0.2121321,0.42426404 +0.75,0.35000002,0.42426413,0.21213205 +0.75,0.35000002,0.37797624,0.37797633 +0.75,0.35000002,0.26726967,0.5345392 +0.75,0.35,0.5345392,0.2672696 +0.75,0.35,0.47622037,0.4762203 +0.75,0.35,0.3367386,0.67347723 +0.75,0.35000002,0.67347723,0.33673862 +0.75,0.45000002,0.29999995,0.3 +0.75,0.45,0.2121321,0.42426404 +0.75,0.45000002,0.42426413,0.21213204 +0.75,0.45,0.37797624,0.3779763 +0.75,0.45,0.26726967,0.5345392 +0.75,0.45,0.5345392,0.2672696 +0.75,0.45,0.47622037,0.47622034 +0.75,0.45000002,0.3367386,0.67347723 +0.75,0.45,0.67347723,0.3367386 +0.75,0.55,0.29999995,0.29999998 +0.75,0.55,0.2121321,0.42426407 +0.75,0.55,0.42426413,0.2121321 +0.75,0.55,0.37797624,0.37797633 +0.75,0.55,0.26726967,0.5345392 +0.75,0.55,0.5345392,0.2672696 +0.75,0.54999995,0.47622037,0.4762203 +0.75,0.55,0.3367386,0.6734772 +0.75,0.55,0.67347723,0.33673862 +0.75,0.65,0.29999995,0.3 +0.75,0.65000004,0.2121321,0.4242641 +0.75,0.65,0.42426413,0.21213204 +0.75,0.65,0.37797624,0.3779763 +0.75,0.65,0.26726967,0.5345392 +0.75,0.65,0.5345392,0.2672696 +0.75,0.65,0.47622037,0.4762203 +0.75,0.65,0.3367386,0.6734772 +0.75,0.65,0.67347723,0.33673856 +0.75,0.75,0.29999995,0.29999995 +0.75,0.75,0.2121321,0.42426413 +0.75,0.75,0.42426413,0.2121321 +0.75,0.75,0.37797624,0.37797624 +0.75,0.75,0.26726967,0.5345392 +0.75,0.75,0.5345392,0.26726967 +0.75,0.75,0.47622037,0.47622037 +0.75,0.75,0.3367386,0.67347723 +0.75,0.75,0.67347723,0.3367386 +0.75,0.85,0.29999995,0.3 +0.75,0.85,0.2121321,0.42426413 +0.75,0.85,0.42426413,0.21213204 +0.75,0.84999996,0.37797624,0.3779763 +0.75,0.85,0.26726967,0.5345392 +0.75,0.85,0.5345392,0.2672696 +0.75,0.85,0.47622037,0.47622037 +0.75,0.85,0.3367386,0.67347723 +0.75,0.85,0.67347723,0.3367386 +0.75,0.95000005,0.29999995,0.3 +0.75,0.95,0.2121321,0.42426407 +0.75,0.95,0.42426413,0.2121321 +0.75,0.95,0.37797624,0.3779763 +0.75,0.95000005,0.26726967,0.5345393 +0.75,0.95,0.5345392,0.26726973 +0.75,0.95,0.47622037,0.47622025 +0.75,0.95,0.3367386,0.6734773 +0.75,0.95000005,0.67347723,0.33673865 +0.85,0.05,0.3,0.3 +0.85,0.04999999,0.21213204,0.42426407 +0.85,0.049999997,0.42426413,0.21213204 +0.84999996,0.049999997,0.3779763,0.37797633 +0.85,0.050000004,0.2672696,0.5345392 +0.85,0.049999997,0.5345392,0.2672696 +0.85,0.050000004,0.47622037,0.4762203 +0.85,0.049999997,0.3367386,0.6734772 +0.85,0.05000001,0.67347723,0.33673862 +0.85,0.15,0.3,0.3 +0.85,0.14999999,0.21213204,0.42426404 +0.85,0.15,0.42426413,0.21213204 +0.84999996,0.15,0.3779763,0.3779763 +0.85,0.15,0.2672696,0.5345392 +0.85,0.15,0.5345392,0.2672696 +0.85,0.15,0.47622037,0.4762203 +0.85,0.15,0.3367386,0.67347723 +0.85,0.15,0.67347723,0.33673865 +0.85,0.25,0.3,0.3 +0.85,0.25,0.21213204,0.42426407 +0.85,0.25,0.42426413,0.21213204 +0.84999996,0.25,0.3779763,0.3779763 +0.85,0.25,0.2672696,0.5345392 +0.85,0.25,0.5345392,0.2672696 +0.85,0.25,0.47622037,0.4762203 +0.85,0.25,0.3367386,0.6734773 +0.85,0.25,0.67347723,0.3367386 +0.85,0.35,0.3,0.3 +0.85,0.34999996,0.21213204,0.42426404 +0.85,0.35000002,0.42426413,0.21213205 +0.84999996,0.35000002,0.3779763,0.37797633 +0.85,0.35000002,0.2672696,0.5345392 +0.85,0.35,0.5345392,0.2672696 +0.85,0.35,0.47622037,0.4762203 +0.85,0.35,0.3367386,0.67347723 +0.85,0.35000002,0.67347723,0.33673862 +0.85,0.45000002,0.3,0.3 +0.85,0.45,0.21213204,0.42426404 +0.85,0.45000002,0.42426413,0.21213204 +0.84999996,0.45,0.3779763,0.3779763 +0.85,0.45,0.2672696,0.5345392 +0.85,0.45,0.5345392,0.2672696 +0.85,0.45,0.47622037,0.47622034 +0.85,0.45000002,0.3367386,0.67347723 +0.85,0.45,0.67347723,0.3367386 +0.85,0.55,0.3,0.29999998 +0.85,0.55,0.21213204,0.42426407 +0.85,0.55,0.42426413,0.2121321 +0.84999996,0.55,0.3779763,0.37797633 +0.85,0.55,0.2672696,0.5345392 +0.85,0.55,0.5345392,0.2672696 +0.85,0.54999995,0.47622037,0.4762203 +0.85,0.55,0.3367386,0.6734772 +0.85,0.55,0.67347723,0.33673862 +0.85,0.65,0.3,0.3 +0.85,0.65000004,0.21213204,0.4242641 +0.85,0.65,0.42426413,0.21213204 +0.84999996,0.65,0.3779763,0.3779763 +0.85,0.65,0.2672696,0.5345392 +0.85,0.65,0.5345392,0.2672696 +0.85,0.65,0.47622037,0.4762203 +0.85,0.65,0.3367386,0.6734772 +0.85,0.65,0.67347723,0.33673856 +0.85,0.75,0.3,0.29999995 +0.85,0.75,0.21213204,0.42426413 +0.85,0.75,0.42426413,0.2121321 +0.84999996,0.75,0.3779763,0.37797624 +0.85,0.75,0.2672696,0.5345392 +0.85,0.75,0.5345392,0.26726967 +0.85,0.75,0.47622037,0.47622037 +0.85,0.75,0.3367386,0.67347723 +0.85,0.75,0.67347723,0.3367386 +0.85,0.85,0.3,0.3 +0.85,0.85,0.21213204,0.42426413 +0.85,0.85,0.42426413,0.21213204 +0.84999996,0.84999996,0.3779763,0.3779763 +0.85,0.85,0.2672696,0.5345392 +0.85,0.85,0.5345392,0.2672696 +0.85,0.85,0.47622037,0.47622037 +0.85,0.85,0.3367386,0.67347723 +0.85,0.85,0.67347723,0.3367386 +0.85,0.95000005,0.3,0.3 +0.85,0.95,0.21213204,0.42426407 +0.85,0.95,0.42426413,0.2121321 +0.84999996,0.95,0.3779763,0.3779763 +0.85,0.95000005,0.2672696,0.5345393 +0.85,0.95,0.5345392,0.26726973 +0.85,0.95,0.47622037,0.47622025 +0.85,0.95,0.3367386,0.6734773 +0.85,0.95000005,0.67347723,0.33673865 +0.95000005,0.05,0.3,0.3 +0.95,0.04999999,0.2121321,0.42426407 +0.95,0.049999997,0.42426407,0.21213204 +0.95,0.049999997,0.3779763,0.37797633 +0.95,0.050000004,0.26726973,0.5345392 +0.95000005,0.049999997,0.5345393,0.2672696 +0.95,0.050000004,0.47622025,0.4762203 +0.95000005,0.049999997,0.33673865,0.6734772 +0.95,0.05000001,0.6734773,0.33673862 +0.95000005,0.15,0.3,0.3 +0.95,0.14999999,0.2121321,0.42426404 +0.95,0.15,0.42426407,0.21213204 +0.95,0.15,0.3779763,0.3779763 +0.95,0.15,0.26726973,0.5345392 +0.95000005,0.15,0.5345393,0.2672696 +0.95,0.15,0.47622025,0.4762203 +0.95000005,0.15,0.33673865,0.67347723 +0.95,0.15,0.6734773,0.33673865 +0.95000005,0.25,0.3,0.3 +0.95,0.25,0.2121321,0.42426407 +0.95,0.25,0.42426407,0.21213204 +0.95,0.25,0.3779763,0.3779763 +0.95,0.25,0.26726973,0.5345392 +0.95000005,0.25,0.5345393,0.2672696 +0.95,0.25,0.47622025,0.4762203 +0.95000005,0.25,0.33673865,0.6734773 +0.95,0.25,0.6734773,0.3367386 +0.95000005,0.35,0.3,0.3 +0.95,0.34999996,0.2121321,0.42426404 +0.95,0.35000002,0.42426407,0.21213205 +0.95,0.35000002,0.3779763,0.37797633 +0.95,0.35000002,0.26726973,0.5345392 +0.95000005,0.35,0.5345393,0.2672696 +0.95,0.35,0.47622025,0.4762203 +0.95000005,0.35,0.33673865,0.67347723 +0.95,0.35000002,0.6734773,0.33673862 +0.95000005,0.45000002,0.3,0.3 +0.95,0.45,0.2121321,0.42426404 +0.95,0.45000002,0.42426407,0.21213204 +0.95,0.45,0.3779763,0.3779763 +0.95,0.45,0.26726973,0.5345392 +0.95000005,0.45,0.5345393,0.2672696 +0.95,0.45,0.47622025,0.47622034 +0.95000005,0.45000002,0.33673865,0.67347723 +0.95,0.45,0.6734773,0.3367386 +0.95000005,0.55,0.3,0.29999998 +0.95,0.55,0.2121321,0.42426407 +0.95,0.55,0.42426407,0.2121321 +0.95,0.55,0.3779763,0.37797633 +0.95,0.55,0.26726973,0.5345392 +0.95000005,0.55,0.5345393,0.2672696 +0.95,0.54999995,0.47622025,0.4762203 +0.95000005,0.55,0.33673865,0.6734772 +0.95,0.55,0.6734773,0.33673862 +0.95000005,0.65,0.3,0.3 +0.95,0.65000004,0.2121321,0.4242641 +0.95,0.65,0.42426407,0.21213204 +0.95,0.65,0.3779763,0.3779763 +0.95,0.65,0.26726973,0.5345392 +0.95000005,0.65,0.5345393,0.2672696 +0.95,0.65,0.47622025,0.4762203 +0.95000005,0.65,0.33673865,0.6734772 +0.95,0.65,0.6734773,0.33673856 +0.95000005,0.75,0.3,0.29999995 +0.95,0.75,0.2121321,0.42426413 +0.95,0.75,0.42426407,0.2121321 +0.95,0.75,0.3779763,0.37797624 +0.95,0.75,0.26726973,0.5345392 +0.95000005,0.75,0.5345393,0.26726967 +0.95,0.75,0.47622025,0.47622037 +0.95000005,0.75,0.33673865,0.67347723 +0.95,0.75,0.6734773,0.3367386 +0.95000005,0.85,0.3,0.3 +0.95,0.85,0.2121321,0.42426413 +0.95,0.85,0.42426407,0.21213204 +0.95,0.84999996,0.3779763,0.3779763 +0.95,0.85,0.26726973,0.5345392 +0.95000005,0.85,0.5345393,0.2672696 +0.95,0.85,0.47622025,0.47622037 +0.95000005,0.85,0.33673865,0.67347723 +0.95,0.85,0.6734773,0.3367386 +0.95000005,0.95000005,0.3,0.3 +0.95,0.95,0.2121321,0.42426407 +0.95,0.95,0.42426407,0.2121321 +0.95,0.95,0.3779763,0.3779763 +0.95,0.95000005,0.26726973,0.5345393 +0.95000005,0.95,0.5345393,0.26726973 +0.95,0.95,0.47622025,0.47622025 +0.95000005,0.95,0.33673865,0.6734773 +0.95,0.95000005,0.6734773,0.33673865 +0.1,0.1,0.6,0.6 +0.099999994,0.09999998,0.42426407,0.84852815 +0.09999998,0.099999994,0.84852815,0.42426407 +0.099999994,0.099999994,0.75595266,0.75595266 +0.099999994,0.10000001,0.5345392,1.0690784 +0.10000001,0.099999994,1.0690784,0.5345392 +0.10000001,0.10000001,0.9524406,0.9524406 +0.10000002,0.099999994,0.67347723,1.3469543 +0.099999994,0.10000002,1.3469543,0.67347723 +0.1,0.3,0.6,0.6 +0.099999994,0.29999998,0.42426407,0.8485281 +0.09999998,0.3,0.84852815,0.42426407 +0.099999994,0.3,0.75595266,0.7559526 +0.099999994,0.3,0.5345392,1.0690784 +0.10000001,0.3,1.0690784,0.5345392 +0.10000001,0.3,0.9524406,0.9524406 +0.10000002,0.3,0.67347723,1.3469545 +0.099999994,0.3,1.3469543,0.6734773 +0.1,0.5,0.6,0.6 +0.099999994,0.5,0.42426407,0.84852815 +0.09999998,0.5,0.84852815,0.42426407 +0.099999994,0.5,0.75595266,0.7559526 +0.099999994,0.5,0.5345392,1.0690784 +0.10000001,0.5,1.0690784,0.5345392 +0.10000001,0.5,0.9524406,0.9524406 +0.10000002,0.5,0.67347723,1.3469546 +0.099999994,0.5,1.3469543,0.6734772 +0.1,0.7,0.6,0.6 +0.099999994,0.6999999,0.42426407,0.8485281 +0.09999998,0.70000005,0.84852815,0.4242641 +0.099999994,0.70000005,0.75595266,0.75595266 +0.099999994,0.70000005,0.5345392,1.0690784 +0.10000001,0.7,1.0690784,0.5345392 +0.10000001,0.7,0.9524406,0.9524406 +0.10000002,0.7,0.67347723,1.3469545 +0.099999994,0.70000005,1.3469543,0.67347723 +0.1,0.90000004,0.6,0.6 +0.099999994,0.9,0.42426407,0.8485281 +0.09999998,0.90000004,0.84852815,0.42426407 +0.099999994,0.9,0.75595266,0.7559526 +0.099999994,0.9,0.5345392,1.0690784 +0.10000001,0.9,1.0690784,0.5345392 +0.10000001,0.9,0.9524406,0.9524407 +0.10000002,0.90000004,0.67347723,1.3469545 +0.099999994,0.9,1.3469543,0.6734772 +0.3,0.1,0.6,0.6 +0.3,0.09999998,0.42426407,0.84852815 +0.29999998,0.099999994,0.8485281,0.42426407 +0.3,0.099999994,0.7559526,0.75595266 +0.3,0.10000001,0.5345392,1.0690784 +0.3,0.099999994,1.0690784,0.5345392 +0.3,0.10000001,0.9524406,0.9524406 +0.3,0.099999994,0.6734773,1.3469543 +0.3,0.10000002,1.3469545,0.67347723 +0.3,0.3,0.6,0.6 +0.3,0.29999998,0.42426407,0.8485281 +0.29999998,0.3,0.8485281,0.42426407 +0.3,0.3,0.7559526,0.7559526 +0.3,0.3,0.5345392,1.0690784 +0.3,0.3,1.0690784,0.5345392 +0.3,0.3,0.9524406,0.9524406 +0.3,0.3,0.6734773,1.3469545 +0.3,0.3,1.3469545,0.6734773 +0.3,0.5,0.6,0.6 +0.3,0.5,0.42426407,0.84852815 +0.29999998,0.5,0.8485281,0.42426407 +0.3,0.5,0.7559526,0.7559526 +0.3,0.5,0.5345392,1.0690784 +0.3,0.5,1.0690784,0.5345392 +0.3,0.5,0.9524406,0.9524406 +0.3,0.5,0.6734773,1.3469546 +0.3,0.5,1.3469545,0.6734772 +0.3,0.7,0.6,0.6 +0.3,0.6999999,0.42426407,0.8485281 +0.29999998,0.70000005,0.8485281,0.4242641 +0.3,0.70000005,0.7559526,0.75595266 +0.3,0.70000005,0.5345392,1.0690784 +0.3,0.7,1.0690784,0.5345392 +0.3,0.7,0.9524406,0.9524406 +0.3,0.7,0.6734773,1.3469545 +0.3,0.70000005,1.3469545,0.67347723 +0.3,0.90000004,0.6,0.6 +0.3,0.9,0.42426407,0.8485281 +0.29999998,0.90000004,0.8485281,0.42426407 +0.3,0.9,0.7559526,0.7559526 +0.3,0.9,0.5345392,1.0690784 +0.3,0.9,1.0690784,0.5345392 +0.3,0.9,0.9524406,0.9524407 +0.3,0.90000004,0.6734773,1.3469545 +0.3,0.9,1.3469545,0.6734772 +0.5,0.1,0.6,0.6 +0.5,0.09999998,0.42426407,0.84852815 +0.5,0.099999994,0.84852815,0.42426407 +0.5,0.099999994,0.7559526,0.75595266 +0.5,0.10000001,0.5345392,1.0690784 +0.5,0.099999994,1.0690784,0.5345392 +0.5,0.10000001,0.9524406,0.9524406 +0.5,0.099999994,0.6734772,1.3469543 +0.5,0.10000002,1.3469546,0.67347723 +0.5,0.3,0.6,0.6 +0.5,0.29999998,0.42426407,0.8485281 +0.5,0.3,0.84852815,0.42426407 +0.5,0.3,0.7559526,0.7559526 +0.5,0.3,0.5345392,1.0690784 +0.5,0.3,1.0690784,0.5345392 +0.5,0.3,0.9524406,0.9524406 +0.5,0.3,0.6734772,1.3469545 +0.5,0.3,1.3469546,0.6734773 +0.5,0.5,0.6,0.6 +0.5,0.5,0.42426407,0.84852815 +0.5,0.5,0.84852815,0.42426407 +0.5,0.5,0.7559526,0.7559526 +0.5,0.5,0.5345392,1.0690784 +0.5,0.5,1.0690784,0.5345392 +0.5,0.5,0.9524406,0.9524406 +0.5,0.5,0.6734772,1.3469546 +0.5,0.5,1.3469546,0.6734772 +0.5,0.7,0.6,0.6 +0.5,0.6999999,0.42426407,0.8485281 +0.5,0.70000005,0.84852815,0.4242641 +0.5,0.70000005,0.7559526,0.75595266 +0.5,0.70000005,0.5345392,1.0690784 +0.5,0.7,1.0690784,0.5345392 +0.5,0.7,0.9524406,0.9524406 +0.5,0.7,0.6734772,1.3469545 +0.5,0.70000005,1.3469546,0.67347723 +0.5,0.90000004,0.6,0.6 +0.5,0.9,0.42426407,0.8485281 +0.5,0.90000004,0.84852815,0.42426407 +0.5,0.9,0.7559526,0.7559526 +0.5,0.9,0.5345392,1.0690784 +0.5,0.9,1.0690784,0.5345392 +0.5,0.9,0.9524406,0.9524407 +0.5,0.90000004,0.6734772,1.3469545 +0.5,0.9,1.3469546,0.6734772 +0.7,0.1,0.6,0.6 +0.70000005,0.09999998,0.4242641,0.84852815 +0.6999999,0.099999994,0.8485281,0.42426407 +0.70000005,0.099999994,0.75595266,0.75595266 +0.7,0.10000001,0.5345392,1.0690784 +0.70000005,0.099999994,1.0690784,0.5345392 +0.7,0.10000001,0.9524406,0.9524406 +0.70000005,0.099999994,0.67347723,1.3469543 +0.7,0.10000002,1.3469545,0.67347723 +0.7,0.3,0.6,0.6 +0.70000005,0.29999998,0.4242641,0.8485281 +0.6999999,0.3,0.8485281,0.42426407 +0.70000005,0.3,0.75595266,0.7559526 +0.7,0.3,0.5345392,1.0690784 +0.70000005,0.3,1.0690784,0.5345392 +0.7,0.3,0.9524406,0.9524406 +0.70000005,0.3,0.67347723,1.3469545 +0.7,0.3,1.3469545,0.6734773 +0.7,0.5,0.6,0.6 +0.70000005,0.5,0.4242641,0.84852815 +0.6999999,0.5,0.8485281,0.42426407 +0.70000005,0.5,0.75595266,0.7559526 +0.7,0.5,0.5345392,1.0690784 +0.70000005,0.5,1.0690784,0.5345392 +0.7,0.5,0.9524406,0.9524406 +0.70000005,0.5,0.67347723,1.3469546 +0.7,0.5,1.3469545,0.6734772 +0.7,0.7,0.6,0.6 +0.70000005,0.6999999,0.4242641,0.8485281 +0.6999999,0.70000005,0.8485281,0.4242641 +0.70000005,0.70000005,0.75595266,0.75595266 +0.7,0.70000005,0.5345392,1.0690784 +0.70000005,0.7,1.0690784,0.5345392 +0.7,0.7,0.9524406,0.9524406 +0.70000005,0.7,0.67347723,1.3469545 +0.7,0.70000005,1.3469545,0.67347723 +0.7,0.90000004,0.6,0.6 +0.70000005,0.9,0.4242641,0.8485281 +0.6999999,0.90000004,0.8485281,0.42426407 +0.70000005,0.9,0.75595266,0.7559526 +0.7,0.9,0.5345392,1.0690784 +0.70000005,0.9,1.0690784,0.5345392 +0.7,0.9,0.9524406,0.9524407 +0.70000005,0.90000004,0.67347723,1.3469545 +0.7,0.9,1.3469545,0.6734772 +0.90000004,0.1,0.6,0.6 +0.90000004,0.09999998,0.42426407,0.84852815 +0.9,0.099999994,0.8485281,0.42426407 +0.9,0.099999994,0.7559526,0.75595266 +0.9,0.10000001,0.5345392,1.0690784 +0.9,0.099999994,1.0690784,0.5345392 +0.9,0.10000001,0.9524407,0.9524406 +0.9,0.099999994,0.6734772,1.3469543 +0.90000004,0.10000002,1.3469545,0.67347723 +0.90000004,0.3,0.6,0.6 +0.90000004,0.29999998,0.42426407,0.8485281 +0.9,0.3,0.8485281,0.42426407 +0.9,0.3,0.7559526,0.7559526 +0.9,0.3,0.5345392,1.0690784 +0.9,0.3,1.0690784,0.5345392 +0.9,0.3,0.9524407,0.9524406 +0.9,0.3,0.6734772,1.3469545 +0.90000004,0.3,1.3469545,0.6734773 +0.90000004,0.5,0.6,0.6 +0.90000004,0.5,0.42426407,0.84852815 +0.9,0.5,0.8485281,0.42426407 +0.9,0.5,0.7559526,0.7559526 +0.9,0.5,0.5345392,1.0690784 +0.9,0.5,1.0690784,0.5345392 +0.9,0.5,0.9524407,0.9524406 +0.9,0.5,0.6734772,1.3469546 +0.90000004,0.5,1.3469545,0.6734772 +0.90000004,0.7,0.6,0.6 +0.90000004,0.6999999,0.42426407,0.8485281 +0.9,0.70000005,0.8485281,0.4242641 +0.9,0.70000005,0.7559526,0.75595266 +0.9,0.70000005,0.5345392,1.0690784 +0.9,0.7,1.0690784,0.5345392 +0.9,0.7,0.9524407,0.9524406 +0.9,0.7,0.6734772,1.3469545 +0.90000004,0.70000005,1.3469545,0.67347723 +0.90000004,0.90000004,0.6,0.6 +0.90000004,0.9,0.42426407,0.8485281 +0.9,0.90000004,0.8485281,0.42426407 +0.9,0.9,0.7559526,0.7559526 +0.9,0.9,0.5345392,1.0690784 +0.9,0.9,1.0690784,0.5345392 +0.9,0.9,0.9524407,0.9524407 +0.9,0.90000004,0.6734772,1.3469545 +0.90000004,0.9,1.3469545,0.6734772 +0.16666666,0.16666666,0.99999994,0.99999994 +0.16666666,0.16666666,0.70710677,1.4142137 +0.16666666,0.16666666,1.4142137,0.70710677 +0.16666666,0.16666666,1.2599211,1.2599211 +0.16666664,0.16666669,0.8908987,1.7817975 +0.16666669,0.16666664,1.7817975,0.8908987 +0.16666669,0.16666669,1.587401,1.587401 +0.16666667,0.16666663,1.122462,2.244924 +0.16666663,0.16666667,2.244924,1.122462 +0.16666666,0.5,0.99999994,1.0 +0.16666666,0.5,0.70710677,1.4142137 +0.16666666,0.5,1.4142137,0.7071068 +0.16666666,0.5,1.2599211,1.2599211 +0.16666664,0.5,0.8908987,1.7817974 +0.16666669,0.5,1.7817975,0.8908987 +0.16666669,0.49999997,1.587401,1.5874009 +0.16666667,0.5,1.122462,2.244924 +0.16666663,0.5,2.244924,1.122462 +0.16666666,0.83333325,0.99999994,0.99999994 +0.16666666,0.8333333,0.70710677,1.4142135 +0.16666666,0.8333333,1.4142137,0.7071067 +0.16666666,0.8333333,1.2599211,1.259921 +0.16666664,0.8333334,0.8908987,1.7817974 +0.16666669,0.83333325,1.7817975,0.89089864 +0.16666669,0.8333333,1.587401,1.587401 +0.16666667,0.83333325,1.122462,2.244924 +0.16666663,0.8333334,2.244924,1.122462 +0.5,0.16666666,1.0,0.99999994 +0.5,0.16666666,0.7071068,1.4142137 +0.5,0.16666666,1.4142137,0.70710677 +0.5,0.16666666,1.2599211,1.2599211 +0.5,0.16666669,0.8908987,1.7817975 +0.5,0.16666664,1.7817974,0.8908987 +0.49999997,0.16666669,1.5874009,1.587401 +0.5,0.16666663,1.122462,2.244924 +0.5,0.16666667,2.244924,1.122462 +0.5,0.5,1.0,1.0 +0.5,0.5,0.7071068,1.4142137 +0.5,0.5,1.4142137,0.7071068 +0.5,0.5,1.2599211,1.2599211 +0.5,0.5,0.8908987,1.7817974 +0.5,0.5,1.7817974,0.8908987 +0.49999997,0.49999997,1.5874009,1.5874009 +0.5,0.5,1.122462,2.244924 +0.5,0.5,2.244924,1.122462 +0.5,0.83333325,1.0,0.99999994 +0.5,0.8333333,0.7071068,1.4142135 +0.5,0.8333333,1.4142137,0.7071067 +0.5,0.8333333,1.2599211,1.259921 +0.5,0.8333334,0.8908987,1.7817974 +0.5,0.83333325,1.7817974,0.89089864 +0.49999997,0.8333333,1.5874009,1.587401 +0.5,0.83333325,1.122462,2.244924 +0.5,0.8333334,2.244924,1.122462 +0.83333325,0.16666666,0.99999994,0.99999994 +0.8333333,0.16666666,0.7071067,1.4142137 +0.8333333,0.16666666,1.4142135,0.70710677 +0.8333333,0.16666666,1.259921,1.2599211 +0.83333325,0.16666669,0.89089864,1.7817975 +0.8333334,0.16666664,1.7817974,0.8908987 +0.8333333,0.16666669,1.587401,1.587401 +0.8333334,0.16666663,1.122462,2.244924 +0.83333325,0.16666667,2.244924,1.122462 +0.83333325,0.5,0.99999994,1.0 +0.8333333,0.5,0.7071067,1.4142137 +0.8333333,0.5,1.4142135,0.7071068 +0.8333333,0.5,1.259921,1.2599211 +0.83333325,0.5,0.89089864,1.7817974 +0.8333334,0.5,1.7817974,0.8908987 +0.8333333,0.49999997,1.587401,1.5874009 +0.8333334,0.5,1.122462,2.244924 +0.83333325,0.5,2.244924,1.122462 +0.83333325,0.83333325,0.99999994,0.99999994 +0.8333333,0.8333333,0.7071067,1.4142135 +0.8333333,0.8333333,1.4142135,0.7071067 +0.8333333,0.8333333,1.259921,1.259921 +0.83333325,0.8333334,0.89089864,1.7817974 +0.8333334,0.83333325,1.7817974,0.89089864 +0.8333333,0.8333333,1.587401,1.587401 +0.8333334,0.83333325,1.122462,2.244924 +0.83333325,0.8333334,2.244924,1.122462 diff --git a/mediapipe/tasks/testdata/metadata/efficientdet_lite0_v1.json b/mediapipe/tasks/testdata/metadata/efficientdet_lite0_v1.json index a3b98a626..f91229980 100644 --- a/mediapipe/tasks/testdata/metadata/efficientdet_lite0_v1.json +++ b/mediapipe/tasks/testdata/metadata/efficientdet_lite0_v1.json @@ -42,15 +42,13 @@ "description": "The scores of the detected boxes.", "content": { "content_properties_type": "FeatureProperties", - "content_properties": { - }, + "content_properties": {}, "range": { "min": 2, "max": 2 } }, - "stats": { - } + "stats": {} }, { "name": "location", @@ -71,34 +69,29 @@ "max": 2 } }, - "stats": { - } + "stats": {} }, { "name": "number of detections", "description": "The number of the detected boxes.", "content": { "content_properties_type": "FeatureProperties", - "content_properties": { - } + "content_properties": {} }, - "stats": { - } + "stats": {} }, { "name": "category", "description": "The categories of the detected boxes.", "content": { "content_properties_type": "FeatureProperties", - "content_properties": { - }, + "content_properties": {}, "range": { "min": 2, "max": 2 } }, - "stats": { - }, + "stats": {}, "associated_files": [ { "name": "labels.txt", diff --git a/mediapipe/tasks/testdata/metadata/ssd_mobilenet_v1_no_metadata.json b/mediapipe/tasks/testdata/metadata/ssd_mobilenet_v1_no_metadata.json index 95500f196..e4df01ddf 100644 --- a/mediapipe/tasks/testdata/metadata/ssd_mobilenet_v1_no_metadata.json +++ b/mediapipe/tasks/testdata/metadata/ssd_mobilenet_v1_no_metadata.json @@ -56,23 +56,20 @@ "max": 2 } }, - "stats": { - } + "stats": {} }, { "name": "category", "description": "The categories of the detected boxes.", "content": { "content_properties_type": "FeatureProperties", - "content_properties": { - }, + "content_properties": {}, "range": { "min": 2, "max": 2 } }, - "stats": { - }, + "stats": {}, "associated_files": [ { "name": "labels.txt", @@ -86,26 +83,22 @@ "description": "The scores of the detected boxes.", "content": { "content_properties_type": "FeatureProperties", - "content_properties": { - }, + "content_properties": {}, "range": { "min": 2, "max": 2 } }, - "stats": { - } + "stats": {} }, { "name": "number of detections", "description": "The number of the detected boxes.", "content": { "content_properties_type": "FeatureProperties", - "content_properties": { - } + "content_properties": {} }, - "stats": { - } + "stats": {} } ], "output_tensor_groups": [ diff --git a/third_party/external_files.bzl b/third_party/external_files.bzl index 7264c1b1c..c47f0fbb6 100644 --- a/third_party/external_files.bzl +++ b/third_party/external_files.bzl @@ -198,8 +198,8 @@ def external_files(): http_file( name = "com_google_mediapipe_coco_ssd_mobilenet_v1_score_calibration_json", - sha256 = "f377600be924c29697477f9d739db9db5d712aec4a644548526912858db6a082", - urls = ["https://storage.googleapis.com/mediapipe-assets/coco_ssd_mobilenet_v1_score_calibration.json?generation=1677522739770755"], + sha256 = "a850674f9043bfc775527fee7f1b639f7fe0fb56e8d3ed2b710247967c888b09", + urls = ["https://storage.googleapis.com/mediapipe-assets/coco_ssd_mobilenet_v1_score_calibration.json?generation=1682456086898538"], ) http_file( @@ -262,10 +262,28 @@ def external_files(): urls = ["https://storage.googleapis.com/mediapipe-assets/dynamic_input_classifier.tflite?generation=1680543275416843"], ) + http_file( + name = "com_google_mediapipe_efficientdet_lite0_fp16_no_nms_anchors_csv", + sha256 = "284475a0f16e34afcc6c0fe68b05bd871aca5b20c83db0870c6a36dd63827176", + urls = ["https://storage.googleapis.com/mediapipe-assets/efficientdet_lite0_fp16_no_nms_anchors.csv?generation=1682456090001817"], + ) + + http_file( + name = "com_google_mediapipe_efficientdet_lite0_fp16_no_nms_json", + sha256 = "dc3b333e41c43fb49ace048c25c18d0e34df78fb5ee77edbe169264368f78b92", + urls = ["https://storage.googleapis.com/mediapipe-assets/efficientdet_lite0_fp16_no_nms.json?generation=1682456092938505"], + ) + + http_file( + name = "com_google_mediapipe_efficientdet_lite0_fp16_no_nms_tflite", + sha256 = "bcda125c96d3767bca894c8cbe7bc458379c9974c9fd8bdc6204e7124a74082a", + urls = ["https://storage.googleapis.com/mediapipe-assets/efficientdet_lite0_fp16_no_nms.tflite?generation=1682456096034465"], + ) + http_file( name = "com_google_mediapipe_efficientdet_lite0_v1_json", - sha256 = "7a9e1fb625a6130a251e612637fc546cfc8cfabfadc7dbdade44c87f1d8996ca", - urls = ["https://storage.googleapis.com/mediapipe-assets/efficientdet_lite0_v1.json?generation=1677522746026682"], + sha256 = "ef9706696a3ea5d87f4324ac56e877a92033d33e522c4b7d5a416fbcab24d8fc", + urls = ["https://storage.googleapis.com/mediapipe-assets/efficientdet_lite0_v1.json?generation=1682456098581704"], ) http_file( @@ -1158,8 +1176,8 @@ def external_files(): http_file( name = "com_google_mediapipe_ssd_mobilenet_v1_no_metadata_json", - sha256 = "89157590b736cf3f3247aa9c8be3570c2856f4981a1e9476117e7c629e7c4825", - urls = ["https://storage.googleapis.com/mediapipe-assets/ssd_mobilenet_v1_no_metadata.json?generation=1677522786336455"], + sha256 = "ae5a5971a1c3df705307448ef97c854d846b7e6f2183fb51015bd5af5d7deb0f", + urls = ["https://storage.googleapis.com/mediapipe-assets/ssd_mobilenet_v1_no_metadata.json?generation=1682456117002011"], ) http_file( From db2592a04d7ed5e17ebf9ddbd380f62fd60b9c66 Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:24:20 +0530 Subject: [PATCH 084/753] Rename task_issue_template.yaml to 00-task-issue-template.yaml --- .../{task_issue_template.yaml => 00-task-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{task_issue_template.yaml => 00-task-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/task_issue_template.yaml b/.github/ISSUE_TEMPLATE/00-task-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/task_issue_template.yaml rename to .github/ISSUE_TEMPLATE/00-task-issue-template.yaml From 17bee87b277290d98290ac5a196ada996d586b9d Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:26:39 +0530 Subject: [PATCH 085/753] Rename model_maker_issue_template.yaml to 11-model-maker-issue-template.yaml --- ...ker_issue_template.yaml => 11-model-maker-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{model_maker_issue_template.yaml => 11-model-maker-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/model_maker_issue_template.yaml b/.github/ISSUE_TEMPLATE/11-model-maker-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/model_maker_issue_template.yaml rename to .github/ISSUE_TEMPLATE/11-model-maker-issue-template.yaml From 2d69c48e391f4eed44422cf8dfaf07ac436c6fd3 Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:27:12 +0530 Subject: [PATCH 086/753] Rename studio_issue_template.yaml to 12-studio-issue-template.yaml --- .../{studio_issue_template.yaml => 12-studio-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{studio_issue_template.yaml => 12-studio-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/studio_issue_template.yaml b/.github/ISSUE_TEMPLATE/12-studio-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/studio_issue_template.yaml rename to .github/ISSUE_TEMPLATE/12-studio-issue-template.yaml From badccdd87b8940c955c3840ea67a1328327f2817 Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:29:49 +0530 Subject: [PATCH 087/753] Rename feature_request_issue_template.yaml to 13-feature-request-issue-template.yaml --- ...issue_template.yaml => 13-feature-request-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{feature_request_issue_template.yaml => 13-feature-request-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/feature_request_issue_template.yaml b/.github/ISSUE_TEMPLATE/13-feature-request-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/feature_request_issue_template.yaml rename to .github/ISSUE_TEMPLATE/13-feature-request-issue-template.yaml From a99b0d6b9c8a83018aa271850ad8f3e4a1ab5e37 Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:30:23 +0530 Subject: [PATCH 088/753] Rename build.install_issue_template.yaml to 14-build-install-issue-template.yaml --- ...l_issue_template.yaml => 14-build-install-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{build.install_issue_template.yaml => 14-build-install-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/build.install_issue_template.yaml b/.github/ISSUE_TEMPLATE/14-build-install-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/build.install_issue_template.yaml rename to .github/ISSUE_TEMPLATE/14-build-install-issue-template.yaml From d15701a5e06baf0c387285a4178c30d0212d4aa9 Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:30:46 +0530 Subject: [PATCH 089/753] Rename bug_issue_template.yaml to 15-bug-issue-template.yaml --- .../{bug_issue_template.yaml => 15-bug-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{bug_issue_template.yaml => 15-bug-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/bug_issue_template.yaml b/.github/ISSUE_TEMPLATE/15-bug-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/bug_issue_template.yaml rename to .github/ISSUE_TEMPLATE/15-bug-issue-template.yaml From a002e24080f7ab47b7d40ca52037f2faab35ad5c Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:31:16 +0530 Subject: [PATCH 090/753] Rename Documentation_issue_template.yaml to 16-documentation-issue-template.yaml --- ...n_issue_template.yaml => 16-documentation-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{Documentation_issue_template.yaml => 16-documentation-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/Documentation_issue_template.yaml b/.github/ISSUE_TEMPLATE/16-documentation-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/Documentation_issue_template.yaml rename to .github/ISSUE_TEMPLATE/16-documentation-issue-template.yaml From 00f355e30139a3bb3ed7dff17e36cbf9b0d94f03 Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:32:06 +0530 Subject: [PATCH 091/753] Rename Solution(Legacy_issue_template).yaml to 17-solution-legacy-issue-template.yaml --- ...ssue_template).yaml => 17-solution-legacy-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{Solution(Legacy_issue_template).yaml => 17-solution-legacy-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/Solution(Legacy_issue_template).yaml b/.github/ISSUE_TEMPLATE/17-solution-legacy-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/Solution(Legacy_issue_template).yaml rename to .github/ISSUE_TEMPLATE/17-solution-legacy-issue-template.yaml From 4046b9741614f35bfb1d0aeb4ef053c43625e4c2 Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:32:41 +0530 Subject: [PATCH 092/753] Rename 50-other-issues.md to 18-other-issues.md --- .github/ISSUE_TEMPLATE/{50-other-issues.md => 18-other-issues.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{50-other-issues.md => 18-other-issues.md} (100%) diff --git a/.github/ISSUE_TEMPLATE/50-other-issues.md b/.github/ISSUE_TEMPLATE/18-other-issues.md similarity index 100% rename from .github/ISSUE_TEMPLATE/50-other-issues.md rename to .github/ISSUE_TEMPLATE/18-other-issues.md From 728cb26644f4321866fd4a69ed55f2906c05fa08 Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:34:48 +0530 Subject: [PATCH 093/753] Rename 13-feature-request-issue-template.yaml to 14-feature-request-issue-template.yaml --- ...issue-template.yaml => 14-feature-request-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{13-feature-request-issue-template.yaml => 14-feature-request-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/13-feature-request-issue-template.yaml b/.github/ISSUE_TEMPLATE/14-feature-request-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/13-feature-request-issue-template.yaml rename to .github/ISSUE_TEMPLATE/14-feature-request-issue-template.yaml From 7d6ccb2dd17ec25af089fed73d773aaf23884add Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:35:16 +0530 Subject: [PATCH 094/753] Rename 14-feature-request-issue-template.yaml to 15-feature-request-issue-template.yaml --- ...issue-template.yaml => 15-feature-request-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{14-feature-request-issue-template.yaml => 15-feature-request-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/14-feature-request-issue-template.yaml b/.github/ISSUE_TEMPLATE/15-feature-request-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/14-feature-request-issue-template.yaml rename to .github/ISSUE_TEMPLATE/15-feature-request-issue-template.yaml From d6b4067319d5415e00c3585924cceef84c26f4df Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:35:44 +0530 Subject: [PATCH 095/753] Rename 15-feature-request-issue-template.yaml to 16-feature-request-issue-template.yaml --- ...issue-template.yaml => 16-feature-request-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{15-feature-request-issue-template.yaml => 16-feature-request-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/15-feature-request-issue-template.yaml b/.github/ISSUE_TEMPLATE/16-feature-request-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/15-feature-request-issue-template.yaml rename to .github/ISSUE_TEMPLATE/16-feature-request-issue-template.yaml From f36f2c64b5ca9266d15f2dd7753fe964a8a117bc Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:36:33 +0530 Subject: [PATCH 096/753] Rename 16-feature-request-issue-template.yaml to 14-feature-request-issue-template.yaml --- ...issue-template.yaml => 14-feature-request-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{16-feature-request-issue-template.yaml => 14-feature-request-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/16-feature-request-issue-template.yaml b/.github/ISSUE_TEMPLATE/14-feature-request-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/16-feature-request-issue-template.yaml rename to .github/ISSUE_TEMPLATE/14-feature-request-issue-template.yaml From 9c8fe490d438ab102bced10b69945de959298a1b Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:36:58 +0530 Subject: [PATCH 097/753] Rename 14-build-install-issue-template.yaml to 15-build-install-issue-template.yaml --- ...l-issue-template.yaml => 15-build-install-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{14-build-install-issue-template.yaml => 15-build-install-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/14-build-install-issue-template.yaml b/.github/ISSUE_TEMPLATE/15-build-install-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/14-build-install-issue-template.yaml rename to .github/ISSUE_TEMPLATE/15-build-install-issue-template.yaml From f9d14157ffbf1044c038c36a747f4896562a48b8 Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:37:28 +0530 Subject: [PATCH 098/753] Rename 15-bug-issue-template.yaml to 16-bug-issue-template.yaml --- .../{15-bug-issue-template.yaml => 16-bug-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{15-bug-issue-template.yaml => 16-bug-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/15-bug-issue-template.yaml b/.github/ISSUE_TEMPLATE/16-bug-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/15-bug-issue-template.yaml rename to .github/ISSUE_TEMPLATE/16-bug-issue-template.yaml From 275eb31a8fa60e9a7c97ab9a4ccfcc983878bfd1 Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:37:44 +0530 Subject: [PATCH 099/753] Rename 16-documentation-issue-template.yaml to 17-documentation-issue-template.yaml --- ...n-issue-template.yaml => 17-documentation-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{16-documentation-issue-template.yaml => 17-documentation-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/16-documentation-issue-template.yaml b/.github/ISSUE_TEMPLATE/17-documentation-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/16-documentation-issue-template.yaml rename to .github/ISSUE_TEMPLATE/17-documentation-issue-template.yaml From 5f505b09e3acb8f7609854bb75226875a05e44ea Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:38:05 +0530 Subject: [PATCH 100/753] Rename 17-solution-legacy-issue-template.yaml to 18-solution-legacy-issue-template.yaml --- ...issue-template.yaml => 18-solution-legacy-issue-template.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{17-solution-legacy-issue-template.yaml => 18-solution-legacy-issue-template.yaml} (100%) diff --git a/.github/ISSUE_TEMPLATE/17-solution-legacy-issue-template.yaml b/.github/ISSUE_TEMPLATE/18-solution-legacy-issue-template.yaml similarity index 100% rename from .github/ISSUE_TEMPLATE/17-solution-legacy-issue-template.yaml rename to .github/ISSUE_TEMPLATE/18-solution-legacy-issue-template.yaml From 6f97203562148fa723625b3e90bde9ed573645ee Mon Sep 17 00:00:00 2001 From: kuaashish <98159216+kuaashish@users.noreply.github.com> Date: Wed, 26 Apr 2023 16:38:23 +0530 Subject: [PATCH 101/753] Rename 18-other-issues.md to 19-other-issues.md --- .github/ISSUE_TEMPLATE/{18-other-issues.md => 19-other-issues.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{18-other-issues.md => 19-other-issues.md} (100%) diff --git a/.github/ISSUE_TEMPLATE/18-other-issues.md b/.github/ISSUE_TEMPLATE/19-other-issues.md similarity index 100% rename from .github/ISSUE_TEMPLATE/18-other-issues.md rename to .github/ISSUE_TEMPLATE/19-other-issues.md From 48aa88f39df68f8dbd4c98741b243be8ae6803aa Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 26 Apr 2023 12:10:26 -0700 Subject: [PATCH 102/753] Change object detector learning rate decay to cosine decay. PiperOrigin-RevId: 527337105 --- docs/framework_concepts/graphs.md | 2 +- mediapipe/framework/api2/contract.h | 2 +- mediapipe/framework/calculator_base.h | 2 +- mediapipe/framework/calculator_context.h | 2 +- mediapipe/framework/calculator_runner.h | 2 +- mediapipe/framework/output_side_packet.h | 2 +- mediapipe/framework/output_side_packet_impl.h | 2 +- mediapipe/framework/output_stream.h | 2 +- mediapipe/framework/scheduler_queue.h | 2 +- .../tracked_anchor_manager_calculator.cc | 2 +- .../glutil/ExternalTextureRenderer.java | 2 +- .../vision/object_detector/hyperparameters.py | 53 ++++--------------- .../vision/object_detector/object_detector.py | 23 ++++---- .../segmentation_postprocessor_gl.cc | 2 +- mediapipe/util/tracking/box_tracker.h | 4 +- 15 files changed, 35 insertions(+), 69 deletions(-) diff --git a/docs/framework_concepts/graphs.md b/docs/framework_concepts/graphs.md index 23e20d052..5f9c68e08 100644 --- a/docs/framework_concepts/graphs.md +++ b/docs/framework_concepts/graphs.md @@ -273,7 +273,7 @@ defined in the enclosing protobuf in order to be traversed using ## Cycles - + By default, MediaPipe requires calculator graphs to be acyclic and treats cycles in a graph as errors. If a graph is intended to have cycles, the cycles need to diff --git a/mediapipe/framework/api2/contract.h b/mediapipe/framework/api2/contract.h index 9b92212cb..90e4c38cd 100644 --- a/mediapipe/framework/api2/contract.h +++ b/mediapipe/framework/api2/contract.h @@ -164,7 +164,7 @@ class Contract { std::tuple items; - // TODO -, check for conflicts. + // TODO: when forwarding nested items (e.g. ports), check for conflicts. decltype(ExtractNestedItems(items)) all_items{ExtractNestedItems(items)}; constexpr auto inputs() const { diff --git a/mediapipe/framework/calculator_base.h b/mediapipe/framework/calculator_base.h index 4bd3d7398..19f37f9de 100644 --- a/mediapipe/framework/calculator_base.h +++ b/mediapipe/framework/calculator_base.h @@ -150,7 +150,7 @@ class CalculatorBase { // Packets may be output during a call to Close(). However, output packets // are silently discarded if Close() is called after a graph run has ended. // - // NOTE - needs to perform an action only when processing is + // NOTE: If Close() needs to perform an action only when processing is // complete, Close() must check if cc->GraphStatus() is OK. virtual absl::Status Close(CalculatorContext* cc) { return absl::OkStatus(); } diff --git a/mediapipe/framework/calculator_context.h b/mediapipe/framework/calculator_context.h index 4eafea79f..284226d92 100644 --- a/mediapipe/framework/calculator_context.h +++ b/mediapipe/framework/calculator_context.h @@ -111,7 +111,7 @@ class CalculatorContext { // Returns the status of the graph run. // - // NOTE -. + // NOTE: This method should only be called during CalculatorBase::Close(). absl::Status GraphStatus() const { return graph_status_; } ProfilingContext* GetProfilingContext() const { diff --git a/mediapipe/framework/calculator_runner.h b/mediapipe/framework/calculator_runner.h index 350fb535c..fb1020de1 100644 --- a/mediapipe/framework/calculator_runner.h +++ b/mediapipe/framework/calculator_runner.h @@ -66,7 +66,7 @@ class CalculatorRunner { explicit CalculatorRunner(const std::string& node_config_string); // Convenience constructor to initialize a calculator which uses indexes // (not tags) for all its fields. - // NOTE -, which + // NOTE: This constructor calls proto_ns::TextFormat::ParseFromString(), which // is not available when using lite protos. CalculatorRunner(const std::string& calculator_type, const std::string& options_string, int num_inputs, diff --git a/mediapipe/framework/output_side_packet.h b/mediapipe/framework/output_side_packet.h index 44eb07085..9a0c8cbd2 100644 --- a/mediapipe/framework/output_side_packet.h +++ b/mediapipe/framework/output_side_packet.h @@ -30,7 +30,7 @@ class OutputSidePacket { // Sets the output side packet. The Packet must contain the data. // - // NOTE - cannot report errors via the return value. It uses an error + // NOTE: Set() cannot report errors via the return value. It uses an error // callback function to report errors. virtual void Set(const Packet& packet) = 0; }; diff --git a/mediapipe/framework/output_side_packet_impl.h b/mediapipe/framework/output_side_packet_impl.h index 7b16eb32b..7e7d639cd 100644 --- a/mediapipe/framework/output_side_packet_impl.h +++ b/mediapipe/framework/output_side_packet_impl.h @@ -48,7 +48,7 @@ class OutputSidePacketImpl : public OutputSidePacket { // Sets the output side packet. The Packet must contain the data. // - // NOTE - cannot report errors via the return value. It uses an error + // NOTE: Set() cannot report errors via the return value. It uses an error // callback function to report errors. void Set(const Packet& packet) override; diff --git a/mediapipe/framework/output_stream.h b/mediapipe/framework/output_stream.h index 55679066d..191c26fd7 100644 --- a/mediapipe/framework/output_stream.h +++ b/mediapipe/framework/output_stream.h @@ -50,7 +50,7 @@ class OutputStream { // the only packet in the stream. // Violation of any of these conditions causes a CHECK-failure. // - // NOTE - cannot report errors via the return value. Instead of a + // NOTE: AddPacket() cannot report errors via the return value. Instead of a // CHECK-failure, a subclass of OutputStream should use a callback function // to report errors. virtual void AddPacket(const Packet& packet) = 0; diff --git a/mediapipe/framework/scheduler_queue.h b/mediapipe/framework/scheduler_queue.h index 345da7dc2..f6777f42b 100644 --- a/mediapipe/framework/scheduler_queue.h +++ b/mediapipe/framework/scheduler_queue.h @@ -102,7 +102,7 @@ class SchedulerQueue : public TaskQueue { // Implements the TaskQueue interface. void RunNextTask() override; - // NOTE -, the caller must call + // NOTE: After calling SetRunning(true), the caller must call // SubmitWaitingTasksToExecutor since tasks may have been added while the // queue was not running. void SetRunning(bool running) ABSL_LOCKS_EXCLUDED(mutex_); diff --git a/mediapipe/graphs/instant_motion_tracking/calculators/tracked_anchor_manager_calculator.cc b/mediapipe/graphs/instant_motion_tracking/calculators/tracked_anchor_manager_calculator.cc index 9468b901e..446aee781 100644 --- a/mediapipe/graphs/instant_motion_tracking/calculators/tracked_anchor_manager_calculator.cc +++ b/mediapipe/graphs/instant_motion_tracking/calculators/tracked_anchor_manager_calculator.cc @@ -25,7 +25,7 @@ constexpr char kAnchorsTag[] = "ANCHORS"; constexpr char kBoxesInputTag[] = "BOXES"; constexpr char kBoxesOutputTag[] = "START_POS"; constexpr char kCancelTag[] = "CANCEL_ID"; -// TODO - +// TODO: Find optimal Height/Width (0.1-0.3) constexpr float kBoxEdgeSize = 0.2f; // Used to establish tracking box dimensions constexpr float kUsToMs = diff --git a/mediapipe/java/com/google/mediapipe/glutil/ExternalTextureRenderer.java b/mediapipe/java/com/google/mediapipe/glutil/ExternalTextureRenderer.java index 2dc6112a3..4dd35f865 100644 --- a/mediapipe/java/com/google/mediapipe/glutil/ExternalTextureRenderer.java +++ b/mediapipe/java/com/google/mediapipe/glutil/ExternalTextureRenderer.java @@ -106,7 +106,7 @@ public class ExternalTextureRenderer { * *

Before calling this, {@link #setup} must have been called. * - *

NOTE -} on passed surface texture. + *

NOTE: Calls {@link SurfaceTexture#updateTexImage()} on passed surface texture. */ public void render(SurfaceTexture surfaceTexture) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); diff --git a/mediapipe/model_maker/python/vision/object_detector/hyperparameters.py b/mediapipe/model_maker/python/vision/object_detector/hyperparameters.py index 8b49564a0..1bc7514f2 100644 --- a/mediapipe/model_maker/python/vision/object_detector/hyperparameters.py +++ b/mediapipe/model_maker/python/vision/object_detector/hyperparameters.py @@ -14,7 +14,7 @@ """Hyperparameters for training object detection models.""" import dataclasses -from typing import List +from typing import Optional from mediapipe.model_maker.python.core import hyperparameters as hp @@ -29,12 +29,13 @@ class HParams(hp.BaseHParams): epochs: Number of training iterations over the dataset. do_fine_tuning: If true, the base module is trained together with the classification layer on top. - learning_rate_epoch_boundaries: List of epoch boundaries where - learning_rate_epoch_boundaries[i] is the epoch where the learning rate - will decay to learning_rate * learning_rate_decay_multipliers[i]. - learning_rate_decay_multipliers: List of learning rate multipliers which - calculates the learning rate at the ith boundary as learning_rate * - learning_rate_decay_multipliers[i]. + cosine_decay_epochs: The number of epochs for cosine decay learning rate. + See + https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/schedules/CosineDecay + for more info. + cosine_decay_alpha: The alpha value for cosine decay learning rate. See + https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/schedules/CosineDecay + for more info. """ # Parameters from BaseHParams class. @@ -42,41 +43,9 @@ class HParams(hp.BaseHParams): batch_size: int = 32 epochs: int = 10 - # Parameters for learning rate decay - learning_rate_epoch_boundaries: List[int] = dataclasses.field( - default_factory=lambda: [] - ) - learning_rate_decay_multipliers: List[float] = dataclasses.field( - default_factory=lambda: [] - ) - - def __post_init__(self): - # Validate stepwise learning rate parameters - lr_boundary_len = len(self.learning_rate_epoch_boundaries) - lr_decay_multipliers_len = len(self.learning_rate_decay_multipliers) - if lr_boundary_len != lr_decay_multipliers_len: - raise ValueError( - "Length of learning_rate_epoch_boundaries and ", - "learning_rate_decay_multipliers do not match: ", - f"{lr_boundary_len}!={lr_decay_multipliers_len}", - ) - # Validate learning_rate_epoch_boundaries - if ( - sorted(self.learning_rate_epoch_boundaries) - != self.learning_rate_epoch_boundaries - ): - raise ValueError( - "learning_rate_epoch_boundaries is not in ascending order: ", - self.learning_rate_epoch_boundaries, - ) - if ( - self.learning_rate_epoch_boundaries - and self.learning_rate_epoch_boundaries[-1] > self.epochs - ): - raise ValueError( - "Values in learning_rate_epoch_boundaries cannot be greater ", - "than epochs", - ) + # Parameters for cosine learning rate decay + cosine_decay_epochs: Optional[int] = None + cosine_decay_alpha: float = 0.0 @dataclasses.dataclass diff --git a/mediapipe/model_maker/python/vision/object_detector/object_detector.py b/mediapipe/model_maker/python/vision/object_detector/object_detector.py index d208a9b28..746eef1b3 100644 --- a/mediapipe/model_maker/python/vision/object_detector/object_detector.py +++ b/mediapipe/model_maker/python/vision/object_detector/object_detector.py @@ -354,19 +354,16 @@ class ObjectDetector(classifier.Classifier): A tf.keras.optimizer.Optimizer for model training. """ init_lr = self._hparams.learning_rate * self._hparams.batch_size / 256 - if self._hparams.learning_rate_epoch_boundaries: - lr_values = [init_lr] + [ - init_lr * m for m in self._hparams.learning_rate_decay_multipliers - ] - lr_step_boundaries = [ - steps_per_epoch * epoch_boundary - for epoch_boundary in self._hparams.learning_rate_epoch_boundaries - ] - learning_rate = tf.keras.optimizers.schedules.PiecewiseConstantDecay( - lr_step_boundaries, lr_values - ) - else: - learning_rate = init_lr + decay_epochs = ( + self._hparams.cosine_decay_epochs + if self._hparams.cosine_decay_epochs + else self._hparams.epochs + ) + learning_rate = tf.keras.optimizers.schedules.CosineDecay( + init_lr, + steps_per_epoch * decay_epochs, + self._hparams.cosine_decay_alpha, + ) return tf.keras.optimizers.experimental.SGD( learning_rate=learning_rate, momentum=0.9 ) diff --git a/mediapipe/tasks/cc/vision/image_segmenter/calculators/segmentation_postprocessor_gl.cc b/mediapipe/tasks/cc/vision/image_segmenter/calculators/segmentation_postprocessor_gl.cc index 96451617f..5b212069f 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/calculators/segmentation_postprocessor_gl.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/calculators/segmentation_postprocessor_gl.cc @@ -581,7 +581,7 @@ SegmentationPostprocessorGl::GetSegmentationResultGpu( // Step 2.5: For SOFTMAX, apply softmax shaders (max, transformAndSum, and // normalization) to create softmax-transformed chunks before channel // extraction. - // NOTE - / sum_over_x(exp(x-C)) = exp(x) / sum_over_x(exp(x)). So + // NOTE: exp(x-C) / sum_over_x(exp(x-C)) = exp(x) / sum_over_x(exp(x)). So // theoretically we can skip the max shader step entirely. However, // applying it does bring all our values into a nice (0, 1] range, so it // will likely be better for precision, especially when dealing with an diff --git a/mediapipe/util/tracking/box_tracker.h b/mediapipe/util/tracking/box_tracker.h index 31ac5c117..8654e97fd 100644 --- a/mediapipe/util/tracking/box_tracker.h +++ b/mediapipe/util/tracking/box_tracker.h @@ -200,7 +200,7 @@ class BoxTracker { // Cancels all ongoing tracks. To avoid race conditions all NewBoxTrack's in // flight will also be canceled. Future NewBoxTrack's will be canceled. - // NOTE - before + // NOTE: To resume execution, you have to call ResumeTracking() before // issuing more NewBoxTrack calls. void CancelAllOngoingTracks() ABSL_LOCKS_EXCLUDED(status_mutex_); void ResumeTracking() ABSL_LOCKS_EXCLUDED(status_mutex_); @@ -208,7 +208,7 @@ class BoxTracker { // Waits for all ongoing tracks to complete. // Optionally accepts a timeout in microseconds (== 0 for infinite wait). // Returns true on success, false if timeout is reached. - // NOTE - must + // NOTE: If WaitForAllOngoingTracks timed out, CancelAllOngoingTracks() must // be called before destructing the BoxTracker object or dangeling running // threads might try to access invalid data. bool WaitForAllOngoingTracks(int timeout_us = 0) From c44cc30ece7b4f910e896fa8ffe381211de17475 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 26 Apr 2023 13:42:54 -0700 Subject: [PATCH 103/753] DetectionPostProcessingGraph for post processing raw tensors from detection models. PiperOrigin-RevId: 527363291 --- .../tasks/cc/components/processors/BUILD | 46 + .../detection_postprocessing_graph.cc | 886 ++++++++++++++++++ .../detection_postprocessing_graph.h | 62 ++ .../detection_postprocessing_graph_test.cc | 570 +++++++++++ .../cc/components/processors/proto/BUILD | 19 + ...tection_postprocessing_graph_options.proto | 49 + .../processors/proto/detector_options.proto | 52 + .../tasks/cc/vision/object_detector/BUILD | 15 +- .../vision/object_detector/object_detector.h | 15 +- .../object_detector/object_detector_graph.cc | 479 +--------- .../object_detector/object_detector_test.cc | 62 +- mediapipe/tasks/testdata/vision/BUILD | 2 + third_party/external_files.bzl | 4 +- 13 files changed, 1791 insertions(+), 470 deletions(-) create mode 100644 mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.cc create mode 100644 mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.h create mode 100644 mediapipe/tasks/cc/components/processors/detection_postprocessing_graph_test.cc create mode 100644 mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.proto create mode 100644 mediapipe/tasks/cc/components/processors/proto/detector_options.proto diff --git a/mediapipe/tasks/cc/components/processors/BUILD b/mediapipe/tasks/cc/components/processors/BUILD index 532bc9a3b..e8f9f57ff 100644 --- a/mediapipe/tasks/cc/components/processors/BUILD +++ b/mediapipe/tasks/cc/components/processors/BUILD @@ -161,3 +161,49 @@ cc_library( ], alwayslink = 1, ) + +cc_library( + name = "detection_postprocessing_graph", + srcs = ["detection_postprocessing_graph.cc"], + hdrs = ["detection_postprocessing_graph.h"], + deps = [ + "//mediapipe/calculators/core:split_vector_calculator", + "//mediapipe/calculators/core:split_vector_calculator_cc_proto", + "//mediapipe/calculators/tensor:tensors_to_detections_calculator", + "//mediapipe/calculators/tensor:tensors_to_detections_calculator_cc_proto", + "//mediapipe/calculators/tflite:ssd_anchors_calculator", + "//mediapipe/calculators/tflite:ssd_anchors_calculator_cc_proto", + "//mediapipe/calculators/util:detection_label_id_to_text_calculator", + "//mediapipe/calculators/util:detection_label_id_to_text_calculator_cc_proto", + "//mediapipe/calculators/util:non_max_suppression_calculator", + "//mediapipe/calculators/util:non_max_suppression_calculator_cc_proto", + "//mediapipe/framework:calculator_cc_proto", + "//mediapipe/framework:calculator_framework", + "//mediapipe/framework/api2:builder", + "//mediapipe/framework/api2:port", + "//mediapipe/framework/formats:detection_cc_proto", + "//mediapipe/framework/formats:tensor", + "//mediapipe/framework/formats/object_detection:anchor_cc_proto", + "//mediapipe/tasks/cc:common", + "//mediapipe/tasks/cc/components/calculators:score_calibration_calculator", + "//mediapipe/tasks/cc/components/calculators:score_calibration_calculator_cc_proto", + "//mediapipe/tasks/cc/components/calculators:score_calibration_utils", + "//mediapipe/tasks/cc/components/processors/proto:detection_postprocessing_graph_options_cc_proto", + "//mediapipe/tasks/cc/components/processors/proto:detector_options_cc_proto", + "//mediapipe/tasks/cc/core:model_resources", + "//mediapipe/tasks/cc/core:utils", + "//mediapipe/tasks/cc/metadata:metadata_extractor", + "//mediapipe/tasks/cc/vision/object_detector/proto:object_detector_options_cc_proto", + "//mediapipe/tasks/metadata:metadata_schema_cc", + "//mediapipe/tasks/metadata:object_detector_metadata_schema_cc", + "//mediapipe/util:label_map_cc_proto", + "//mediapipe/util:label_map_util", + "@com_google_absl//absl/container:flat_hash_set", + "@com_google_absl//absl/status", + "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:str_format", + "@org_tensorflow//tensorflow/lite/schema:schema_fbs", + ], + alwayslink = 1, +) diff --git a/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.cc b/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.cc new file mode 100644 index 000000000..d7fc1892c --- /dev/null +++ b/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.cc @@ -0,0 +1,886 @@ +/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.h" + +#include +#include +#include + +#include "absl/container/flat_hash_set.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/str_format.h" +#include "absl/strings/string_view.h" +#include "mediapipe/calculators/core/split_vector_calculator.pb.h" +#include "mediapipe/calculators/tensor/tensors_to_detections_calculator.pb.h" +#include "mediapipe/calculators/tflite/ssd_anchors_calculator.pb.h" +#include "mediapipe/calculators/util/detection_label_id_to_text_calculator.pb.h" +#include "mediapipe/calculators/util/non_max_suppression_calculator.pb.h" +#include "mediapipe/framework/api2/builder.h" +#include "mediapipe/framework/api2/port.h" +#include "mediapipe/framework/calculator.pb.h" +#include "mediapipe/framework/calculator_framework.h" +#include "mediapipe/framework/formats/detection.pb.h" +#include "mediapipe/framework/formats/object_detection/anchor.pb.h" +#include "mediapipe/framework/formats/tensor.h" +#include "mediapipe/tasks/cc/common.h" +#include "mediapipe/tasks/cc/components/calculators/score_calibration_calculator.pb.h" +#include "mediapipe/tasks/cc/components/calculators/score_calibration_utils.h" +#include "mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.pb.h" +#include "mediapipe/tasks/cc/components/processors/proto/detector_options.pb.h" +#include "mediapipe/tasks/cc/core/model_resources.h" +#include "mediapipe/tasks/cc/core/utils.h" +#include "mediapipe/tasks/cc/metadata/metadata_extractor.h" +#include "mediapipe/tasks/metadata/metadata_schema_generated.h" +#include "mediapipe/tasks/metadata/object_detector_metadata_schema_generated.h" +#include "mediapipe/util/label_map.pb.h" +#include "mediapipe/util/label_map_util.h" +#include "tensorflow/lite/schema/schema_generated.h" + +namespace mediapipe { +namespace tasks { +namespace components { +namespace processors { + +namespace { + +using ::flatbuffers::Offset; +using ::flatbuffers::Vector; +using ::mediapipe::api2::Input; +using ::mediapipe::api2::Output; +using ::mediapipe::api2::builder::Graph; +using ::mediapipe::api2::builder::Source; +using ::mediapipe::tasks::metadata::ModelMetadataExtractor; +using ::tflite::BoundingBoxProperties; +using ::tflite::ContentProperties; +using ::tflite::ContentProperties_BoundingBoxProperties; +using ::tflite::EnumNameContentProperties; +using ::tflite::ProcessUnit; +using ::tflite::ProcessUnitOptions_ScoreThresholdingOptions; +using ::tflite::TensorMetadata; +using LabelItems = mediapipe::proto_ns::Map; +using TensorsSource = + mediapipe::api2::builder::Source>; + +constexpr int kInModelNmsDefaultLocationsIndex = 0; +constexpr int kInModelNmsDefaultCategoriesIndex = 1; +constexpr int kInModelNmsDefaultScoresIndex = 2; +constexpr int kInModelNmsDefaultNumResultsIndex = 3; + +constexpr int kOutModelNmsDefaultLocationsIndex = 0; +constexpr int kOutModelNmsDefaultScoresIndex = 1; + +constexpr float kDefaultScoreThreshold = std::numeric_limits::lowest(); + +constexpr absl::string_view kLocationTensorName = "location"; +constexpr absl::string_view kCategoryTensorName = "category"; +constexpr absl::string_view kScoreTensorName = "score"; +constexpr absl::string_view kNumberOfDetectionsTensorName = + "number of detections"; +constexpr absl::string_view kDetectorMetadataName = "DETECTOR_METADATA"; +constexpr absl::string_view kCalibratedScoresTag = "CALIBRATED_SCORES"; +constexpr absl::string_view kDetectionsTag = "DETECTIONS"; +constexpr absl::string_view kIndicesTag = "INDICES"; +constexpr absl::string_view kScoresTag = "SCORES"; +constexpr absl::string_view kTensorsTag = "TENSORS"; +constexpr absl::string_view kAnchorsTag = "ANCHORS"; + +// Struct holding the different output streams produced by the graph. +struct DetectionPostprocessingOutputStreams { + Source> detections; +}; + +// Parameters used for configuring the post-processing calculators. +struct PostProcessingSpecs { + // The maximum number of detection results to return. + int max_results; + // Indices of the output tensors to match the output tensors to the correct + // index order of the output tensors: [location, categories, scores, + // num_detections]. + std::vector output_tensor_indices; + // For each pack of 4 coordinates returned by the model, this denotes the + // order in which to get the left, top, right and bottom coordinates. + std::vector bounding_box_corners_order; + // This is populated by reading the label files from the TFLite Model + // Metadata: if no such files are available, this is left empty and the + // ObjectDetector will only be able to populate the `index` field of the + // detection results. + LabelItems label_items; + // Score threshold. Detections with a confidence below this value are + // discarded. If none is provided via metadata or options, -FLT_MAX is set as + // default value. + float score_threshold; + // Set of category indices to be allowed/denied. + absl::flat_hash_set allow_or_deny_categories; + // Indicates `allow_or_deny_categories` is an allowlist or a denylist. + bool is_allowlist; + // Score calibration options, if any. + std::optional score_calibration_options; +}; + +absl::Status SanityCheckOptions(const proto::DetectorOptions& options) { + if (options.max_results() == 0) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + "Invalid `max_results` option: value must be != 0", + MediaPipeTasksStatus::kInvalidArgumentError); + } + if (options.category_allowlist_size() > 0 && + options.category_denylist_size() > 0) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + "`category_allowlist` and `category_denylist` are mutually " + "exclusive options.", + MediaPipeTasksStatus::kInvalidArgumentError); + } + return absl::OkStatus(); +} + +absl::StatusOr GetBoundingBoxProperties( + const TensorMetadata& tensor_metadata) { + if (tensor_metadata.content() == nullptr || + tensor_metadata.content()->content_properties() == nullptr) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::StrFormat( + "Expected BoundingBoxProperties for tensor %s, found none.", + tensor_metadata.name() ? tensor_metadata.name()->str() : "#0"), + MediaPipeTasksStatus::kMetadataInvalidContentPropertiesError); + } + + ContentProperties type = tensor_metadata.content()->content_properties_type(); + if (type != ContentProperties_BoundingBoxProperties) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::StrFormat( + "Expected BoundingBoxProperties for tensor %s, found %s.", + tensor_metadata.name() ? tensor_metadata.name()->str() : "#0", + EnumNameContentProperties(type)), + MediaPipeTasksStatus::kMetadataInvalidContentPropertiesError); + } + + const BoundingBoxProperties* properties = + tensor_metadata.content()->content_properties_as_BoundingBoxProperties(); + + // Mobile SSD only supports "BOUNDARIES" bounding box type. + if (properties->type() != tflite::BoundingBoxType_BOUNDARIES) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::StrFormat( + "Mobile SSD only supports BoundingBoxType BOUNDARIES, found %s", + tflite::EnumNameBoundingBoxType(properties->type())), + MediaPipeTasksStatus::kMetadataInvalidContentPropertiesError); + } + + // Mobile SSD only supports "RATIO" coordinates type. + if (properties->coordinate_type() != tflite::CoordinateType_RATIO) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::StrFormat( + "Mobile SSD only supports CoordinateType RATIO, found %s", + tflite::EnumNameCoordinateType(properties->coordinate_type())), + MediaPipeTasksStatus::kMetadataInvalidContentPropertiesError); + } + + // Index is optional, but must contain 4 values if present. + if (properties->index() != nullptr && properties->index()->size() != 4) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::StrFormat( + "Expected BoundingBoxProperties index to contain 4 values, found " + "%d", + properties->index()->size()), + MediaPipeTasksStatus::kMetadataInvalidContentPropertiesError); + } + + return properties; +} + +absl::StatusOr GetLabelItemsIfAny( + const ModelMetadataExtractor& metadata_extractor, + const TensorMetadata& tensor_metadata, + tflite::AssociatedFileType associated_file_type, absl::string_view locale) { + const std::string labels_filename = + ModelMetadataExtractor::FindFirstAssociatedFileName(tensor_metadata, + associated_file_type); + if (labels_filename.empty()) { + LabelItems empty_label_items; + return empty_label_items; + } + ASSIGN_OR_RETURN(absl::string_view labels_file, + metadata_extractor.GetAssociatedFile(labels_filename)); + const std::string display_names_filename = + ModelMetadataExtractor::FindFirstAssociatedFileName( + tensor_metadata, associated_file_type, locale); + absl::string_view display_names_file; + if (!display_names_filename.empty()) { + ASSIGN_OR_RETURN(display_names_file, metadata_extractor.GetAssociatedFile( + display_names_filename)); + } + return mediapipe::BuildLabelMapFromFiles(labels_file, display_names_file); +} + +absl::StatusOr GetScoreThreshold( + const ModelMetadataExtractor& metadata_extractor, + const TensorMetadata& tensor_metadata) { + ASSIGN_OR_RETURN( + const ProcessUnit* score_thresholding_process_unit, + metadata_extractor.FindFirstProcessUnit( + tensor_metadata, ProcessUnitOptions_ScoreThresholdingOptions)); + if (score_thresholding_process_unit == nullptr) { + return kDefaultScoreThreshold; + } + return score_thresholding_process_unit->options_as_ScoreThresholdingOptions() + ->global_score_threshold(); +} + +absl::StatusOr> GetAllowOrDenyCategoryIndicesIfAny( + const proto::DetectorOptions& config, const LabelItems& label_items) { + absl::flat_hash_set category_indices; + // Exit early if no denylist/allowlist. + if (config.category_denylist_size() == 0 && + config.category_allowlist_size() == 0) { + return category_indices; + } + if (label_items.empty()) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + "Using `category_allowlist` or `category_denylist` requires " + "labels to be present in the TFLite Model Metadata but none was found.", + MediaPipeTasksStatus::kMetadataMissingLabelsError); + } + const auto& category_list = config.category_allowlist_size() > 0 + ? config.category_allowlist() + : config.category_denylist(); + for (const auto& category_name : category_list) { + int index = -1; + for (int i = 0; i < label_items.size(); ++i) { + if (label_items.at(i).name() == category_name) { + index = i; + break; + } + } + // Ignores duplicate or unknown categories. + if (index < 0) { + continue; + } + category_indices.insert(index); + } + return category_indices; +} + +absl::StatusOr> +GetScoreCalibrationOptionsIfAny( + const ModelMetadataExtractor& metadata_extractor, + const TensorMetadata& tensor_metadata) { + // Get ScoreCalibrationOptions, if any. + ASSIGN_OR_RETURN( + const ProcessUnit* score_calibration_process_unit, + metadata_extractor.FindFirstProcessUnit( + tensor_metadata, tflite::ProcessUnitOptions_ScoreCalibrationOptions)); + if (score_calibration_process_unit == nullptr) { + return std::nullopt; + } + auto* score_calibration_options = + score_calibration_process_unit->options_as_ScoreCalibrationOptions(); + // Get corresponding AssociatedFile. + auto score_calibration_filename = + metadata_extractor.FindFirstAssociatedFileName( + tensor_metadata, + tflite::AssociatedFileType_TENSOR_AXIS_SCORE_CALIBRATION); + if (score_calibration_filename.empty()) { + return CreateStatusWithPayload( + absl::StatusCode::kNotFound, + "Found ScoreCalibrationOptions but missing required associated " + "parameters file with type TENSOR_AXIS_SCORE_CALIBRATION.", + MediaPipeTasksStatus::kMetadataAssociatedFileNotFoundError); + } + ASSIGN_OR_RETURN( + absl::string_view score_calibration_file, + metadata_extractor.GetAssociatedFile(score_calibration_filename)); + ScoreCalibrationCalculatorOptions score_calibration_calculator_options; + MP_RETURN_IF_ERROR(ConfigureScoreCalibration( + score_calibration_options->score_transformation(), + score_calibration_options->default_score(), score_calibration_file, + &score_calibration_calculator_options)); + return score_calibration_calculator_options; +} + +absl::StatusOr> GetOutputTensorIndices( + const Vector>* tensor_metadatas) { + std::vector output_indices; + if (tensor_metadatas->size() == 4) { + output_indices = { + core::FindTensorIndexByMetadataName(tensor_metadatas, + kLocationTensorName), + core::FindTensorIndexByMetadataName(tensor_metadatas, + kCategoryTensorName), + core::FindTensorIndexByMetadataName(tensor_metadatas, kScoreTensorName), + core::FindTensorIndexByMetadataName(tensor_metadatas, + kNumberOfDetectionsTensorName)}; + // locations, categories, scores, and number of detections + for (int i = 0; i < 4; i++) { + int output_index = output_indices[i]; + // If tensor name is not found, set the default output indices. + if (output_index == -1) { + LOG(WARNING) << absl::StrFormat( + "You don't seem to be matching tensor names in metadata list. The " + "tensor name \"%s\" at index %d in the model metadata doesn't " + "match " + "the available output names: [\"%s\", \"%s\", \"%s\", \"%s\"].", + tensor_metadatas->Get(i)->name()->c_str(), i, kLocationTensorName, + kCategoryTensorName, kScoreTensorName, + kNumberOfDetectionsTensorName); + output_indices = { + kInModelNmsDefaultLocationsIndex, kInModelNmsDefaultCategoriesIndex, + kInModelNmsDefaultScoresIndex, kInModelNmsDefaultNumResultsIndex}; + return output_indices; + } + } + } else if (tensor_metadatas->size() == 2) { + output_indices = {core::FindTensorIndexByMetadataName(tensor_metadatas, + kLocationTensorName), + core::FindTensorIndexByMetadataName(tensor_metadatas, + kScoreTensorName)}; + // location, score + for (int i = 0; i < 2; i++) { + int output_index = output_indices[i]; + // If tensor name is not found, set the default output indices. + if (output_index == -1) { + LOG(WARNING) << absl::StrFormat( + "You don't seem to be matching tensor names in metadata list. The " + "tensor name \"%s\" at index %d in the model metadata doesn't " + "match " + "the available output names: [\"%s\", \"%s\"].", + tensor_metadatas->Get(i)->name()->c_str(), i, kLocationTensorName, + kScoreTensorName); + output_indices = {kOutModelNmsDefaultLocationsIndex, + kOutModelNmsDefaultScoresIndex}; + return output_indices; + } + } + } else { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::StrFormat( + "Expected a model with 2 or 4 output tensors metadata, found %d.", + tensor_metadatas->size()), + MediaPipeTasksStatus::kInvalidArgumentError); + } + return output_indices; +} + +// Builds PostProcessingSpecs from DetectorOptions and model metadata for +// configuring the post-processing calculators. +absl::StatusOr BuildPostProcessingSpecs( + const proto::DetectorOptions& options, bool in_model_nms, + const ModelMetadataExtractor* metadata_extractor) { + const auto* output_tensors_metadata = + metadata_extractor->GetOutputTensorMetadata(); + PostProcessingSpecs specs; + specs.max_results = options.max_results(); + ASSIGN_OR_RETURN(specs.output_tensor_indices, + GetOutputTensorIndices(output_tensors_metadata)); + // Extracts mandatory BoundingBoxProperties and performs sanity checks on the + // fly. + ASSIGN_OR_RETURN(const BoundingBoxProperties* bounding_box_properties, + GetBoundingBoxProperties(*output_tensors_metadata->Get( + specs.output_tensor_indices[0]))); + if (bounding_box_properties->index() == nullptr) { + specs.bounding_box_corners_order = {0, 1, 2, 3}; + } else { + auto bounding_box_index = bounding_box_properties->index(); + specs.bounding_box_corners_order = { + bounding_box_index->Get(0), + bounding_box_index->Get(1), + bounding_box_index->Get(2), + bounding_box_index->Get(3), + }; + } + // Builds label map (if available) from metadata. + // For models with in-model-nms, the label map is stored in the Category + // tensor which use TENSOR_VALUE_LABELS. For models with out-of-model-nms, the + // label map is stored in the Score tensor which use TENSOR_AXIS_LABELS. + ASSIGN_OR_RETURN( + specs.label_items, + GetLabelItemsIfAny( + *metadata_extractor, + *output_tensors_metadata->Get(specs.output_tensor_indices[1]), + in_model_nms ? tflite::AssociatedFileType_TENSOR_VALUE_LABELS + : tflite::AssociatedFileType_TENSOR_AXIS_LABELS, + options.display_names_locale())); + // Obtains allow/deny categories. + specs.is_allowlist = !options.category_allowlist().empty(); + ASSIGN_OR_RETURN( + specs.allow_or_deny_categories, + GetAllowOrDenyCategoryIndicesIfAny(options, specs.label_items)); + + // Sets score threshold. + if (options.has_score_threshold()) { + specs.score_threshold = options.score_threshold(); + } else { + ASSIGN_OR_RETURN( + specs.score_threshold, + GetScoreThreshold( + *metadata_extractor, + *output_tensors_metadata->Get( + specs.output_tensor_indices + [in_model_nms ? kInModelNmsDefaultScoresIndex + : kOutModelNmsDefaultScoresIndex]))); + } + if (in_model_nms) { + // Builds score calibration options (if available) from metadata. + ASSIGN_OR_RETURN( + specs.score_calibration_options, + GetScoreCalibrationOptionsIfAny( + *metadata_extractor, + *output_tensors_metadata->Get( + specs.output_tensor_indices[kInModelNmsDefaultScoresIndex]))); + } + return specs; +} + +// Builds PostProcessingSpecs from DetectorOptions and model metadata for +// configuring the post-processing calculators for models with +// non-maximum-suppression. +absl::StatusOr BuildInModelNmsPostProcessingSpecs( + const proto::DetectorOptions& options, + const ModelMetadataExtractor* metadata_extractor) { + // Checks output tensor metadata is present and consistent with model. + auto* output_tensors_metadata = metadata_extractor->GetOutputTensorMetadata(); + if (output_tensors_metadata == nullptr || + output_tensors_metadata->size() != 4) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::StrFormat("Mismatch between number of output tensors (4) and " + "output tensors metadata (%d).", + output_tensors_metadata == nullptr + ? 0 + : output_tensors_metadata->size()), + MediaPipeTasksStatus::kMetadataInconsistencyError); + } + return BuildPostProcessingSpecs(options, /*in_model_nms=*/true, + metadata_extractor); +} + +// Fills in the TensorsToDetectionsCalculatorOptions based on +// PostProcessingSpecs. +void ConfigureInModelNmsTensorsToDetectionsCalculator( + const PostProcessingSpecs& specs, + mediapipe::TensorsToDetectionsCalculatorOptions* options) { + options->set_num_classes(specs.label_items.size()); + options->set_num_coords(4); + options->set_min_score_thresh(specs.score_threshold); + if (specs.max_results != -1) { + options->set_max_results(specs.max_results); + } + if (specs.is_allowlist) { + options->mutable_allow_classes()->Assign( + specs.allow_or_deny_categories.begin(), + specs.allow_or_deny_categories.end()); + } else { + options->mutable_ignore_classes()->Assign( + specs.allow_or_deny_categories.begin(), + specs.allow_or_deny_categories.end()); + } + + const auto& output_indices = specs.output_tensor_indices; + // Assigns indices to each the model output tensor. + auto* tensor_mapping = options->mutable_tensor_mapping(); + tensor_mapping->set_detections_tensor_index(output_indices[0]); + tensor_mapping->set_classes_tensor_index(output_indices[1]); + tensor_mapping->set_scores_tensor_index(output_indices[2]); + tensor_mapping->set_num_detections_tensor_index(output_indices[3]); + + // Assigns the bounding box corner order. + auto box_boundaries_indices = options->mutable_box_boundaries_indices(); + box_boundaries_indices->set_xmin(specs.bounding_box_corners_order[0]); + box_boundaries_indices->set_ymin(specs.bounding_box_corners_order[1]); + box_boundaries_indices->set_xmax(specs.bounding_box_corners_order[2]); + box_boundaries_indices->set_ymax(specs.bounding_box_corners_order[3]); +} + +// Builds PostProcessingSpecs from DetectorOptions and model metadata for +// configuring the post-processing calculators for models without +// non-maximum-suppression. +absl::StatusOr BuildOutModelNmsPostProcessingSpecs( + const proto::DetectorOptions& options, + const ModelMetadataExtractor* metadata_extractor) { + // Checks output tensor metadata is present and consistent with model. + auto* output_tensors_metadata = metadata_extractor->GetOutputTensorMetadata(); + if (output_tensors_metadata == nullptr || + output_tensors_metadata->size() != 2) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::StrFormat("Mismatch between number of output tensors (2) and " + "output tensors metadata (%d).", + output_tensors_metadata == nullptr + ? 0 + : output_tensors_metadata->size()), + MediaPipeTasksStatus::kMetadataInconsistencyError); + } + return BuildPostProcessingSpecs(options, /*in_model_nms=*/false, + metadata_extractor); +} + +// Configures the TensorsToDetectionCalculator for models without +// non-maximum-suppression in tflite model. The required config parameters are +// extracted from the ObjectDetectorMetadata +// (metadata/object_detector_metadata_schema.fbs). +absl::Status ConfigureOutModelNmsTensorsToDetectionsCalculator( + const ModelMetadataExtractor* metadata_extractor, + const PostProcessingSpecs& specs, + mediapipe::TensorsToDetectionsCalculatorOptions* options) { + bool found_detector_metadata = false; + if (metadata_extractor->GetCustomMetadataList() != nullptr && + metadata_extractor->GetCustomMetadataList()->size() > 0) { + for (const auto* custom_metadata : + *metadata_extractor->GetCustomMetadataList()) { + if (custom_metadata->name()->str() == kDetectorMetadataName) { + found_detector_metadata = true; + const auto* tensors_decoding_options = + GetObjectDetectorOptions(custom_metadata->data()->data()) + ->tensors_decoding_options(); + // Here we don't set the max results for TensorsToDetectionsCalculator. + // For models without nms, the results are filtered by max_results in + // NonMaxSuppressionCalculator. + options->set_num_classes(tensors_decoding_options->num_classes()); + options->set_num_boxes(tensors_decoding_options->num_boxes()); + options->set_num_coords(tensors_decoding_options->num_coords()); + options->set_keypoint_coord_offset( + tensors_decoding_options->keypoint_coord_offset()); + options->set_num_keypoints(tensors_decoding_options->num_keypoints()); + options->set_num_values_per_keypoint( + tensors_decoding_options->num_values_per_keypoint()); + options->set_x_scale(tensors_decoding_options->x_scale()); + options->set_y_scale(tensors_decoding_options->y_scale()); + options->set_w_scale(tensors_decoding_options->w_scale()); + options->set_h_scale(tensors_decoding_options->h_scale()); + options->set_apply_exponential_on_box_size( + tensors_decoding_options->apply_exponential_on_box_size()); + options->set_sigmoid_score(tensors_decoding_options->sigmoid_score()); + break; + } + } + } + if (!found_detector_metadata) { + return absl::InvalidArgumentError( + "TensorsDecodingOptions is not found in the object detector " + "metadata."); + } + // Options not configured through metadata. + options->set_box_format( + mediapipe::TensorsToDetectionsCalculatorOptions::YXHW); + options->set_min_score_thresh(specs.score_threshold); + if (specs.is_allowlist) { + options->mutable_allow_classes()->Assign( + specs.allow_or_deny_categories.begin(), + specs.allow_or_deny_categories.end()); + } else { + options->mutable_ignore_classes()->Assign( + specs.allow_or_deny_categories.begin(), + specs.allow_or_deny_categories.end()); + } + + const auto& output_indices = specs.output_tensor_indices; + // Assigns indices to each the model output tensor. + auto* tensor_mapping = options->mutable_tensor_mapping(); + tensor_mapping->set_detections_tensor_index(output_indices[0]); + tensor_mapping->set_scores_tensor_index(output_indices[1]); + return absl::OkStatus(); +} + +// Configures the SsdAnchorsCalculator for models without +// non-maximum-suppression in tflite model. The required config parameters are +// extracted from the ObjectDetectorMetadata +// (metadata/object_detector_metadata_schema.fbs). +absl::Status ConfigureSsdAnchorsCalculator( + const ModelMetadataExtractor* metadata_extractor, + mediapipe::SsdAnchorsCalculatorOptions* options) { + bool found_detector_metadata = false; + if (metadata_extractor->GetCustomMetadataList() != nullptr && + metadata_extractor->GetCustomMetadataList()->size() > 0) { + for (const auto* custom_metadata : + *metadata_extractor->GetCustomMetadataList()) { + if (custom_metadata->name()->str() == kDetectorMetadataName) { + found_detector_metadata = true; + const auto* ssd_anchors_options = + GetObjectDetectorOptions(custom_metadata->data()->data()) + ->ssd_anchors_options(); + for (const auto* ssd_anchor : + *ssd_anchors_options->fixed_anchors_schema()->anchors()) { + auto* fixed_anchor = options->add_fixed_anchors(); + fixed_anchor->set_y_center(ssd_anchor->y_center()); + fixed_anchor->set_x_center(ssd_anchor->x_center()); + fixed_anchor->set_h(ssd_anchor->height()); + fixed_anchor->set_w(ssd_anchor->width()); + } + break; + } + } + } + if (!found_detector_metadata) { + return absl::InvalidArgumentError( + "SsdAnchorsOptions is not found in the object detector " + "metadata."); + } + return absl::OkStatus(); +} + +// Sets the default IoU-based non-maximum-suppression configs, and set the +// min_suppression_threshold and max_results for detection models without +// non-maximum-suppression. +void ConfigureNonMaxSuppressionCalculator( + const proto::DetectorOptions& detector_options, + mediapipe::NonMaxSuppressionCalculatorOptions* options) { + options->set_min_suppression_threshold( + detector_options.min_suppression_threshold()); + options->set_overlap_type( + mediapipe::NonMaxSuppressionCalculatorOptions::INTERSECTION_OVER_UNION); + options->set_algorithm( + mediapipe::NonMaxSuppressionCalculatorOptions::DEFAULT); + options->set_max_num_detections(detector_options.max_results()); +} + +// Sets the labels from post PostProcessingSpecs. +void ConfigureDetectionLabelIdToTextCalculator( + PostProcessingSpecs& specs, + mediapipe::DetectionLabelIdToTextCalculatorOptions* options) { + *options->mutable_label_items() = std::move(specs.label_items); +} + +// Splits the vector of 4 output tensors from model inference and calibrate the +// score tensors according to the metadata, if any. Then concatenate the tensors +// back to a vector of 4 tensors. +absl::StatusOr>> CalibrateScores( + Source> model_output_tensors, + const proto::DetectionPostprocessingGraphOptions& options, Graph& graph) { + // Split tensors. + auto* split_tensor_vector_node = + &graph.AddNode("SplitTensorVectorCalculator"); + auto& split_tensor_vector_options = + split_tensor_vector_node + ->GetOptions(); + for (int i = 0; i < 4; ++i) { + auto* range = split_tensor_vector_options.add_ranges(); + range->set_begin(i); + range->set_end(i + 1); + } + model_output_tensors >> split_tensor_vector_node->In(0); + + // Add score calibration calculator. + auto* score_calibration_node = &graph.AddNode("ScoreCalibrationCalculator"); + score_calibration_node->GetOptions() + .CopyFrom(options.score_calibration_options()); + const auto& tensor_mapping = + options.tensors_to_detections_options().tensor_mapping(); + split_tensor_vector_node->Out(tensor_mapping.classes_tensor_index()) >> + score_calibration_node->In(kIndicesTag); + split_tensor_vector_node->Out(tensor_mapping.scores_tensor_index()) >> + score_calibration_node->In(kScoresTag); + + // Re-concatenate tensors. + auto* concatenate_tensor_vector_node = + &graph.AddNode("ConcatenateTensorVectorCalculator"); + for (int i = 0; i < 4; ++i) { + if (i == tensor_mapping.scores_tensor_index()) { + score_calibration_node->Out(kCalibratedScoresTag) >> + concatenate_tensor_vector_node->In(i); + } else { + split_tensor_vector_node->Out(i) >> concatenate_tensor_vector_node->In(i); + } + } + model_output_tensors = + concatenate_tensor_vector_node->Out(0).Cast>(); + return model_output_tensors; +} + +} // namespace + +absl::Status ConfigureDetectionPostprocessingGraph( + const tasks::core::ModelResources& model_resources, + const proto::DetectorOptions& detector_options, + proto::DetectionPostprocessingGraphOptions& options) { + MP_RETURN_IF_ERROR(SanityCheckOptions(detector_options)); + const auto& model = *model_resources.GetTfLiteModel(); + bool in_model_nms = false; + if (model.subgraphs()->size() != 1) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::StrFormat("Expected a model with a single subgraph, found %d.", + model.subgraphs()->size()), + MediaPipeTasksStatus::kInvalidArgumentError); + } + if (model.subgraphs()->Get(0)->outputs()->size() == 2) { + in_model_nms = false; + } else if (model.subgraphs()->Get(0)->outputs()->size() == 4) { + in_model_nms = true; + } else { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + absl::StrFormat( + "Expected a model with 2 or 4 output tensors, found %d.", + model.subgraphs()->Get(0)->outputs()->size()), + MediaPipeTasksStatus::kInvalidArgumentError); + } + + const ModelMetadataExtractor* metadata_extractor = + model_resources.GetMetadataExtractor(); + if (in_model_nms) { + ASSIGN_OR_RETURN(auto post_processing_specs, + BuildInModelNmsPostProcessingSpecs(detector_options, + metadata_extractor)); + ConfigureInModelNmsTensorsToDetectionsCalculator( + post_processing_specs, options.mutable_tensors_to_detections_options()); + ConfigureDetectionLabelIdToTextCalculator( + post_processing_specs, + options.mutable_detection_label_ids_to_text_options()); + if (post_processing_specs.score_calibration_options.has_value()) { + *options.mutable_score_calibration_options() = + std::move(*post_processing_specs.score_calibration_options); + } + } else { + ASSIGN_OR_RETURN(auto post_processing_specs, + BuildOutModelNmsPostProcessingSpecs(detector_options, + metadata_extractor)); + MP_RETURN_IF_ERROR(ConfigureOutModelNmsTensorsToDetectionsCalculator( + metadata_extractor, post_processing_specs, + options.mutable_tensors_to_detections_options())); + MP_RETURN_IF_ERROR(ConfigureSsdAnchorsCalculator( + metadata_extractor, options.mutable_ssd_anchors_options())); + ConfigureNonMaxSuppressionCalculator( + detector_options, options.mutable_non_max_suppression_options()); + ConfigureDetectionLabelIdToTextCalculator( + post_processing_specs, + options.mutable_detection_label_ids_to_text_options()); + } + + return absl::OkStatus(); +} + +// A DetectionPostprocessingGraph converts raw tensors into +// std::vector. +// +// Inputs: +// TENSORS - std::vector +// The output tensors of an InferenceCalculator. The tensors vector could be +// size 4 or size 2. Tensors vector of size 4 expects the tensors from the +// models with DETECTION_POSTPROCESS ops in the tflite graph. Tensors vector +// of size 2 expects the tensors from the models without the ops. +// [1]: +// https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/kernels/detection_postprocess.cc +// Outputs: +// DETECTIONS - std::vector +// The postprocessed detection results. +// +// The recommended way of using this graph is through the GraphBuilder API +// using the 'ConfigureDetectionPostprocessingGraph()' function. See header +// file for more details. +class DetectionPostprocessingGraph : public mediapipe::Subgraph { + public: + absl::StatusOr GetConfig( + mediapipe::SubgraphContext* sc) override { + Graph graph; + ASSIGN_OR_RETURN( + auto output_streams, + BuildDetectionPostprocessing( + *sc->MutableOptions(), + graph.In(kTensorsTag).Cast>(), graph)); + output_streams.detections >> + graph.Out(kDetectionsTag).Cast>(); + return graph.GetConfig(); + } + + private: + // Adds an on-device detection postprocessing graph into the provided + // builder::Graph instance. The detection postprocessing graph takes + // tensors (std::vector) as input and returns one output + // stream: + // - Detection results as a std::vector. + // + // graph_options: the on-device DetectionPostprocessingGraphOptions. + // tensors_in: (std::vector>) tensors to postprocess. + // graph: the mediapipe builder::Graph instance to be updated. + absl::StatusOr + BuildDetectionPostprocessing( + proto::DetectionPostprocessingGraphOptions& graph_options, + Source> tensors_in, Graph& graph) { + std::optional>> detections; + if (!graph_options.has_non_max_suppression_options()) { + // Calculators to perform score calibration, if specified in the options. + if (graph_options.has_score_calibration_options()) { + ASSIGN_OR_RETURN(tensors_in, + CalibrateScores(tensors_in, graph_options, graph)); + } + // Calculator to convert output tensors to a detection proto vector. + auto& tensors_to_detections = + graph.AddNode("TensorsToDetectionsCalculator"); + tensors_to_detections + .GetOptions() + .Swap(graph_options.mutable_tensors_to_detections_options()); + tensors_in >> tensors_to_detections.In(kTensorsTag); + detections = tensors_to_detections.Out(kDetectionsTag) + .Cast>(); + } else { + // Generates a single side packet containing a vector of SSD anchors. + auto& ssd_anchor = graph.AddNode("SsdAnchorsCalculator"); + ssd_anchor.GetOptions().Swap( + graph_options.mutable_ssd_anchors_options()); + auto anchors = + ssd_anchor.SideOut("").Cast>(); + // Convert raw output tensors to detections. + auto& tensors_to_detections = + graph.AddNode("TensorsToDetectionsCalculator"); + tensors_to_detections + .GetOptions() + .Swap(graph_options.mutable_tensors_to_detections_options()); + anchors >> tensors_to_detections.SideIn(kAnchorsTag); + tensors_in >> tensors_to_detections.In(kTensorsTag); + detections = tensors_to_detections.Out(kDetectionsTag) + .Cast>(); + // Non maximum suppression removes redundant object detections. + auto& non_maximum_suppression = + graph.AddNode("NonMaxSuppressionCalculator"); + non_maximum_suppression + .GetOptions() + .Swap(graph_options.mutable_non_max_suppression_options()); + *detections >> non_maximum_suppression.In(""); + detections = + non_maximum_suppression.Out("").Cast>(); + } + + // Calculator to assign detection labels. + auto& detection_label_id_to_text = + graph.AddNode("DetectionLabelIdToTextCalculator"); + detection_label_id_to_text + .GetOptions() + .Swap(graph_options.mutable_detection_label_ids_to_text_options()); + *detections >> detection_label_id_to_text.In(""); + return { + {detection_label_id_to_text.Out("").Cast>()}}; + } +}; + +// REGISTER_MEDIAPIPE_GRAPH argument has to fit on one line to work properly. +// clang-format off +REGISTER_MEDIAPIPE_GRAPH( + ::mediapipe::tasks::components::processors::DetectionPostprocessingGraph); // NOLINT +// clang-format on + +} // namespace processors +} // namespace components +} // namespace tasks +} // namespace mediapipe diff --git a/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.h b/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.h new file mode 100644 index 000000000..1696b844f --- /dev/null +++ b/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.h @@ -0,0 +1,62 @@ +/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.pb.h" +#include "mediapipe/tasks/cc/components/processors/proto/detector_options.pb.h" +#include "mediapipe/tasks/cc/core/model_resources.h" + +#ifndef MEDIAPIPE_TASKS_CC_COMPONENTS_PROCESSORS_DETECTION_POSTPROCESSING_GRAPH_H_ +#define MEDIAPIPE_TASKS_CC_COMPONENTS_PROCESSORS_DETECTION_POSTPROCESSING_GRAPH_H_ + +namespace mediapipe { +namespace tasks { +namespace components { +namespace processors { + +// Configures a DetectionPostprocessingGraph using the provided model +// resources and DetectorOptions. +// +// Example usage: +// +// auto& postprocessing = +// graph.AddNode("mediapipe.tasks.components.processors.DetectionPostprocessingGraph"); +// MP_RETURN_IF_ERROR(ConfigureDetectionPostprocessingGraph( +// model_resources, +// detector_options, +// &preprocessing.GetOptions())); +// +// The resulting DetectionPostprocessingGraph has the following I/O: +// Inputs: +// TENSORS - std::vector +// The output tensors of an InferenceCalculator. The tensors vector could be +// size 4 or size 2. Tensors vector of size 4 expects the tensors from the +// models with DETECTION_POSTPROCESS ops in the tflite graph. Tensors vector +// of size 2 expects the tensors from the models without the ops. +// [1]: +// https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/kernels/detection_postprocess.cc +// Outputs: +// DETECTIONS - std::vector +// The postprocessed detection results. +absl::Status ConfigureDetectionPostprocessingGraph( + const tasks::core::ModelResources& model_resources, + const proto::DetectorOptions& detector_options, + proto::DetectionPostprocessingGraphOptions& options); + +} // namespace processors +} // namespace components +} // namespace tasks +} // namespace mediapipe + +#endif // MEDIAPIPE_TASKS_CC_COMPONENTS_PROCESSORS_DETECTION_POSTPROCESSING_GRAPH_H_ diff --git a/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph_test.cc b/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph_test.cc new file mode 100644 index 000000000..36aead0c1 --- /dev/null +++ b/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph_test.cc @@ -0,0 +1,570 @@ +/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.h" + +#include + +#include "absl/flags/flag.h" +#include "absl/memory/memory.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "absl/strings/string_view.h" +#include "mediapipe/calculators/util/detection_label_id_to_text_calculator.pb.h" +#include "mediapipe/framework/api2/builder.h" +#include "mediapipe/framework/api2/packet.h" +#include "mediapipe/framework/api2/port.h" +#include "mediapipe/framework/calculator_framework.h" +#include "mediapipe/framework/calculator_runner.h" +#include "mediapipe/framework/deps/file_path.h" +#include "mediapipe/framework/formats/detection.pb.h" +#include "mediapipe/framework/formats/tensor.h" +#include "mediapipe/framework/graph_runner.h" +#include "mediapipe/framework/output_stream_poller.h" +#include "mediapipe/framework/port/gmock.h" +#include "mediapipe/framework/port/gtest.h" +#include "mediapipe/framework/port/status_matchers.h" +#include "mediapipe/framework/timestamp.h" +#include "mediapipe/tasks/cc/components/calculators/score_calibration_calculator.pb.h" +#include "mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.pb.h" +#include "mediapipe/tasks/cc/components/processors/proto/detector_options.pb.h" +#include "mediapipe/tasks/cc/core/model_resources.h" +#include "mediapipe/tasks/cc/core/proto/external_file.pb.h" +#include "tensorflow/lite/test_util.h" + +namespace mediapipe { +namespace tasks { +namespace components { +namespace processors { +namespace { + +using ::mediapipe::api2::Input; +using ::mediapipe::api2::Output; +using ::mediapipe::api2::builder::Graph; +using ::mediapipe::api2::builder::Source; +using ::mediapipe::file::JoinPath; +using ::mediapipe::tasks::core::ModelResources; +using ::testing::ElementsAre; +using ::testing::HasSubstr; +using ::testing::Pointwise; +using ::testing::proto::Approximately; +using ::testing::proto::Partially; + +constexpr absl::string_view kTestDataDirectory = + "/mediapipe/tasks/testdata/vision"; +constexpr absl::string_view kMobileSsdWithMetadata = + "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.tflite"; +constexpr absl::string_view kMobileSsdWithDummyScoreCalibration = + "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29_with_dummy_score_calibration." + "tflite"; +constexpr absl::string_view kEfficientDetWithoutNms = + "efficientdet_lite0_fp16_no_nms.tflite"; + +constexpr char kTestModelResourcesTag[] = "test_model_resources"; + +constexpr absl::string_view kTensorsTag = "TENSORS"; +constexpr absl::string_view kDetectionsTag = "DETECTIONS"; +constexpr absl::string_view kTensorsName = "tensors"; +constexpr absl::string_view kDetectionsName = "detections"; + +// Helper function to get ModelResources. +absl::StatusOr> CreateModelResourcesForModel( + absl::string_view model_name) { + auto external_file = std::make_unique(); + external_file->set_file_name(JoinPath("./", kTestDataDirectory, model_name)); + return ModelResources::Create(kTestModelResourcesTag, + std::move(external_file)); +} + +class ConfigureTest : public tflite::testing::Test {}; + +TEST_F(ConfigureTest, FailsWithInvalidMaxResults) { + MP_ASSERT_OK_AND_ASSIGN(auto model_resources, + CreateModelResourcesForModel(kMobileSsdWithMetadata)); + proto::DetectorOptions options_in; + options_in.set_max_results(0); + + proto::DetectionPostprocessingGraphOptions options_out; + auto status = ConfigureDetectionPostprocessingGraph(*model_resources, + options_in, options_out); + + EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument); + EXPECT_THAT(status.message(), HasSubstr("Invalid `max_results` option")); +} + +TEST_F(ConfigureTest, FailsWithBothAllowlistAndDenylist) { + MP_ASSERT_OK_AND_ASSIGN(auto model_resources, + CreateModelResourcesForModel(kMobileSsdWithMetadata)); + proto::DetectorOptions options_in; + options_in.add_category_allowlist("foo"); + options_in.add_category_denylist("bar"); + + proto::DetectionPostprocessingGraphOptions options_out; + auto status = ConfigureDetectionPostprocessingGraph(*model_resources, + options_in, options_out); + + EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument); + EXPECT_THAT(status.message(), HasSubstr("mutually exclusive options")); +} + +TEST_F(ConfigureTest, SucceedsWithMaxResults) { + MP_ASSERT_OK_AND_ASSIGN(auto model_resources, + CreateModelResourcesForModel(kMobileSsdWithMetadata)); + proto::DetectorOptions options_in; + options_in.set_max_results(3); + + proto::DetectionPostprocessingGraphOptions options_out; + MP_ASSERT_OK(ConfigureDetectionPostprocessingGraph(*model_resources, + options_in, options_out)); + + EXPECT_THAT( + options_out, + Approximately(Partially(EqualsProto( + R"pb(tensors_to_detections_options { + min_score_thresh: -3.4028235e+38 + num_classes: 90 + num_coords: 4 + max_results: 3 + tensor_mapping { + detections_tensor_index: 0 + classes_tensor_index: 1 + scores_tensor_index: 2 + num_detections_tensor_index: 3 + } + box_boundaries_indices { ymin: 0 xmin: 1 ymax: 2 xmax: 3 } + } + )pb")))); +} + +TEST_F(ConfigureTest, SucceedsWithMaxResultsWithoutModelNms) { + MP_ASSERT_OK_AND_ASSIGN(auto model_resources, CreateModelResourcesForModel( + kEfficientDetWithoutNms)); + proto::DetectorOptions options_in; + options_in.set_max_results(3); + + proto::DetectionPostprocessingGraphOptions options_out; + MP_ASSERT_OK(ConfigureDetectionPostprocessingGraph(*model_resources, + options_in, options_out)); + EXPECT_THAT(options_out, Approximately(Partially(EqualsProto( + R"pb(tensors_to_detections_options { + min_score_thresh: -3.4028235e+38 + num_classes: 90 + num_boxes: 19206 + num_coords: 4 + x_scale: 1 + y_scale: 1 + w_scale: 1 + h_scale: 1 + keypoint_coord_offset: 0 + num_keypoints: 0 + num_values_per_keypoint: 2 + apply_exponential_on_box_size: true + sigmoid_score: false + tensor_mapping { + detections_tensor_index: 1 + scores_tensor_index: 0 + } + box_format: YXHW + } + non_max_suppression_options { + max_num_detections: 3 + min_suppression_threshold: 0 + overlap_type: INTERSECTION_OVER_UNION + algorithm: DEFAULT + } + )pb")))); + EXPECT_THAT( + options_out.detection_label_ids_to_text_options().label_items_size(), 90); +} + +TEST_F(ConfigureTest, SucceedsWithScoreThreshold) { + MP_ASSERT_OK_AND_ASSIGN(auto model_resources, + CreateModelResourcesForModel(kMobileSsdWithMetadata)); + proto::DetectorOptions options_in; + options_in.set_score_threshold(0.5); + + proto::DetectionPostprocessingGraphOptions options_out; + MP_ASSERT_OK(ConfigureDetectionPostprocessingGraph(*model_resources, + options_in, options_out)); + EXPECT_THAT( + options_out, + Approximately(Partially(EqualsProto( + R"pb(tensors_to_detections_options { + min_score_thresh: 0.5 + num_classes: 90 + num_coords: 4 + tensor_mapping { + detections_tensor_index: 0 + classes_tensor_index: 1 + scores_tensor_index: 2 + num_detections_tensor_index: 3 + } + box_boundaries_indices { ymin: 0 xmin: 1 ymax: 2 xmax: 3 } + } + )pb")))); + EXPECT_THAT( + options_out.detection_label_ids_to_text_options().label_items_size(), 90); +} + +TEST_F(ConfigureTest, SucceedsWithAllowlist) { + MP_ASSERT_OK_AND_ASSIGN(auto model_resources, + CreateModelResourcesForModel(kMobileSsdWithMetadata)); + proto::DetectorOptions options_in; + options_in.add_category_allowlist("bicycle"); + proto::DetectionPostprocessingGraphOptions options_out; + MP_ASSERT_OK(ConfigureDetectionPostprocessingGraph(*model_resources, + options_in, options_out)); + // Clear labels ids to text and compare the rest of the options. + options_out.clear_detection_label_ids_to_text_options(); + EXPECT_THAT( + options_out, + Approximately(EqualsProto( + R"pb(tensors_to_detections_options { + min_score_thresh: -3.4028235e+38 + num_classes: 90 + num_coords: 4 + allow_classes: 1 + tensor_mapping { + detections_tensor_index: 0 + classes_tensor_index: 1 + scores_tensor_index: 2 + num_detections_tensor_index: 3 + } + box_boundaries_indices { ymin: 0 xmin: 1 ymax: 2 xmax: 3 } + } + )pb"))); +} + +TEST_F(ConfigureTest, SucceedsWithDenylist) { + MP_ASSERT_OK_AND_ASSIGN(auto model_resources, + CreateModelResourcesForModel(kMobileSsdWithMetadata)); + proto::DetectorOptions options_in; + options_in.add_category_denylist("person"); + proto::DetectionPostprocessingGraphOptions options_out; + MP_ASSERT_OK(ConfigureDetectionPostprocessingGraph(*model_resources, + options_in, options_out)); + // Clear labels ids to text and compare the rest of the options. + options_out.clear_detection_label_ids_to_text_options(); + EXPECT_THAT( + options_out, + Approximately(EqualsProto( + R"pb(tensors_to_detections_options { + min_score_thresh: -3.4028235e+38 + num_classes: 90 + num_coords: 4 + ignore_classes: 0 + tensor_mapping { + detections_tensor_index: 0 + classes_tensor_index: 1 + scores_tensor_index: 2 + num_detections_tensor_index: 3 + } + box_boundaries_indices { ymin: 0 xmin: 1 ymax: 2 xmax: 3 } + } + )pb"))); +} + +TEST_F(ConfigureTest, SucceedsWithScoreCalibration) { + MP_ASSERT_OK_AND_ASSIGN( + auto model_resources, + CreateModelResourcesForModel(kMobileSsdWithDummyScoreCalibration)); + proto::DetectorOptions options_in; + proto::DetectionPostprocessingGraphOptions options_out; + MP_ASSERT_OK(ConfigureDetectionPostprocessingGraph(*model_resources, + options_in, options_out)); + // Clear labels ids to text. + options_out.clear_detection_label_ids_to_text_options(); + // Check sigmoids size and first element. + ASSERT_EQ(options_out.score_calibration_options().sigmoids_size(), 89); + EXPECT_THAT(options_out.score_calibration_options().sigmoids()[0], + EqualsProto(R"pb(scale: 1.0 slope: 1.0 offset: 0.0)pb")); + options_out.mutable_score_calibration_options()->clear_sigmoids(); + // Compare the rest of the option. + EXPECT_THAT( + options_out, + Approximately(EqualsProto( + R"pb(tensors_to_detections_options { + min_score_thresh: -3.4028235e+38 + num_classes: 90 + num_coords: 4 + tensor_mapping { + detections_tensor_index: 0 + classes_tensor_index: 1 + scores_tensor_index: 2 + num_detections_tensor_index: 3 + } + box_boundaries_indices { ymin: 0 xmin: 1 ymax: 2 xmax: 3 } + } + score_calibration_options { + score_transformation: IDENTITY + default_score: 0.5 + } + )pb"))); +} + +class PostprocessingTest : public tflite::testing::Test { + protected: + absl::StatusOr BuildGraph( + absl::string_view model_name, const proto::DetectorOptions& options) { + ASSIGN_OR_RETURN(auto model_resources, + CreateModelResourcesForModel(model_name)); + + Graph graph; + auto& postprocessing = graph.AddNode( + "mediapipe.tasks.components.processors." + "DetectionPostprocessingGraph"); + MP_RETURN_IF_ERROR(ConfigureDetectionPostprocessingGraph( + *model_resources, options, + postprocessing + .GetOptions())); + graph[Input>(kTensorsTag)].SetName( + std::string(kTensorsName)) >> + postprocessing.In(kTensorsTag); + postprocessing.Out(kDetectionsTag).SetName(std::string(kDetectionsName)) >> + graph[Output>(kDetectionsTag)]; + MP_RETURN_IF_ERROR(calculator_graph_.Initialize(graph.GetConfig())); + ASSIGN_OR_RETURN(auto poller, calculator_graph_.AddOutputStreamPoller( + std::string(kDetectionsName))); + MP_RETURN_IF_ERROR(calculator_graph_.StartRun(/*extra_side_packets=*/{})); + return poller; + } + + template + void AddTensor(const std::vector& tensor, + const Tensor::ElementType& element_type, + const Tensor::Shape& shape) { + tensors_->emplace_back(element_type, shape); + auto view = tensors_->back().GetCpuWriteView(); + T* buffer = view.buffer(); + std::copy(tensor.begin(), tensor.end(), buffer); + } + + absl::Status Run(int timestamp = 0) { + MP_RETURN_IF_ERROR(calculator_graph_.AddPacketToInputStream( + std::string(kTensorsName), + Adopt(tensors_.release()).At(Timestamp(timestamp)))); + // Reset tensors for future calls. + tensors_ = absl::make_unique>(); + return absl::OkStatus(); + } + + template + absl::StatusOr GetResult(OutputStreamPoller& poller) { + MP_RETURN_IF_ERROR(calculator_graph_.WaitUntilIdle()); + MP_RETURN_IF_ERROR(calculator_graph_.CloseAllInputStreams()); + + Packet packet; + if (!poller.Next(&packet)) { + return absl::InternalError("Unable to get output packet"); + } + auto result = packet.Get(); + MP_RETURN_IF_ERROR(calculator_graph_.WaitUntilDone()); + return result; + } + + private: + CalculatorGraph calculator_graph_; + std::unique_ptr> tensors_ = + absl::make_unique>(); +}; + +TEST_F(PostprocessingTest, SucceedsWithMetadata) { + // Build graph. + proto::DetectorOptions options; + options.set_max_results(3); + MP_ASSERT_OK_AND_ASSIGN(auto poller, + BuildGraph(kMobileSsdWithMetadata, options)); + + // Build input tensors. + constexpr int kBboxesNum = 5; + // Location tensor. + std::vector location_tensor(kBboxesNum * 4, 0); + for (int i = 0; i < kBboxesNum; ++i) { + location_tensor[i * 4] = 0.1f; + location_tensor[i * 4 + 1] = 0.1f; + location_tensor[i * 4 + 2] = 0.4f; + location_tensor[i * 4 + 3] = 0.5f; + } + // Category tensor. + std::vector category_tensor(kBboxesNum, 0); + for (int i = 0; i < kBboxesNum; ++i) { + category_tensor[i] = i + 1; + } + + // Score tensor. Post processed tensor scores are in descending order. + std::vector score_tensor(kBboxesNum, 0); + for (int i = 0; i < kBboxesNum; ++i) { + score_tensor[i] = static_cast(kBboxesNum - i) / kBboxesNum; + } + + // Number of detections tensor. + std::vector num_detections_tensor(1, 0); + num_detections_tensor[0] = kBboxesNum; + + // Send tensors and get results. + AddTensor(location_tensor, Tensor::ElementType::kFloat32, {1, kBboxesNum, 4}); + AddTensor(category_tensor, Tensor::ElementType::kFloat32, {1, kBboxesNum}); + AddTensor(score_tensor, Tensor::ElementType::kFloat32, {1, kBboxesNum}); + AddTensor(num_detections_tensor, Tensor::ElementType::kFloat32, {1}); + MP_ASSERT_OK(Run()); + + // Validate results. + EXPECT_THAT(GetResult>(poller), + IsOkAndHolds(ElementsAre(Approximately(EqualsProto( + R"pb( + label: "bicycle" + score: 1 + location_data { + format: RELATIVE_BOUNDING_BOX + relative_bounding_box { + xmin: 0.1 + ymin: 0.1 + width: 0.4 + height: 0.3 + } + } + )pb")), + Approximately(EqualsProto( + R"pb( + label: "car" + score: 0.8 + location_data { + format: RELATIVE_BOUNDING_BOX + relative_bounding_box { + xmin: 0.1 + ymin: 0.1 + width: 0.4 + height: 0.3 + } + } + )pb")), + Approximately(EqualsProto( + R"pb( + label: "motorcycle" + score: 0.6 + location_data { + format: RELATIVE_BOUNDING_BOX + relative_bounding_box { + xmin: 0.1 + ymin: 0.1 + width: 0.4 + height: 0.3 + } + } + )pb"))))); +} + +TEST_F(PostprocessingTest, SucceedsWithOutModelNms) { + // Build graph. + proto::DetectorOptions options; + options.set_max_results(3); + MP_ASSERT_OK_AND_ASSIGN(auto poller, + BuildGraph(kEfficientDetWithoutNms, options)); + + // Build input tensors. + constexpr int kBboxesNum = 19206; + constexpr int kBicycleBboxIdx = 1000; + constexpr int kCarBboxIdx = 2000; + constexpr int kMotoCycleBboxIdx = 4000; + // Location tensor. + std::vector location_tensor(kBboxesNum * 4, 0); + for (int i = 0; i < kBboxesNum; ++i) { + location_tensor[i * 4] = 0.5f; + location_tensor[i * 4 + 1] = 0.5f; + location_tensor[i * 4 + 2] = 0.001f; + location_tensor[i * 4 + 3] = 0.001f; + } + + // Detected three objects. + location_tensor[kBicycleBboxIdx * 4] = 0.7f; + location_tensor[kBicycleBboxIdx * 4 + 1] = 0.8f; + location_tensor[kBicycleBboxIdx * 4 + 2] = 0.2f; + location_tensor[kBicycleBboxIdx * 4 + 3] = 0.1f; + + location_tensor[kCarBboxIdx * 4] = 0.1f; + location_tensor[kCarBboxIdx * 4 + 1] = 0.1f; + location_tensor[kCarBboxIdx * 4 + 2] = 0.1f; + location_tensor[kCarBboxIdx * 4 + 3] = 0.1f; + + location_tensor[kMotoCycleBboxIdx * 4] = 0.2f; + location_tensor[kMotoCycleBboxIdx * 4 + 1] = 0.8f; + location_tensor[kMotoCycleBboxIdx * 4 + 2] = 0.1f; + location_tensor[kMotoCycleBboxIdx * 4 + 3] = 0.2f; + + // Score tensor. + constexpr int kClassesNum = 90; + std::vector score_tensor(kBboxesNum * kClassesNum, 1.f / kClassesNum); + + // Detected three objects. + score_tensor[kBicycleBboxIdx * kClassesNum + 1] = 1.0f; // bicycle. + score_tensor[kCarBboxIdx * kClassesNum + 2] = 0.9f; // car. + score_tensor[kMotoCycleBboxIdx * kClassesNum + 3] = 0.8f; // motorcycle. + + // Send tensors and get results. + AddTensor(score_tensor, Tensor::ElementType::kFloat32, {1, kBboxesNum, 90}); + AddTensor(location_tensor, Tensor::ElementType::kFloat32, {1, kBboxesNum, 4}); + MP_ASSERT_OK(Run()); + + // Validate results. + EXPECT_THAT(GetResult>(poller), + IsOkAndHolds(ElementsAre(Approximately(EqualsProto( + R"pb( + label: "bicycle" + score: 1 + location_data { + format: RELATIVE_BOUNDING_BOX + relative_bounding_box { + xmin: 0.8137423 + ymin: 0.067235775 + width: 0.117221 + height: 0.064774655 + } + } + )pb")), + Approximately(EqualsProto( + R"pb( + label: "car" + score: 0.9 + location_data { + format: RELATIVE_BOUNDING_BOX + relative_bounding_box { + xmin: 0.53849804 + ymin: 0.08949606 + width: 0.05861056 + height: 0.11722109 + } + } + )pb")), + Approximately(EqualsProto( + R"pb( + label: "motorcycle" + score: 0.8 + location_data { + format: RELATIVE_BOUNDING_BOX + relative_bounding_box { + xmin: 0.13779688 + ymin: 0.26394117 + width: 0.16322193 + height: 0.07384467 + } + } + )pb"))))); +} + +} // namespace +} // namespace processors +} // namespace components +} // namespace tasks +} // namespace mediapipe diff --git a/mediapipe/tasks/cc/components/processors/proto/BUILD b/mediapipe/tasks/cc/components/processors/proto/BUILD index 1877bc7e2..82d4ea21b 100644 --- a/mediapipe/tasks/cc/components/processors/proto/BUILD +++ b/mediapipe/tasks/cc/components/processors/proto/BUILD @@ -23,6 +23,11 @@ mediapipe_proto_library( srcs = ["classifier_options.proto"], ) +mediapipe_proto_library( + name = "detector_options_proto", + srcs = ["detector_options.proto"], +) + mediapipe_proto_library( name = "classification_postprocessing_graph_options_proto", srcs = ["classification_postprocessing_graph_options.proto"], @@ -35,6 +40,20 @@ mediapipe_proto_library( ], ) +mediapipe_proto_library( + name = "detection_postprocessing_graph_options_proto", + srcs = ["detection_postprocessing_graph_options.proto"], + deps = [ + "//mediapipe/calculators/tensor:tensors_to_detections_calculator_proto", + "//mediapipe/calculators/tflite:ssd_anchors_calculator_proto", + "//mediapipe/calculators/util:detection_label_id_to_text_calculator_proto", + "//mediapipe/calculators/util:non_max_suppression_calculator_proto", + "//mediapipe/framework:calculator_options_proto", + "//mediapipe/framework:calculator_proto", + "//mediapipe/tasks/cc/components/calculators:score_calibration_calculator_proto", + ], +) + mediapipe_proto_library( name = "embedder_options_proto", srcs = ["embedder_options.proto"], diff --git a/mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.proto b/mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.proto new file mode 100644 index 000000000..ec11df2b4 --- /dev/null +++ b/mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.proto @@ -0,0 +1,49 @@ +/* Copyright 2023 The MediaPipe Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +syntax = "proto3"; + +package mediapipe.tasks.components.processors.proto; + +import "mediapipe/calculators/tensor/tensors_to_detections_calculator.proto"; +import "mediapipe/calculators/tflite/ssd_anchors_calculator.proto"; +import "mediapipe/calculators/util/detection_label_id_to_text_calculator.proto"; +import "mediapipe/calculators/util/non_max_suppression_calculator.proto"; +import "mediapipe/framework/calculator.proto"; +import "mediapipe/tasks/cc/components/calculators/score_calibration_calculator.proto"; + +message DetectionPostprocessingGraphOptions { + // Optional SsdAnchorsCalculatorOptions for models without + // non-maximum-suppression in tflite model graph. + optional mediapipe.SsdAnchorsCalculatorOptions ssd_anchors_options = 1; + + // Optional TensorsToDetectionsCalculatorOptions for models without + // non-maximum-suppression in tflite model graph. + optional mediapipe.TensorsToDetectionsCalculatorOptions + tensors_to_detections_options = 2; + + // Optional NonMaxSuppressionCalculatorOptions for models without + // non-maximum-suppression in tflite model graph. + optional mediapipe.NonMaxSuppressionCalculatorOptions + non_max_suppression_options = 3; + + // Optional score calibration options for models with non-maximum-suppression + // in tflite model graph. + optional ScoreCalibrationCalculatorOptions score_calibration_options = 4; + + // Optional detection label id to text calculator options. + optional mediapipe.DetectionLabelIdToTextCalculatorOptions + detection_label_ids_to_text_options = 5; +} diff --git a/mediapipe/tasks/cc/components/processors/proto/detector_options.proto b/mediapipe/tasks/cc/components/processors/proto/detector_options.proto new file mode 100644 index 000000000..c70b1f7a6 --- /dev/null +++ b/mediapipe/tasks/cc/components/processors/proto/detector_options.proto @@ -0,0 +1,52 @@ +/* Copyright 2022 The MediaPipe Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +syntax = "proto2"; + +package mediapipe.tasks.components.processors.proto; + +option java_package = "com.google.mediapipe.tasks.components.processors.proto"; +option java_outer_classname = "DetectorOptionsProto"; + +// Shared options used by all detection tasks. +message DetectorOptions { + // The locale to use for display names specified through the TFLite Model + // Metadata, if any. Defaults to English. + optional string display_names_locale = 1 [default = "en"]; + + // The maximum number of top-scored detection results to return. If < 0, + // all available results will be returned. If 0, an invalid argument error is + // returned. + optional int32 max_results = 2 [default = -1]; + + // Score threshold, overrides the ones provided in the model metadata + // (if any). Results below this value are rejected. + optional float score_threshold = 3; + + // Overlapping threshold for non-maximum-suppression calculator. Only used for + // models without built-in non-maximum-suppression, i.e., models that don't + // use the Detection_Postprocess TFLite Op + optional float min_suppression_threshold = 6; + + // Optional allowlist of category names. If non-empty, detections whose + // category name is not in this set will be filtered out. Duplicate or unknown + // category names are ignored. Mutually exclusive with category_denylist. + repeated string category_allowlist = 4; + + // Optional denylist of category names. If non-empty, detection whose category + // name is in this set will be filtered out. Duplicate or unknown category + // names are ignored. Mutually exclusive with category_allowlist. + repeated string category_denylist = 5; +} diff --git a/mediapipe/tasks/cc/vision/object_detector/BUILD b/mediapipe/tasks/cc/vision/object_detector/BUILD index 855fc29f5..40d7ab50b 100644 --- a/mediapipe/tasks/cc/vision/object_detector/BUILD +++ b/mediapipe/tasks/cc/vision/object_detector/BUILD @@ -54,12 +54,7 @@ cc_library( name = "object_detector_graph", srcs = ["object_detector_graph.cc"], deps = [ - "//mediapipe/calculators/core:split_vector_calculator_cc_proto", "//mediapipe/calculators/tensor:inference_calculator", - "//mediapipe/calculators/tensor:tensors_to_detections_calculator", - "//mediapipe/calculators/tensor:tensors_to_detections_calculator_cc_proto", - "//mediapipe/calculators/util:detection_label_id_to_text_calculator", - "//mediapipe/calculators/util:detection_label_id_to_text_calculator_cc_proto", "//mediapipe/calculators/util:detection_projection_calculator", "//mediapipe/calculators/util:detection_transformation_calculator", "//mediapipe/calculators/util:detections_deduplicate_calculator", @@ -71,19 +66,15 @@ cc_library( "//mediapipe/framework/formats:rect_cc_proto", "//mediapipe/framework/formats:tensor", "//mediapipe/tasks/cc:common", - "//mediapipe/tasks/cc/components/calculators:score_calibration_calculator_cc_proto", - "//mediapipe/tasks/cc/components/calculators:score_calibration_utils", + "//mediapipe/tasks/cc/components/processors:detection_postprocessing_graph", "//mediapipe/tasks/cc/components/processors:image_preprocessing_graph", + "//mediapipe/tasks/cc/components/processors/proto:detection_postprocessing_graph_options_cc_proto", + "//mediapipe/tasks/cc/components/processors/proto:detector_options_cc_proto", "//mediapipe/tasks/cc/core:model_resources", "//mediapipe/tasks/cc/core:model_task_graph", - "//mediapipe/tasks/cc/core:utils", - "//mediapipe/tasks/cc/core/proto:acceleration_cc_proto", "//mediapipe/tasks/cc/core/proto:inference_subgraph_cc_proto", - "//mediapipe/tasks/cc/metadata:metadata_extractor", "//mediapipe/tasks/cc/vision/object_detector/proto:object_detector_options_cc_proto", "//mediapipe/tasks/metadata:metadata_schema_cc", - "//mediapipe/util:label_map_cc_proto", - "//mediapipe/util:label_map_util", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", ], diff --git a/mediapipe/tasks/cc/vision/object_detector/object_detector.h b/mediapipe/tasks/cc/vision/object_detector/object_detector.h index bddbef4bb..de2c0dbaf 100644 --- a/mediapipe/tasks/cc/vision/object_detector/object_detector.h +++ b/mediapipe/tasks/cc/vision/object_detector/object_detector.h @@ -99,7 +99,20 @@ struct ObjectDetectorOptions { // - only RGB inputs are supported (`channels` is required to be 3). // - if type is kTfLiteFloat32, NormalizationOptions are required to be // attached to the metadata for input normalization. -// Output tensors must be the 4 outputs of a `DetectionPostProcess` op, i.e: +// Output tensors could be 2 output tensors or 4 output tensors. +// The 2 output tensors must represent locations and scores, respectively. +// (kTfLiteFloat32) +// - locations tensor of size `[num_results x num_coords]`. The num_coords is +// the number of coordinates a location result represent. Usually in the +// form: [4 + 2 * keypoint_num], where 4 location values encode the bounding +// box (y_center, x_center, height, width) and the additional keypoints are in +// (y, x) order. +// (kTfLiteFloat32) +// - scores tensor of size `[num_results x num_classes]`. The values of a +// result represent the classification probability belonging to the class at +// the index, which is denoted in the label file of corresponding tensor +// metadata in the model file. +// The 4 output tensors must come from `DetectionPostProcess` op, i.e: // (kTfLiteFloat32) // - locations tensor of size `[num_results x 4]`, the inner array // representing bounding boxes in the form [top, left, right, bottom]. diff --git a/mediapipe/tasks/cc/vision/object_detector/object_detector_graph.cc b/mediapipe/tasks/cc/vision/object_detector/object_detector_graph.cc index 783ed742a..e2b374970 100644 --- a/mediapipe/tasks/cc/vision/object_detector/object_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/object_detector/object_detector_graph.cc @@ -13,16 +13,10 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ -#include -#include -#include #include #include "absl/status/status.h" #include "absl/status/statusor.h" -#include "mediapipe/calculators/core/split_vector_calculator.pb.h" -#include "mediapipe/calculators/tensor/tensors_to_detections_calculator.pb.h" -#include "mediapipe/calculators/util/detection_label_id_to_text_calculator.pb.h" #include "mediapipe/framework/api2/builder.h" #include "mediapipe/framework/api2/port.h" #include "mediapipe/framework/calculator.pb.h" @@ -31,19 +25,15 @@ limitations under the License. #include "mediapipe/framework/formats/rect.pb.h" #include "mediapipe/framework/formats/tensor.h" #include "mediapipe/tasks/cc/common.h" -#include "mediapipe/tasks/cc/components/calculators/score_calibration_calculator.pb.h" -#include "mediapipe/tasks/cc/components/calculators/score_calibration_utils.h" +#include "mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.h" #include "mediapipe/tasks/cc/components/processors/image_preprocessing_graph.h" +#include "mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.pb.h" +#include "mediapipe/tasks/cc/components/processors/proto/detector_options.pb.h" #include "mediapipe/tasks/cc/core/model_resources.h" #include "mediapipe/tasks/cc/core/model_task_graph.h" -#include "mediapipe/tasks/cc/core/proto/acceleration.pb.h" #include "mediapipe/tasks/cc/core/proto/inference_subgraph.pb.h" -#include "mediapipe/tasks/cc/core/utils.h" -#include "mediapipe/tasks/cc/metadata/metadata_extractor.h" #include "mediapipe/tasks/cc/vision/object_detector/proto/object_detector_options.pb.h" #include "mediapipe/tasks/metadata/metadata_schema_generated.h" -#include "mediapipe/util/label_map.pb.h" -#include "mediapipe/util/label_map_util.h" namespace mediapipe { namespace tasks { @@ -56,42 +46,18 @@ using ::mediapipe::api2::Input; using ::mediapipe::api2::Output; using ::mediapipe::api2::builder::Graph; using ::mediapipe::api2::builder::Source; -using ::mediapipe::tasks::metadata::ModelMetadataExtractor; -using ::tflite::BoundingBoxProperties; -using ::tflite::ContentProperties; -using ::tflite::ContentProperties_BoundingBoxProperties; -using ::tflite::EnumNameContentProperties; -using ::tflite::ProcessUnit; -using ::tflite::ProcessUnitOptions_ScoreThresholdingOptions; -using ::tflite::TensorMetadata; -using LabelItems = mediapipe::proto_ns::Map; using ObjectDetectorOptionsProto = object_detector::proto::ObjectDetectorOptions; using TensorsSource = mediapipe::api2::builder::Source>; -constexpr int kDefaultLocationsIndex = 0; -constexpr int kDefaultCategoriesIndex = 1; -constexpr int kDefaultScoresIndex = 2; -constexpr int kDefaultNumResultsIndex = 3; - -constexpr float kDefaultScoreThreshold = std::numeric_limits::lowest(); - -constexpr char kLocationTensorName[] = "location"; -constexpr char kCategoryTensorName[] = "category"; -constexpr char kScoreTensorName[] = "score"; -constexpr char kNumberOfDetectionsTensorName[] = "number of detections"; - -constexpr char kCalibratedScoresTag[] = "CALIBRATED_SCORES"; constexpr char kDetectionsTag[] = "DETECTIONS"; constexpr char kImageSizeTag[] = "IMAGE_SIZE"; constexpr char kImageTag[] = "IMAGE"; -constexpr char kIndicesTag[] = "INDICES"; constexpr char kMatrixTag[] = "MATRIX"; constexpr char kNormRectTag[] = "NORM_RECT"; constexpr char kPixelDetectionsTag[] = "PIXEL_DETECTIONS"; constexpr char kProjectionMatrixTag[] = "PROJECTION_MATRIX"; -constexpr char kScoresTag[] = "SCORES"; constexpr char kTensorTag[] = "TENSORS"; // Struct holding the different output streams produced by the object detection @@ -101,34 +67,6 @@ struct ObjectDetectionOutputStreams { Source image; }; -// Parameters used for configuring the post-processing calculators. -struct PostProcessingSpecs { - // The maximum number of detection results to return. - int max_results; - // Indices of the output tensors to match the output tensors to the correct - // index order of the output tensors: [location, categories, scores, - // num_detections]. - std::vector output_tensor_indices; - // For each pack of 4 coordinates returned by the model, this denotes the - // order in which to get the left, top, right and bottom coordinates. - std::vector bounding_box_corners_order; - // This is populated by reading the label files from the TFLite Model - // Metadata: if no such files are available, this is left empty and the - // ObjectDetector will only be able to populate the `index` field of the - // detection results. - LabelItems label_items; - // Score threshold. Detections with a confidence below this value are - // discarded. If none is provided via metadata or options, -FLT_MAX is set as - // default value. - float score_threshold; - // Set of category indices to be allowed/denied. - absl::flat_hash_set allow_or_deny_categories; - // Indicates `allow_or_deny_categories` is an allowlist or a denylist. - bool is_allowlist; - // Score calibration options, if any. - std::optional score_calibration_options; -}; - absl::Status SanityCheckOptions(const ObjectDetectorOptionsProto& options) { if (options.max_results() == 0) { return CreateStatusWithPayload( @@ -147,310 +85,6 @@ absl::Status SanityCheckOptions(const ObjectDetectorOptionsProto& options) { return absl::OkStatus(); } -absl::StatusOr GetBoundingBoxProperties( - const TensorMetadata& tensor_metadata) { - if (tensor_metadata.content() == nullptr || - tensor_metadata.content()->content_properties() == nullptr) { - return CreateStatusWithPayload( - absl::StatusCode::kInvalidArgument, - absl::StrFormat( - "Expected BoundingBoxProperties for tensor %s, found none.", - tensor_metadata.name() ? tensor_metadata.name()->str() : "#0"), - MediaPipeTasksStatus::kMetadataInvalidContentPropertiesError); - } - - ContentProperties type = tensor_metadata.content()->content_properties_type(); - if (type != ContentProperties_BoundingBoxProperties) { - return CreateStatusWithPayload( - absl::StatusCode::kInvalidArgument, - absl::StrFormat( - "Expected BoundingBoxProperties for tensor %s, found %s.", - tensor_metadata.name() ? tensor_metadata.name()->str() : "#0", - EnumNameContentProperties(type)), - MediaPipeTasksStatus::kMetadataInvalidContentPropertiesError); - } - - const BoundingBoxProperties* properties = - tensor_metadata.content()->content_properties_as_BoundingBoxProperties(); - - // Mobile SSD only supports "BOUNDARIES" bounding box type. - if (properties->type() != tflite::BoundingBoxType_BOUNDARIES) { - return CreateStatusWithPayload( - absl::StatusCode::kInvalidArgument, - absl::StrFormat( - "Mobile SSD only supports BoundingBoxType BOUNDARIES, found %s", - tflite::EnumNameBoundingBoxType(properties->type())), - MediaPipeTasksStatus::kMetadataInvalidContentPropertiesError); - } - - // Mobile SSD only supports "RATIO" coordinates type. - if (properties->coordinate_type() != tflite::CoordinateType_RATIO) { - return CreateStatusWithPayload( - absl::StatusCode::kInvalidArgument, - absl::StrFormat( - "Mobile SSD only supports CoordinateType RATIO, found %s", - tflite::EnumNameCoordinateType(properties->coordinate_type())), - MediaPipeTasksStatus::kMetadataInvalidContentPropertiesError); - } - - // Index is optional, but must contain 4 values if present. - if (properties->index() != nullptr && properties->index()->size() != 4) { - return CreateStatusWithPayload( - absl::StatusCode::kInvalidArgument, - absl::StrFormat( - "Expected BoundingBoxProperties index to contain 4 values, found " - "%d", - properties->index()->size()), - MediaPipeTasksStatus::kMetadataInvalidContentPropertiesError); - } - - return properties; -} - -absl::StatusOr GetLabelItemsIfAny( - const ModelMetadataExtractor& metadata_extractor, - const TensorMetadata& tensor_metadata, absl::string_view locale) { - const std::string labels_filename = - ModelMetadataExtractor::FindFirstAssociatedFileName( - tensor_metadata, tflite::AssociatedFileType_TENSOR_VALUE_LABELS); - if (labels_filename.empty()) { - LabelItems empty_label_items; - return empty_label_items; - } - ASSIGN_OR_RETURN(absl::string_view labels_file, - metadata_extractor.GetAssociatedFile(labels_filename)); - const std::string display_names_filename = - ModelMetadataExtractor::FindFirstAssociatedFileName( - tensor_metadata, tflite::AssociatedFileType_TENSOR_VALUE_LABELS, - locale); - absl::string_view display_names_file; - if (!display_names_filename.empty()) { - ASSIGN_OR_RETURN(display_names_file, metadata_extractor.GetAssociatedFile( - display_names_filename)); - } - return mediapipe::BuildLabelMapFromFiles(labels_file, display_names_file); -} - -absl::StatusOr GetScoreThreshold( - const ModelMetadataExtractor& metadata_extractor, - const TensorMetadata& tensor_metadata) { - ASSIGN_OR_RETURN( - const ProcessUnit* score_thresholding_process_unit, - metadata_extractor.FindFirstProcessUnit( - tensor_metadata, ProcessUnitOptions_ScoreThresholdingOptions)); - if (score_thresholding_process_unit == nullptr) { - return kDefaultScoreThreshold; - } - return score_thresholding_process_unit->options_as_ScoreThresholdingOptions() - ->global_score_threshold(); -} - -absl::StatusOr> GetAllowOrDenyCategoryIndicesIfAny( - const ObjectDetectorOptionsProto& config, const LabelItems& label_items) { - absl::flat_hash_set category_indices; - // Exit early if no denylist/allowlist. - if (config.category_denylist_size() == 0 && - config.category_allowlist_size() == 0) { - return category_indices; - } - if (label_items.empty()) { - return CreateStatusWithPayload( - absl::StatusCode::kInvalidArgument, - "Using `category_allowlist` or `category_denylist` requires " - "labels to be present in the TFLite Model Metadata but none was found.", - MediaPipeTasksStatus::kMetadataMissingLabelsError); - } - const auto& category_list = config.category_allowlist_size() > 0 - ? config.category_allowlist() - : config.category_denylist(); - for (const auto& category_name : category_list) { - int index = -1; - for (int i = 0; i < label_items.size(); ++i) { - if (label_items.at(i).name() == category_name) { - index = i; - break; - } - } - // Ignores duplicate or unknown categories. - if (index < 0) { - continue; - } - category_indices.insert(index); - } - return category_indices; -} - -absl::StatusOr> -GetScoreCalibrationOptionsIfAny( - const ModelMetadataExtractor& metadata_extractor, - const TensorMetadata& tensor_metadata) { - // Get ScoreCalibrationOptions, if any. - ASSIGN_OR_RETURN( - const ProcessUnit* score_calibration_process_unit, - metadata_extractor.FindFirstProcessUnit( - tensor_metadata, tflite::ProcessUnitOptions_ScoreCalibrationOptions)); - if (score_calibration_process_unit == nullptr) { - return std::nullopt; - } - auto* score_calibration_options = - score_calibration_process_unit->options_as_ScoreCalibrationOptions(); - // Get corresponding AssociatedFile. - auto score_calibration_filename = - metadata_extractor.FindFirstAssociatedFileName( - tensor_metadata, - tflite::AssociatedFileType_TENSOR_AXIS_SCORE_CALIBRATION); - if (score_calibration_filename.empty()) { - return CreateStatusWithPayload( - absl::StatusCode::kNotFound, - "Found ScoreCalibrationOptions but missing required associated " - "parameters file with type TENSOR_AXIS_SCORE_CALIBRATION.", - MediaPipeTasksStatus::kMetadataAssociatedFileNotFoundError); - } - ASSIGN_OR_RETURN( - absl::string_view score_calibration_file, - metadata_extractor.GetAssociatedFile(score_calibration_filename)); - ScoreCalibrationCalculatorOptions score_calibration_calculator_options; - MP_RETURN_IF_ERROR(ConfigureScoreCalibration( - score_calibration_options->score_transformation(), - score_calibration_options->default_score(), score_calibration_file, - &score_calibration_calculator_options)); - return score_calibration_calculator_options; -} - -std::vector GetOutputTensorIndices( - const flatbuffers::Vector>* - tensor_metadatas) { - std::vector output_indices = { - core::FindTensorIndexByMetadataName(tensor_metadatas, - kLocationTensorName), - core::FindTensorIndexByMetadataName(tensor_metadatas, - kCategoryTensorName), - core::FindTensorIndexByMetadataName(tensor_metadatas, kScoreTensorName), - core::FindTensorIndexByMetadataName(tensor_metadatas, - kNumberOfDetectionsTensorName)}; - // locations, categories, scores, and number of detections - for (int i = 0; i < 4; i++) { - int output_index = output_indices[i]; - // If tensor name is not found, set the default output indices. - if (output_index == -1) { - LOG(WARNING) << absl::StrFormat( - "You don't seem to be matching tensor names in metadata list. The " - "tensor name \"%s\" at index %d in the model metadata doesn't " - "match " - "the available output names: [\"%s\", \"%s\", \"%s\", \"%s\"].", - tensor_metadatas->Get(i)->name()->c_str(), i, kLocationTensorName, - kCategoryTensorName, kScoreTensorName, kNumberOfDetectionsTensorName); - output_indices = {kDefaultLocationsIndex, kDefaultCategoriesIndex, - kDefaultScoresIndex, kDefaultNumResultsIndex}; - return output_indices; - } - } - return output_indices; -} - -// Builds PostProcessingSpecs from ObjectDetectorOptionsProto and model metadata -// for configuring the post-processing calculators. -absl::StatusOr BuildPostProcessingSpecs( - const ObjectDetectorOptionsProto& options, - const ModelMetadataExtractor* metadata_extractor) { - // Checks output tensor metadata is present and consistent with model. - auto* output_tensors_metadata = metadata_extractor->GetOutputTensorMetadata(); - if (output_tensors_metadata == nullptr || - output_tensors_metadata->size() != 4) { - return CreateStatusWithPayload( - absl::StatusCode::kInvalidArgument, - absl::StrFormat("Mismatch between number of output tensors (4) and " - "output tensors metadata (%d).", - output_tensors_metadata == nullptr - ? 0 - : output_tensors_metadata->size()), - MediaPipeTasksStatus::kMetadataInconsistencyError); - } - PostProcessingSpecs specs; - specs.max_results = options.max_results(); - specs.output_tensor_indices = GetOutputTensorIndices(output_tensors_metadata); - // Extracts mandatory BoundingBoxProperties and performs sanity checks on the - // fly. - ASSIGN_OR_RETURN(const BoundingBoxProperties* bounding_box_properties, - GetBoundingBoxProperties(*output_tensors_metadata->Get( - specs.output_tensor_indices[0]))); - if (bounding_box_properties->index() == nullptr) { - specs.bounding_box_corners_order = {0, 1, 2, 3}; - } else { - auto bounding_box_index = bounding_box_properties->index(); - specs.bounding_box_corners_order = { - bounding_box_index->Get(0), - bounding_box_index->Get(1), - bounding_box_index->Get(2), - bounding_box_index->Get(3), - }; - } - // Builds label map (if available) from metadata. - ASSIGN_OR_RETURN(specs.label_items, - GetLabelItemsIfAny(*metadata_extractor, - *output_tensors_metadata->Get( - specs.output_tensor_indices[1]), - options.display_names_locale())); - // Obtains allow/deny categories. - specs.is_allowlist = !options.category_allowlist().empty(); - ASSIGN_OR_RETURN( - specs.allow_or_deny_categories, - GetAllowOrDenyCategoryIndicesIfAny(options, specs.label_items)); - // Sets score threshold. - if (options.has_score_threshold()) { - specs.score_threshold = options.score_threshold(); - } else { - ASSIGN_OR_RETURN(specs.score_threshold, - GetScoreThreshold(*metadata_extractor, - *output_tensors_metadata->Get( - specs.output_tensor_indices[2]))); - } - // Builds score calibration options (if available) from metadata. - ASSIGN_OR_RETURN( - specs.score_calibration_options, - GetScoreCalibrationOptionsIfAny( - *metadata_extractor, - *output_tensors_metadata->Get(specs.output_tensor_indices[2]))); - return specs; -} - -// Fills in the TensorsToDetectionsCalculatorOptions based on -// PostProcessingSpecs. -void ConfigureTensorsToDetectionsCalculator( - const PostProcessingSpecs& specs, - mediapipe::TensorsToDetectionsCalculatorOptions* options) { - options->set_num_classes(specs.label_items.size()); - options->set_num_coords(4); - options->set_min_score_thresh(specs.score_threshold); - if (specs.max_results != -1) { - options->set_max_results(specs.max_results); - } - if (specs.is_allowlist) { - options->mutable_allow_classes()->Assign( - specs.allow_or_deny_categories.begin(), - specs.allow_or_deny_categories.end()); - } else { - options->mutable_ignore_classes()->Assign( - specs.allow_or_deny_categories.begin(), - specs.allow_or_deny_categories.end()); - } - - const auto& output_indices = specs.output_tensor_indices; - // Assigns indices to each the model output tensor. - auto* tensor_mapping = options->mutable_tensor_mapping(); - tensor_mapping->set_detections_tensor_index(output_indices[0]); - tensor_mapping->set_classes_tensor_index(output_indices[1]); - tensor_mapping->set_scores_tensor_index(output_indices[2]); - tensor_mapping->set_num_detections_tensor_index(output_indices[3]); - - // Assigns the bounding box corner order. - auto box_boundaries_indices = options->mutable_box_boundaries_indices(); - box_boundaries_indices->set_xmin(specs.bounding_box_corners_order[0]); - box_boundaries_indices->set_ymin(specs.bounding_box_corners_order[1]); - box_boundaries_indices->set_xmax(specs.bounding_box_corners_order[2]); - box_boundaries_indices->set_ymax(specs.bounding_box_corners_order[3]); -} - } // namespace // A "mediapipe.tasks.vision.ObjectDetectorGraph" performs object detection. @@ -530,7 +164,6 @@ class ObjectDetectorGraph : public core::ModelTaskGraph { const core::ModelResources& model_resources, Source image_in, Source norm_rect_in, Graph& graph) { MP_RETURN_IF_ERROR(SanityCheckOptions(task_options)); - // Checks that the model has 4 outputs. auto& model = *model_resources.GetTfLiteModel(); if (model.subgraphs()->size() != 1) { return CreateStatusWithPayload( @@ -539,13 +172,6 @@ class ObjectDetectorGraph : public core::ModelTaskGraph { model.subgraphs()->size()), MediaPipeTasksStatus::kInvalidArgumentError); } - if (model.subgraphs()->Get(0)->outputs()->size() != 4) { - return CreateStatusWithPayload( - absl::StatusCode::kInvalidArgument, - absl::StrFormat("Expected a model with 4 output tensors, found %d.", - model.subgraphs()->Get(0)->outputs()->size()), - MediaPipeTasksStatus::kInvalidArgumentError); - } // Checks that metadata is available. auto* metadata_extractor = model_resources.GetMetadataExtractor(); if (metadata_extractor->GetModelMetadata() == nullptr || @@ -577,70 +203,36 @@ class ObjectDetectorGraph : public core::ModelTaskGraph { auto& inference = AddInference( model_resources, task_options.base_options().acceleration(), graph); preprocessing.Out(kTensorTag) >> inference.In(kTensorTag); - - // Adds post processing calculators. - ASSIGN_OR_RETURN( - auto post_processing_specs, - BuildPostProcessingSpecs(task_options, metadata_extractor)); - // Calculators to perform score calibration, if specified in the metadata. - TensorsSource calibrated_tensors = + TensorsSource model_output_tensors = inference.Out(kTensorTag).Cast>(); - if (post_processing_specs.score_calibration_options.has_value()) { - // Split tensors. - auto* split_tensor_vector_node = - &graph.AddNode("SplitTensorVectorCalculator"); - auto& split_tensor_vector_options = - split_tensor_vector_node - ->GetOptions(); - for (int i = 0; i < 4; ++i) { - auto* range = split_tensor_vector_options.add_ranges(); - range->set_begin(i); - range->set_end(i + 1); - } - calibrated_tensors >> split_tensor_vector_node->In(0); - // Add score calibration calculator. - auto* score_calibration_node = - &graph.AddNode("ScoreCalibrationCalculator"); - score_calibration_node->GetOptions() - .CopyFrom(*post_processing_specs.score_calibration_options); - split_tensor_vector_node->Out( - post_processing_specs.output_tensor_indices[1]) >> - score_calibration_node->In(kIndicesTag); - split_tensor_vector_node->Out( - post_processing_specs.output_tensor_indices[2]) >> - score_calibration_node->In(kScoresTag); - - // Re-concatenate tensors. - auto* concatenate_tensor_vector_node = - &graph.AddNode("ConcatenateTensorVectorCalculator"); - for (int i = 0; i < 4; ++i) { - if (i == post_processing_specs.output_tensor_indices[2]) { - score_calibration_node->Out(kCalibratedScoresTag) >> - concatenate_tensor_vector_node->In(i); - } else { - split_tensor_vector_node->Out(i) >> - concatenate_tensor_vector_node->In(i); - } - } - calibrated_tensors = - concatenate_tensor_vector_node->Out(0).Cast>(); - } - // Calculator to convert output tensors to a detection proto vector. - // Connects TensorsToDetectionsCalculator's input stream to the output - // tensors produced by the inference subgraph. - auto& tensors_to_detections = - graph.AddNode("TensorsToDetectionsCalculator"); - ConfigureTensorsToDetectionsCalculator( - post_processing_specs, - &tensors_to_detections - .GetOptions()); - calibrated_tensors >> tensors_to_detections.In(kTensorTag); + // Add Detection postprocessing graph to convert tensors to detections. + auto& postprocessing = graph.AddNode( + "mediapipe.tasks.components.processors.DetectionPostprocessingGraph"); + components::processors::proto::DetectorOptions detector_options; + detector_options.set_max_results(task_options.max_results()); + detector_options.set_score_threshold(task_options.score_threshold()); + detector_options.set_display_names_locale( + task_options.display_names_locale()); + detector_options.mutable_category_allowlist()->CopyFrom( + task_options.category_allowlist()); + detector_options.mutable_category_denylist()->CopyFrom( + task_options.category_denylist()); + // TODO: expose min suppression threshold in + // ObjectDetectorOptions. + detector_options.set_min_suppression_threshold(0.3); + MP_RETURN_IF_ERROR( + components::processors::ConfigureDetectionPostprocessingGraph( + model_resources, detector_options, + postprocessing + .GetOptions())); + model_output_tensors >> postprocessing.In(kTensorTag); + auto detections = postprocessing.Out(kDetectionsTag); // Calculator to projects detections back to the original coordinate system. auto& detection_projection = graph.AddNode("DetectionProjectionCalculator"); - tensors_to_detections.Out(kDetectionsTag) >> - detection_projection.In(kDetectionsTag); + detections >> detection_projection.In(kDetectionsTag); preprocessing.Out(kMatrixTag) >> detection_projection.In(kProjectionMatrixTag); @@ -652,22 +244,13 @@ class ObjectDetectorGraph : public core::ModelTaskGraph { detection_transformation.In(kDetectionsTag); preprocessing.Out(kImageSizeTag) >> detection_transformation.In(kImageSizeTag); - - // Calculator to assign detection labels. - auto& detection_label_id_to_text = - graph.AddNode("DetectionLabelIdToTextCalculator"); - auto& detection_label_id_to_text_opts = - detection_label_id_to_text - .GetOptions(); - *detection_label_id_to_text_opts.mutable_label_items() = - std::move(post_processing_specs.label_items); - detection_transformation.Out(kPixelDetectionsTag) >> - detection_label_id_to_text.In(""); + auto detections_in_pixel = + detection_transformation.Out(kPixelDetectionsTag); // Deduplicate Detections with same bounding box coordinates. auto& detections_deduplicate = graph.AddNode("DetectionsDeduplicateCalculator"); - detection_label_id_to_text.Out("") >> detections_deduplicate.In(""); + detections_in_pixel >> detections_deduplicate.In(""); // Outputs the labeled detections and the processed image as the subgraph // output streams. diff --git a/mediapipe/tasks/cc/vision/object_detector/object_detector_test.cc b/mediapipe/tasks/cc/vision/object_detector/object_detector_test.cc index a4fed0f9e..8642af7c4 100644 --- a/mediapipe/tasks/cc/vision/object_detector/object_detector_test.cc +++ b/mediapipe/tasks/cc/vision/object_detector/object_detector_test.cc @@ -76,15 +76,18 @@ using ::testing::HasSubstr; using ::testing::Optional; using DetectionProto = mediapipe::Detection; -constexpr char kTestDataDirectory[] = "/mediapipe/tasks/testdata/vision/"; -constexpr char kMobileSsdWithMetadata[] = - "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.tflite"; -constexpr char kMobileSsdWithDummyScoreCalibration[] = +constexpr absl::string_view kTestDataDirectory{ + "/mediapipe/tasks/testdata/vision/"}; +constexpr absl::string_view kMobileSsdWithMetadata{ + "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.tflite"}; +constexpr absl::string_view kMobileSsdWithDummyScoreCalibration{ "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29_with_dummy_score_calibration." - "tflite"; + "tflite"}; // The model has different output tensor order. -constexpr char kEfficientDetWithMetadata[] = - "coco_efficientdet_lite0_v1_1.0_quant_2021_09_06.tflite"; +constexpr absl::string_view kEfficientDetWithMetadata{ + "coco_efficientdet_lite0_v1_1.0_quant_2021_09_06.tflite"}; +constexpr absl::string_view kEfficientDetWithoutNms{ + "efficientdet_lite0_fp16_no_nms.tflite"}; // Checks that the two provided `Detection` proto vectors are equal, with a // tolerancy on floating-point scores to account for numerical instabilities. @@ -451,6 +454,51 @@ TEST_F(ImageModeTest, SucceedsEfficientDetModel) { })pb")})); } +TEST_F(ImageModeTest, SucceedsEfficientDetNoNmsModel) { + MP_ASSERT_OK_AND_ASSIGN(Image image, + DecodeImageFromFile(JoinPath("./", kTestDataDirectory, + "cats_and_dogs.jpg"))); + auto options = std::make_unique(); + options->max_results = 4; + options->base_options.model_asset_path = + JoinPath("./", kTestDataDirectory, kEfficientDetWithoutNms); + MP_ASSERT_OK_AND_ASSIGN(std::unique_ptr object_detector, + ObjectDetector::Create(std::move(options))); + MP_ASSERT_OK_AND_ASSIGN(auto results, object_detector->Detect(image)); + MP_ASSERT_OK(object_detector->Close()); + ExpectApproximatelyEqual( + results, + ConvertToDetectionResult( + {ParseTextProtoOrDie(R"pb( + label: "dog" + score: 0.733542 + location_data { + format: BOUNDING_BOX + bounding_box { xmin: 636 ymin: 160 width: 282 height: 451 } + })pb"), + ParseTextProtoOrDie(R"pb( + label: "cat" + score: 0.699751 + location_data { + format: BOUNDING_BOX + bounding_box { xmin: 870 ymin: 411 width: 208 height: 187 } + })pb"), + ParseTextProtoOrDie(R"pb( + label: "dog" + score: 0.682425 + location_data { + format: BOUNDING_BOX + bounding_box { xmin: 386 ymin: 216 width: 256 height: 376 } + })pb"), + ParseTextProtoOrDie(R"pb( + label: "cat" + score: 0.646585 + location_data { + format: BOUNDING_BOX + bounding_box { xmin: 83 ymin: 399 width: 347 height: 198 } + })pb")})); +} + TEST_F(ImageModeTest, SucceedsWithoutImageResizing) { MP_ASSERT_OK_AND_ASSIGN(Image image, DecodeImageFromFile(JoinPath( "./", kTestDataDirectory, diff --git a/mediapipe/tasks/testdata/vision/BUILD b/mediapipe/tasks/testdata/vision/BUILD index 649d8d452..a8704123c 100644 --- a/mediapipe/tasks/testdata/vision/BUILD +++ b/mediapipe/tasks/testdata/vision/BUILD @@ -41,6 +41,7 @@ mediapipe_files(srcs = [ "conv2d_input_channel_1.tflite", "deeplabv3.tflite", "dense.tflite", + "efficientdet_lite0_fp16_no_nms.tflite", "face_detection_full_range.tflite", "face_detection_full_range_sparse.tflite", "face_detection_short_range.tflite", @@ -167,6 +168,7 @@ filegroup( "conv2d_input_channel_1.tflite", "deeplabv3.tflite", "dense.tflite", + "efficientdet_lite0_fp16_no_nms.tflite", "face_detection_full_range.tflite", "face_detection_full_range_sparse.tflite", "face_detection_short_range.tflite", diff --git a/third_party/external_files.bzl b/third_party/external_files.bzl index c47f0fbb6..6a1582cc7 100644 --- a/third_party/external_files.bzl +++ b/third_party/external_files.bzl @@ -276,8 +276,8 @@ def external_files(): http_file( name = "com_google_mediapipe_efficientdet_lite0_fp16_no_nms_tflite", - sha256 = "bcda125c96d3767bca894c8cbe7bc458379c9974c9fd8bdc6204e7124a74082a", - urls = ["https://storage.googleapis.com/mediapipe-assets/efficientdet_lite0_fp16_no_nms.tflite?generation=1682456096034465"], + sha256 = "237a58389081333e5cf4154e42b593ce7dd357445536fcaf4ca5bc51c2c50f1c", + urls = ["https://storage.googleapis.com/mediapipe-assets/efficientdet_lite0_fp16_no_nms.tflite?generation=1682476299542472"], ) http_file( From 9c98435027bd88c041f88f6aba1e61d7b31ef4d5 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 27 Apr 2023 02:15:16 +0530 Subject: [PATCH 104/753] Updated iOS framework names --- mediapipe/tasks/ios/BUILD | 22 +++++++++---------- .../ios/MediaPipeTaskCommon.podspec.template | 10 ++++----- .../ios/MediaPipeTaskText.podspec.template | 8 +++---- .../ios/MediaPipeTaskVision.podspec.template | 8 +++---- mediapipe/tasks/ios/build_ios_framework.sh | 20 ++++++++++------- 5 files changed, 36 insertions(+), 32 deletions(-) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index 25b7ab9ce..a1292373c 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -27,13 +27,13 @@ package(default_visibility = ["//visibility:public"]) licenses(["notice"]) -# list of targets to be added in avoid_deps of ":MediaPipeTaskVision_framework" -# and ":MediaPipeTaskText_framework". +# list of targets to be added in avoid_deps of ":MediaPipeTasksVision_framework" +# and ":MediaPipeTasksText_framework". # The transitive closure of the following targets are used for building the # frameworks but are avoided from the framework binaries to avoid duplicate symbols # error when included in an xcode project: # 1. iOS classes shared amongst the various vision and text tasks. These classes -# will be built with ":MediaPipeTaskCommon_framework" +# will be built with ":MediaPipeTasksCommon_framework" # 2. Task graphs. These will be built with ":MediaPipeTaskGraphs_library". # 3. gpu targets which will be built with the ":MediaPipeTaskGraphs_library". OBJC_COMMON_DEPS = [ @@ -73,7 +73,7 @@ strip_api_include_path_prefix( ) apple_static_xcframework( - name = "MediaPipeTaskText_framework", + name = "MediaPipeTasksText_framework", public_hdrs = [ ":MPPBaseOptions.h", ":MPPCategory.h", @@ -90,7 +90,7 @@ apple_static_xcframework( ":MPPTextEmbedderOptions.h", ":MPPTextEmbedderResult.h", ], - bundle_name = "MediaPipeTaskText", + bundle_name = "MediaPipeTasksText", ios = { "simulator" : ["arm64", "x86_64"], "device" : ["arm64"], @@ -102,14 +102,14 @@ apple_static_xcframework( "//mediapipe/tasks/ios/text/text_classifier:MPPTextClassifier", "//mediapipe/tasks/ios/text/text_embedder:MPPTextEmbedder", ], - # avoid dependencies of ":MediaPipeCommon_framework" and + # avoid dependencies of ":MediaPipeTasksCommon_framework" and # ":MediaPipeTaskGraphs_library in order to prevent duplicate symbols error # when the frameworks are imported in iOS projects. avoid_deps = OBJC_COMMON_DEPS ) apple_static_xcframework( - name = "MediaPipeTaskVision_framework", + name = "MediaPipeTasksVision_framework", public_hdrs = [ ":MPPBaseOptions.h", ":MPPCategory.h", @@ -127,7 +127,7 @@ apple_static_xcframework( ":MPPObjectDetectorOptions.h", ":MPPObjectDetectionResult.h", ], - bundle_name = "MediaPipeTaskVision", + bundle_name = "MediaPipeTasksVision", ios = { "simulator" : ["arm64", "x86_64"], "device" : ["arm64"], @@ -139,7 +139,7 @@ apple_static_xcframework( "//mediapipe/tasks/ios/vision/image_classifier:MPPImageClassifier", "//mediapipe/tasks/ios/vision/object_detector:MPPObjectDetector", ], - # Avoids dependencies of ":MediaPipeCommon_framework" and + # Avoids dependencies of ":MediaPipeTasksCommon_framework" and # ":MediaPipeTaskGraphs_library in order to prevent duplicate symbols error # when the frameworks are imported in iOS projects. # Also avoids opencv since it will be built with @@ -171,8 +171,8 @@ apple_static_library( ) apple_static_xcframework( - name = "MediaPipeTaskCommon_framework", - bundle_name = "MediaPipeTaskCommon", + name = "MediaPipeTasksCommon_framework", + bundle_name = "MediaPipeTasksCommon", ios = { "simulator" : ["arm64", "x86_64"], "device" : ["arm64"], diff --git a/mediapipe/tasks/ios/MediaPipeTaskCommon.podspec.template b/mediapipe/tasks/ios/MediaPipeTaskCommon.podspec.template index 52dc73b3a..de9a3fa26 100644 --- a/mediapipe/tasks/ios/MediaPipeTaskCommon.podspec.template +++ b/mediapipe/tasks/ios/MediaPipeTaskCommon.podspec.template @@ -1,5 +1,5 @@ Pod::Spec.new do |s| - s.name = 'MediaPipeTaskCommon' + s.name = 'MediaPipeTasksCommon' s.version = '${MPP_BUILD_VERSION}' s.authors = 'Google Inc.' s.license = { :type => 'Apache',:file => "LICENSE" } @@ -10,14 +10,14 @@ Pod::Spec.new do |s| s.ios.deployment_target = '11.0' - s.module_name = 'MediaPipeTaskCommon' + s.module_name = 'MediaPipeTasksCommon' s.static_framework = true s.user_target_xcconfig = { - 'OTHER_LDFLAGS[sdk=iphonesimulator*]' => '$(inherited) -force_load "${PODS_ROOT}/MediaPipeTaskCommon/frameworks/graph_libraries/libMediaPipeTaskCommon_simulator_graph.a"', - 'OTHER_LDFLAGS[sdk=iphoneos*]' => '$(inherited) -force_load "$(PODS_ROOT)/MediaPipeTaskCommon/frameworks/graph_libraries/libMediaPipeTaskCommon_device_graph.a"', + 'OTHER_LDFLAGS[sdk=iphonesimulator*]' => '$(inherited) -force_load "${PODS_ROOT}/MediaPipeTasksCommon/frameworks/graph_libraries/libMediaPipeTasksCommon_simulator_graph.a"', + 'OTHER_LDFLAGS[sdk=iphoneos*]' => '$(inherited) -force_load "$(PODS_ROOT)/MediaPipeTasksCommon/frameworks/graph_libraries/libMediaPipeTasksCommon_device_graph.a"', } s.frameworks = 'Accelerate', 'CoreMedia', 'AssetsLibrary', 'CoreFoundation', 'CoreGraphics', 'CoreImage', 'QuartzCore', 'AVFoundation', 'CoreVideo' s.preserve_paths ='frameworks/graph_libraries/*.a' s.library = 'c++' - s.vendored_frameworks = 'frameworks/MediaPipeTaskCommon.xcframework' + s.vendored_frameworks = 'frameworks/MediaPipeTasksCommon.xcframework' end diff --git a/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template b/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template index e84779ae8..144d36f88 100644 --- a/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template +++ b/mediapipe/tasks/ios/MediaPipeTaskText.podspec.template @@ -1,5 +1,5 @@ Pod::Spec.new do |s| - s.name = 'MediaPipeTaskText' + s.name = 'MediaPipeTasksText' s.version = '${MPP_BUILD_VERSION}' s.authors = 'Google Inc.' s.license = { :type => 'Apache',:file => "LICENSE" } @@ -10,9 +10,9 @@ Pod::Spec.new do |s| s.ios.deployment_target = '11.0' - s.module_name = 'MediaPipeTaskText' + s.module_name = 'MediaPipeTasksText' s.static_framework = true - s.dependency 'MediaPipeTaskCommonObjects' + s.dependency 'MediaPipeTasksCommon' s.library = 'c++' - s.vendored_frameworks = 'frameworks/MediaPipeTaskText.xcframework' + s.vendored_frameworks = 'frameworks/MediaPipeTasksText.xcframework' end diff --git a/mediapipe/tasks/ios/MediaPipeTaskVision.podspec.template b/mediapipe/tasks/ios/MediaPipeTaskVision.podspec.template index 0d530e4cf..373c1768b 100644 --- a/mediapipe/tasks/ios/MediaPipeTaskVision.podspec.template +++ b/mediapipe/tasks/ios/MediaPipeTaskVision.podspec.template @@ -1,5 +1,5 @@ Pod::Spec.new do |s| - s.name = 'MediaPipeTaskVision' + s.name = 'MediaPipeTasksVision' s.version = '${MPP_BUILD_VERSION}' s.authors = 'Google Inc.' s.license = { :type => 'Apache',:file => "LICENSE" } @@ -10,9 +10,9 @@ Pod::Spec.new do |s| s.ios.deployment_target = '11.0' - s.module_name = 'MediaPipeTaskVision' + s.module_name = 'MediaPipeTasksVision' s.static_framework = true - s.dependency 'MediaPipeTaskCommonObjects' + s.dependency 'MediaPipeTasksCommon' s.library = 'c++' - s.vendored_frameworks = 'frameworks/MediaPipeTaskVision.xcframework' + s.vendored_frameworks = 'frameworks/MediaPipeTasksVision.xcframework' end diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index 7ebbedca0..744c49852 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -16,7 +16,7 @@ # Set the following variables as appropriate. # * BAZEL: path to bazel. defaults to the first one available in PATH # * FRAMEWORK_NAME: name of the iOS framework to be built. Currently the -# * accepted values are MediaPipeTaskCommon, MediaPipeTaskText, MediaPipeTaskVision. +# * accepted values are MediaPipeTasksCommon, MediaPipeTasksText, MediaPipeTasksVision. # * MPP_BUILD_VERSION: to specify the release version. defaults to 0.0.1-dev # * IS_RELEASE_BUILD: set as true if this build should be a release build # * ARCHIVE_FRAMEWORK: set as true if the framework should be archived @@ -47,10 +47,14 @@ if [ -z ${FRAMEWORK_NAME+x} ]; then fi case $FRAMEWORK_NAME in - "MediaPipeTaskText") + "MediaPipeTasksText") + ;; + "MediaPipeTasksVision") + ;; + "MediaPipeTasksCommon") ;; *) - echo "Wrong framework name. The following framework names are allowed: MediaPipeTaskText" + echo "Wrong framework name. The following framework names are allowed: MediaPipeTasksText, MediaPipeTasksVision, MediaPipeTasksCommon" exit 1 ;; esac @@ -106,11 +110,11 @@ function build_ios_frameworks_and_libraries { local FRAMEWORK_CQUERY_COMMAND="-c opt --apple_generate_dsym=false ${FULL_FRAMEWORK_TARGET}" IOS_FRAMEWORK_PATH="$(build_target "${FRAMEWORK_CQUERY_COMMAND}")" - # `MediaPipeTaskCommon`` pods must also include the task graph libraries which + # `MediaPipeTasksCommon`` pods must also include the task graph libraries which # are to be force loaded. Hence the graph libraies are only built if the framework - # name is `MediaPipeTaskCommon`.` + # name is `MediaPipeTasksCommon`.` case $FRAMEWORK_NAME in - "MediaPipeTaskCommon") + "MediaPipeTasksCommon") local IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_sim_fat --apple_generate_dsym=false //mediapipe/tasks/ios:MediaPipeTaskGraphs_library" IOS_GRAPHS_SIMULATOR_LIBRARY_PATH="$(build_target "${IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND}")" @@ -141,10 +145,10 @@ function create_framework_archive { echo ${IOS_FRAMEWORK_PATH} unzip "${IOS_FRAMEWORK_PATH}" -d "${FRAMEWORKS_DIR}" - # If the framwork being built is `MediaPipeTaskCommon`, the built graph + # If the framwork being built is `MediaPipeTasksCommon`, the built graph # libraries should be copied to the output directory which is to be archived. case $FRAMEWORK_NAME in - "MediaPipeTaskCommon") + "MediaPipeTasksCommon") local GRAPH_LIBRARIES_DIR="graph_libraries" From 1e776e8e015db0de99a071ff301cd5e8c1b90230 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 27 Apr 2023 02:31:30 +0530 Subject: [PATCH 105/753] Fixed indendation issues --- mediapipe/tasks/ios/BUILD | 1 - mediapipe/tasks/ios/build_ios_framework.sh | 35 +++++++++++----------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index a1292373c..e40b5339b 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -153,7 +153,6 @@ apple_static_library( name = "MediaPipeTaskGraphs_library", minimum_os_version = MPP_TASK_MINIMUM_OS_VERSION, platform_type = "ios", - minimum_os_version = MPP_TASK_MINIMUM_OS_VERSION, deps = [ "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index 744c49852..6351a4d4d 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -47,7 +47,7 @@ if [ -z ${FRAMEWORK_NAME+x} ]; then fi case $FRAMEWORK_NAME in - "MediaPipeTasksText") + "MediaPipeTasksCommon") ;; "MediaPipeTasksVision") ;; @@ -123,8 +123,8 @@ function build_ios_frameworks_and_libraries { local IOS_DEVICE_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_arm64 --apple_generate_dsym=false //mediapipe/tasks/ios:MediaPipeTaskGraphs_library" IOS_GRAPHS_DEVICE_LIBRARY_PATH="$(build_target "${IOS_DEVICE_LIBRARY_CQUERY_COMMAND}")" ;; - *) - ;; + *) + ;; esac } @@ -149,26 +149,25 @@ function create_framework_archive { # libraries should be copied to the output directory which is to be archived. case $FRAMEWORK_NAME in "MediaPipeTasksCommon") - local GRAPH_LIBRARIES_DIR="graph_libraries" - - local GRAPH_LIBRARIES_DIR="graph_libraries" - - # Create the parent folder which will hold the graph libraries of all architectures. - mkdir -p "${FRAMEWORKS_DIR}/${GRAPH_LIBRARIES_DIR}" + # Create the parent folder which will hold the graph libraries of all architectures. + mkdir -p "${FRAMEWORKS_DIR}/${GRAPH_LIBRARIES_DIR}" - local SIMULATOR_GRAPH_LIBRARY_PATH="${FRAMEWORKS_DIR}/${GRAPH_LIBRARIES_DIR}/lib${FRAMEWORK_NAME}_simulator_graph.a" + local SIMULATOR_GRAPH_LIBRARY_PATH="${FRAMEWORKS_DIR}/${GRAPH_LIBRARIES_DIR}/lib${FRAMEWORK_NAME}_simulator_graph.a" - # Copy ios simulator fat library into a separate directory. - echo ${IOS_GRAPHS_SIMULATOR_LIBRARY_PATH} - cp "${IOS_GRAPHS_SIMULATOR_LIBRARY_PATH}" "${SIMULATOR_GRAPH_LIBRARY_PATH}" - + # Copy ios simulator fat library into a separate directory. + echo ${IOS_GRAPHS_SIMULATOR_LIBRARY_PATH} + cp "${IOS_GRAPHS_SIMULATOR_LIBRARY_PATH}" "${SIMULATOR_GRAPH_LIBRARY_PATH}" - local IOS_DEVICE_GRAPH_LIBRARY_PATH="${FRAMEWORKS_DIR}/${GRAPH_LIBRARIES_DIR}/lib${FRAMEWORK_NAME}_device_graph.a" + local IOS_DEVICE_GRAPH_LIBRARY_PATH="${FRAMEWORKS_DIR}/${GRAPH_LIBRARIES_DIR}/lib${FRAMEWORK_NAME}_device_graph.a" - # Copy ios device library into a separate directory. - echo ${IOS_GRAPHS_DEVICE_LIBRARY_PATH} - cp "${IOS_GRAPHS_DEVICE_LIBRARY_PATH}" "${IOS_DEVICE_GRAPH_LIBRARY_PATH}" + # Copy ios device library into a separate directory. + echo ${IOS_GRAPHS_DEVICE_LIBRARY_PATH} + cp "${IOS_GRAPHS_DEVICE_LIBRARY_PATH}" "${IOS_DEVICE_GRAPH_LIBRARY_PATH}" + ;; + *) + ;; + esac #----- (3) Move the framework to the destination ----- if [[ "${ARCHIVE_FRAMEWORK}" == true ]]; then From a8cb1f1dad62144481e25759bcc63fabb7365b4a Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 27 Apr 2023 02:47:19 +0530 Subject: [PATCH 106/753] Updated default values --- mediapipe/tasks/ios/build_ios_framework.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index 6351a4d4d..f75e0db7a 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -32,9 +32,12 @@ fi BAZEL="${BAZEL:-$(which bazel)}" MPP_BUILD_VERSION=${MPP_BUILD_VERSION:-0.0.1-dev} MPP_ROOT_DIR=$(git rev-parse --show-toplevel) -ARCHIVE_FRAMEWORK=true -IS_RELEASE_BUILD=false -DEST_DIR=$HOME +ARCHIVE_FRAMEWORK=${ARCHIVE_FRAMEWORK:-true} +IS_RELEASE_BUILD=${IS_RELEASE_BUILD:-false} +DEST_DIR=${DEST_DIR:-$HOME} + +echo "Destination" +echo "${DEST_DIR}" if [[ ! -x "${BAZEL}" ]]; then echo "bazel executable is not found." From 1d8e24b9aa79864016b2004c4d81134637029c9e Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 27 Apr 2023 02:47:52 +0530 Subject: [PATCH 107/753] Updated documentation --- mediapipe/tasks/ios/build_ios_framework.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index f75e0db7a..3df9f1eac 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -113,7 +113,7 @@ function build_ios_frameworks_and_libraries { local FRAMEWORK_CQUERY_COMMAND="-c opt --apple_generate_dsym=false ${FULL_FRAMEWORK_TARGET}" IOS_FRAMEWORK_PATH="$(build_target "${FRAMEWORK_CQUERY_COMMAND}")" - # `MediaPipeTasksCommon`` pods must also include the task graph libraries which + # `MediaPipeTasksCommon` pods must also include the task graph libraries which # are to be force loaded. Hence the graph libraies are only built if the framework # name is `MediaPipeTasksCommon`.` case $FRAMEWORK_NAME in From ee2665ad13512c118b4475a4d42263116a1c36db Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 27 Apr 2023 02:54:50 +0530 Subject: [PATCH 108/753] Added missing input files in vision library --- mediapipe/tasks/ios/BUILD | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index e40b5339b..f06344c88 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -60,6 +60,7 @@ strip_api_include_path_prefix( "//mediapipe/tasks/ios/components/containers:sources/MPPClassificationResult.h", "//mediapipe/tasks/ios/components/containers:sources/MPPEmbedding.h", "//mediapipe/tasks/ios/components/containers:sources/MPPEmbeddingResult.h", + "//mediapipe/tasks/ios/components/containers:sources/MPPDetection.h", "//mediapipe/tasks/ios/core:sources/MPPBaseOptions.h", "//mediapipe/tasks/ios/core:sources/MPPTaskOptions.h", "//mediapipe/tasks/ios/core:sources/MPPTaskResult.h", @@ -69,6 +70,14 @@ strip_api_include_path_prefix( "//mediapipe/tasks/ios/text/text_embedder:sources/MPPTextEmbedder.h", "//mediapipe/tasks/ios/text/text_embedder:sources/MPPTextEmbedderOptions.h", "//mediapipe/tasks/ios/text/text_embedder:sources/MPPTextEmbedderResult.h", + "//mediapipe/tasks/ios/vision/core:sources/MPPRunningMode.h", + "//mediapipe/tasks/ios/vision/core:sources/MPPImage.h", + "//mediapipe/tasks/ios/vision/image_classifier:sources/MPPImageClassifier.h", + "//mediapipe/tasks/ios/vision/image_classifier:sources/MPPImageClassifierOptions.h", + "//mediapipe/tasks/ios/vision/image_classifier:sources/MPPImageClassifierResult.h", + "//mediapipe/tasks/ios/vision/object_detector:sources/MPPObjectDetector.h", + "//mediapipe/tasks/ios/vision/object_detector:sources/MPPObjectDetectorOptions.h", + "//mediapipe/tasks/ios/vision/object_detector:sources/MPPObjectDetectionResult.h", ], ) From 261e02e491929e4ebc153336075aad1de60c28fb Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 27 Apr 2023 02:55:58 +0530 Subject: [PATCH 109/753] Fixed case name --- mediapipe/tasks/ios/build_ios_framework.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index 3df9f1eac..8cc1747da 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -54,7 +54,7 @@ case $FRAMEWORK_NAME in ;; "MediaPipeTasksVision") ;; - "MediaPipeTasksCommon") + "MediaPipeTasksText") ;; *) echo "Wrong framework name. The following framework names are allowed: MediaPipeTasksText, MediaPipeTasksVision, MediaPipeTasksCommon" From a45d1f5e90a6a02381e5d2bfd9c53fb000c76dba Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 26 Apr 2023 14:25:35 -0700 Subject: [PATCH 110/753] Internal change. PiperOrigin-RevId: 527374728 --- .../pose_landmarker_graph_test.cc | 72 +++++++++++++++++++ mediapipe/tasks/testdata/vision/BUILD | 2 + third_party/external_files.bzl | 6 ++ 3 files changed, 80 insertions(+) diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph_test.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph_test.cc index 92bc80c5a..6f7488a5f 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph_test.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph_test.cc @@ -14,6 +14,7 @@ limitations under the License. ==============================================================================*/ #include +#include #include "absl/flags/flag.h" #include "absl/status/statusor.h" @@ -24,12 +25,15 @@ limitations under the License. #include "mediapipe/framework/calculator_framework.h" #include "mediapipe/framework/deps/file_path.h" #include "mediapipe/framework/formats/image.h" +#include "mediapipe/framework/formats/image_format.pb.h" +#include "mediapipe/framework/formats/image_frame.h" #include "mediapipe/framework/formats/landmark.pb.h" #include "mediapipe/framework/formats/rect.pb.h" #include "mediapipe/framework/packet.h" #include "mediapipe/framework/port/file_helpers.h" #include "mediapipe/framework/port/gmock.h" #include "mediapipe/framework/port/gtest.h" +#include "mediapipe/framework/tool/test_util.h" #include "mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.h" #include "mediapipe/tasks/cc/core/proto/base_options.pb.h" #include "mediapipe/tasks/cc/core/proto/external_file.pb.h" @@ -76,8 +80,11 @@ constexpr char kNormRectTag[] = "NORM_RECT"; constexpr char kNormRectName[] = "norm_rect"; constexpr char kNormLandmarksTag[] = "NORM_LANDMARKS"; constexpr char kNormLandmarksName[] = "norm_landmarks"; +constexpr char kSegmentationMaskTag[] = "SEGMENTATION_MASK"; +constexpr char kSegmentationMaskName[] = "segmentation_mask"; constexpr float kLiteModelFractionDiff = 0.05; // percentage +constexpr float kGoldenMaskSimilarity = 1.0; template ProtoT GetExpectedProto(absl::string_view filename) { @@ -125,6 +132,9 @@ absl::StatusOr> CreatePoseLandmarkerGraphTaskRunner( pose_landmarker.Out(kNormLandmarksTag).SetName(kNormLandmarksName) >> graph[Output>(kNormLandmarksTag)]; + pose_landmarker.Out(kSegmentationMaskTag).SetName(kSegmentationMaskName) >> + graph[Output>(kSegmentationMaskTag)]; + return TaskRunner::Create( graph.GetConfig(), absl::make_unique()); @@ -145,6 +155,21 @@ NormalizedRect MakeNormRect(float x_center, float y_center, float width, class PoseLandmarkerGraphTest : public testing::TestWithParam {}; +// Convert pixels from float range [0,1] to uint8 range [0,255]. +ImageFrame CreateUint8ImageFrame(const Image& image) { + auto* image_frame_ptr = image.GetImageFrameSharedPtr().get(); + ImageFrame output_image_frame(ImageFormat::GRAY8, image_frame_ptr->Width(), + image_frame_ptr->Height(), 1); + float* pixelData = + reinterpret_cast(image_frame_ptr->MutablePixelData()); + uint8_t* uint8PixelData = output_image_frame.MutablePixelData(); + const int total_pixels = image_frame_ptr->Width() * image_frame_ptr->Height(); + for (int i = 0; i < total_pixels; ++i) { + uint8PixelData[i] = static_cast(pixelData[i] * 255.0f); + } + return output_image_frame; +} + TEST_P(PoseLandmarkerGraphTest, Succeeds) { MP_ASSERT_OK_AND_ASSIGN( Image image, DecodeImageFromFile(JoinPath("./", kTestDataDirectory, @@ -167,6 +192,53 @@ TEST_P(PoseLandmarkerGraphTest, Succeeds) { GetParam().landmarks_diff_threshold), *GetParam().expected_landmarks_list)); } + + const std::vector& segmentation_masks = + (*output_packets)[kSegmentationMaskName].Get>(); + + EXPECT_EQ(segmentation_masks.size(), 1); + + const Image& segmentation_mask = segmentation_masks[0]; + const ImageFrame segmentation_mask_image_frame = + CreateUint8ImageFrame(segmentation_mask); + + auto expected_image_frame = LoadTestPng( + JoinPath("./", kTestDataDirectory, "pose_segmentation_mask_golden.png"), + ImageFormat::GRAY8); + + ASSERT_EQ(segmentation_mask_image_frame.Width(), + expected_image_frame->Width()); + ASSERT_EQ(segmentation_mask_image_frame.Height(), + expected_image_frame->Height()); + ASSERT_EQ(segmentation_mask_image_frame.Format(), + expected_image_frame->Format()); + ASSERT_EQ(segmentation_mask_image_frame.NumberOfChannels(), + expected_image_frame->NumberOfChannels()); + ASSERT_EQ(segmentation_mask_image_frame.ByteDepth(), + expected_image_frame->ByteDepth()); + ASSERT_EQ(segmentation_mask_image_frame.NumberOfChannels(), 1); + ASSERT_EQ(segmentation_mask_image_frame.ByteDepth(), 1); + int consistent_pixels = 0; + int num_pixels = segmentation_mask_image_frame.Width() * + segmentation_mask_image_frame.Height(); + for (int i = 0; i < segmentation_mask_image_frame.Height(); ++i) { + for (int j = 0; j < segmentation_mask_image_frame.Width(); ++j) { + consistent_pixels += + (segmentation_mask_image_frame + .PixelData()[segmentation_mask_image_frame.WidthStep() * i + + j] == + expected_image_frame + ->PixelData()[expected_image_frame->WidthStep() * i + j]); + } + } + + EXPECT_GE(static_cast(consistent_pixels) / num_pixels, + kGoldenMaskSimilarity); + + // For visual comparison of segmentation mask output. + MP_ASSERT_OK_AND_ASSIGN(auto output_path, + SavePngTestOutput(segmentation_mask_image_frame, + "segmentation_mask_output")); } INSTANTIATE_TEST_SUITE_P( diff --git a/mediapipe/tasks/testdata/vision/BUILD b/mediapipe/tasks/testdata/vision/BUILD index a8704123c..632e8aa4e 100644 --- a/mediapipe/tasks/testdata/vision/BUILD +++ b/mediapipe/tasks/testdata/vision/BUILD @@ -80,6 +80,7 @@ mediapipe_files(srcs = [ "pose_detection.tflite", "pose_landmark_lite.tflite", "pose_landmarker.task", + "pose_segmentation_mask_golden.png", "right_hands.jpg", "right_hands_rotated.jpg", "segmentation_golden_rotation0.png", @@ -143,6 +144,7 @@ filegroup( "portrait_selfie_segmentation_expected_confidence_mask.jpg", "portrait_selfie_segmentation_landscape_expected_category_mask.jpg", "pose.jpg", + "pose_segmentation_mask_golden.png", "right_hands.jpg", "right_hands_rotated.jpg", "segmentation_golden_rotation0.png", diff --git a/third_party/external_files.bzl b/third_party/external_files.bzl index 6a1582cc7..e8ff7819c 100644 --- a/third_party/external_files.bzl +++ b/third_party/external_files.bzl @@ -1018,6 +1018,12 @@ def external_files(): urls = ["https://storage.googleapis.com/mediapipe-assets/pose_landmarks.pbtxt?generation=1681425322701589"], ) + http_file( + name = "com_google_mediapipe_pose_segmentation_mask_golden_png", + sha256 = "62ee418e18f317327572da5fcc988af703eb31e6f0b9e0bf3d55e6f4797d6953", + urls = ["https://storage.googleapis.com/mediapipe-assets/pose_segmentation_mask_golden.png?generation=1682541414235372"], + ) + http_file( name = "com_google_mediapipe_ptm_512_hdt_ptm_woid_tflite", sha256 = "2baa1c9783d03dd26f91e3c49efbcab11dd1361ff80e40e7209e81f84f281b6a", From baed44ab10a35fafe5ab0bd60571005e2e31e278 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 26 Apr 2023 17:10:17 -0700 Subject: [PATCH 111/753] Internal change PiperOrigin-RevId: 527416263 --- mediapipe/calculators/util/logic_calculator.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mediapipe/calculators/util/logic_calculator.proto b/mediapipe/calculators/util/logic_calculator.proto index fe00a2d9b..8f9f6d856 100644 --- a/mediapipe/calculators/util/logic_calculator.proto +++ b/mediapipe/calculators/util/logic_calculator.proto @@ -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; From b05fd21709a47ae7365a3385c9f73fb7df15e19f Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 26 Apr 2023 17:47:14 -0700 Subject: [PATCH 112/753] Refactor the loss functions to initialize the VGG loss function in the init function to avoid duplicated initialization. PiperOrigin-RevId: 527424556 --- mediapipe/model_maker/python/core/utils/loss_functions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mediapipe/model_maker/python/core/utils/loss_functions.py b/mediapipe/model_maker/python/core/utils/loss_functions.py index cc17ab397..a60bd2ed4 100644 --- a/mediapipe/model_maker/python/core/utils/loss_functions.py +++ b/mediapipe/model_maker/python/core/utils/loss_functions.py @@ -144,6 +144,7 @@ class ImagePerceptualQualityLoss(tf.keras.losses.Loss): """Initializes ImagePerceptualQualityLoss.""" self._loss_weight = loss_weight self._losses = {} + self._vgg_loss = VGGPerceptualLoss(self._loss_weight) self._reduction = reduction def _l1_loss( @@ -164,7 +165,7 @@ class ImagePerceptualQualityLoss(tf.keras.losses.Loss): self._loss_weight = PerceptualLossWeight() if self._loss_weight.content > 0 or self._loss_weight.style > 0: - vgg_loss = VGGPerceptualLoss(self._loss_weight)(img1, img2) + vgg_loss = self._vgg_loss(img1, img2) vgg_loss_value = tf.math.add_n(vgg_loss.values()) loss_value.append(vgg_loss_value) if self._loss_weight.l1 > 0: From 2122b5d7be870237042058e316b599a5eee22eb1 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 26 Apr 2023 18:15:46 -0700 Subject: [PATCH 113/753] Internal change PiperOrigin-RevId: 527430483 --- .../vision/imagesegmenter/ImageSegmenter.java | 29 +++++++++---------- .../InteractiveSegmenter.java | 13 +++++---- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java index 200fbeabb..3d6df3022 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java @@ -80,7 +80,6 @@ public final class ImageSegmenter extends BaseVisionTaskApi { private static final List INPUT_STREAMS = Collections.unmodifiableList( Arrays.asList("IMAGE:" + IMAGE_IN_STREAM_NAME, "NORM_RECT:" + NORM_RECT_IN_STREAM_NAME)); - private static final int IMAGE_OUT_STREAM_INDEX = 0; private static final String TASK_GRAPH_NAME = "mediapipe.tasks.vision.image_segmenter.ImageSegmenterGraph"; private static final String TENSORS_TO_SEGMENTATION_CALCULATOR_NAME = @@ -102,27 +101,21 @@ public final class ImageSegmenter extends BaseVisionTaskApi { "At least one of `outputConfidenceMasks` and `outputCategoryMask` must be set."); } List outputStreams = new ArrayList<>(); - outputStreams.add("IMAGE:image_out"); - // Add an output stream to the output stream list, and get the added output stream index. BiFunction, String, Integer> getStreamIndex = (List streams, String streamName) -> { streams.add(streamName); return streams.size() - 1; }; - - int confidenceMasksOutStreamIndex = + final int confidenceMasksOutStreamIndex = segmenterOptions.outputConfidenceMasks() ? getStreamIndex.apply(outputStreams, "CONFIDENCE_MASKS:confidence_masks") : -1; - int confidenceMaskOutStreamIndex = - segmenterOptions.outputConfidenceMasks() - ? getStreamIndex.apply(outputStreams, "CONFIDENCE_MASK:0:confidence_mask") - : -1; - int categoryMaskOutStreamIndex = + final int categoryMaskOutStreamIndex = segmenterOptions.outputCategoryMask() ? getStreamIndex.apply(outputStreams, "CATEGORY_MASK:category_mask") : -1; + final int imageOutStreamIndex = getStreamIndex.apply(outputStreams, "IMAGE:image_out"); // TODO: Consolidate OutputHandler and TaskRunner. OutputHandler handler = new OutputHandler<>(); @@ -131,17 +124,21 @@ public final class ImageSegmenter extends BaseVisionTaskApi { @Override public ImageSegmenterResult convertToTaskResult(List packets) throws MediaPipeException { - if (packets.get(IMAGE_OUT_STREAM_INDEX).isEmpty()) { + if (packets.get(imageOutStreamIndex).isEmpty()) { return ImageSegmenterResult.create( Optional.empty(), Optional.empty(), - packets.get(IMAGE_OUT_STREAM_INDEX).getTimestamp()); + packets.get(imageOutStreamIndex).getTimestamp()); } boolean copyImage = !segmenterOptions.resultListener().isPresent(); Optional> confidenceMasks = Optional.empty(); if (segmenterOptions.outputConfidenceMasks()) { - int width = PacketGetter.getImageWidth(packets.get(confidenceMaskOutStreamIndex)); - int height = PacketGetter.getImageHeight(packets.get(confidenceMaskOutStreamIndex)); + int width = + PacketGetter.getImageWidthFromImageList( + packets.get(confidenceMasksOutStreamIndex)); + int height = + PacketGetter.getImageHeightFromImageList( + packets.get(confidenceMasksOutStreamIndex)); confidenceMasks = Optional.of(new ArrayList()); int confidenceMasksListSize = PacketGetter.getImageListSize(packets.get(confidenceMasksOutStreamIndex)); @@ -189,13 +186,13 @@ public final class ImageSegmenter extends BaseVisionTaskApi { confidenceMasks, categoryMask, BaseVisionTaskApi.generateResultTimestampMs( - segmenterOptions.runningMode(), packets.get(IMAGE_OUT_STREAM_INDEX))); + segmenterOptions.runningMode(), packets.get(imageOutStreamIndex))); } @Override public MPImage convertToTaskInput(List packets) { return new BitmapImageBuilder( - AndroidPacketGetter.getBitmapFromRgb(packets.get(IMAGE_OUT_STREAM_INDEX))) + AndroidPacketGetter.getBitmapFromRgb(packets.get(imageOutStreamIndex))) .build(); } }); diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java index 2a5d148e4..52a5f2a67 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java @@ -94,7 +94,6 @@ public final class InteractiveSegmenter extends BaseVisionTaskApi { "IMAGE:" + IMAGE_IN_STREAM_NAME, "ROI:" + ROI_IN_STREAM_NAME, "NORM_RECT:" + NORM_RECT_IN_STREAM_NAME)); - private static final int IMAGE_OUT_STREAM_INDEX = 0; private static final String TASK_GRAPH_NAME = "mediapipe.tasks.vision.interactive_segmenter.InteractiveSegmenterGraph"; private static final String TENSORS_TO_SEGMENTATION_CALCULATOR_NAME = @@ -120,7 +119,6 @@ public final class InteractiveSegmenter extends BaseVisionTaskApi { "At least one of `outputConfidenceMasks` and `outputCategoryMask` must be set."); } List outputStreams = new ArrayList<>(); - outputStreams.add("IMAGE:image_out"); if (segmenterOptions.outputConfidenceMasks()) { outputStreams.add("CONFIDENCE_MASKS:confidence_masks"); } @@ -129,6 +127,9 @@ public final class InteractiveSegmenter extends BaseVisionTaskApi { outputStreams.add("CATEGORY_MASK:category_mask"); } final int categoryMaskOutStreamIndex = outputStreams.size() - 1; + outputStreams.add("IMAGE:image_out"); + // TODO: add test for stream indices. + final int imageOutStreamIndex = outputStreams.size() - 1; // TODO: Consolidate OutputHandler and TaskRunner. OutputHandler handler = new OutputHandler<>(); @@ -137,11 +138,11 @@ public final class InteractiveSegmenter extends BaseVisionTaskApi { @Override public ImageSegmenterResult convertToTaskResult(List packets) throws MediaPipeException { - if (packets.get(IMAGE_OUT_STREAM_INDEX).isEmpty()) { + if (packets.get(imageOutStreamIndex).isEmpty()) { return ImageSegmenterResult.create( Optional.empty(), Optional.empty(), - packets.get(IMAGE_OUT_STREAM_INDEX).getTimestamp()); + packets.get(imageOutStreamIndex).getTimestamp()); } // If resultListener is not provided, the resulted MPImage is deep copied from // mediapipe graph. If provided, the result MPImage is wrapping the mediapipe packet @@ -202,13 +203,13 @@ public final class InteractiveSegmenter extends BaseVisionTaskApi { confidenceMasks, categoryMask, BaseVisionTaskApi.generateResultTimestampMs( - RunningMode.IMAGE, packets.get(IMAGE_OUT_STREAM_INDEX))); + RunningMode.IMAGE, packets.get(imageOutStreamIndex))); } @Override public MPImage convertToTaskInput(List packets) { return new BitmapImageBuilder( - AndroidPacketGetter.getBitmapFromRgb(packets.get(IMAGE_OUT_STREAM_INDEX))) + AndroidPacketGetter.getBitmapFromRgb(packets.get(imageOutStreamIndex))) .build(); } }); From 7b055df21193647540b934d5a25fdcbac805d477 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 26 Apr 2023 22:11:06 -0700 Subject: [PATCH 114/753] Internal change PiperOrigin-RevId: 527473249 --- mediapipe/framework/tool/name_util.cc | 2 +- mediapipe/framework/tool/tag_map_test.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediapipe/framework/tool/name_util.cc b/mediapipe/framework/tool/name_util.cc index 4784441d7..d42cbb622 100644 --- a/mediapipe/framework/tool/name_util.cc +++ b/mediapipe/framework/tool/name_util.cc @@ -60,7 +60,7 @@ std::string GetUnusedSidePacketName( } std::string candidate = input_side_packet_name_base; int iter = 2; - while (mediapipe::ContainsKey(input_side_packets, candidate)) { + while (input_side_packets.contains(candidate)) { candidate = absl::StrCat(input_side_packet_name_base, "_", absl::StrFormat("%02d", iter)); ++iter; diff --git a/mediapipe/framework/tool/tag_map_test.cc b/mediapipe/framework/tool/tag_map_test.cc index 20a9be966..a93b94445 100644 --- a/mediapipe/framework/tool/tag_map_test.cc +++ b/mediapipe/framework/tool/tag_map_test.cc @@ -101,7 +101,7 @@ void TestSuccessTagMap(const std::vector& tag_index_names, EXPECT_EQ(tags.size(), tag_map->Mapping().size()) << "Parameters: in " << tag_map->DebugString(); for (int i = 0; i < tags.size(); ++i) { - EXPECT_TRUE(mediapipe::ContainsKey(tag_map->Mapping(), tags[i])) + EXPECT_TRUE(tag_map->Mapping().contains(tags[i])) << "Parameters: Trying to find \"" << tags[i] << "\" in\n" << tag_map->DebugString(); } From 7c70c62465ded131b22bbd2822193641f2a85cdb Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Thu, 27 Apr 2023 08:08:18 -0700 Subject: [PATCH 115/753] Fix typo and improve comments. PiperOrigin-RevId: 527580369 --- .../tasks/cc/vision/face_detector/face_detector_graph.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc b/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc index 545bdb275..8d83ac2c8 100644 --- a/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc @@ -127,9 +127,9 @@ void ConfigureNonMaxSuppressionCalculator( void ConfigureDetectionsToRectsCalculator( mediapipe::DetectionsToRectsCalculatorOptions* options) { - // Left eye. + // Left eye from the observer’s point of view. options->set_rotation_vector_start_keypoint_index(0); - // Right ete. + // Right eye from the observer’s point of view. options->set_rotation_vector_end_keypoint_index(1); options->set_rotation_vector_target_angle_degrees(0); } From bc3434108e35662eb639209097d7c0ec9b1c379d Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 27 Apr 2023 09:15:24 -0700 Subject: [PATCH 116/753] Update MPImage to use containers PiperOrigin-RevId: 527596164 --- mediapipe/tasks/web/vision/core/image.test.ts | 8 +- mediapipe/tasks/web/vision/core/image.ts | 191 ++++++++++-------- 2 files changed, 109 insertions(+), 90 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/image.test.ts b/mediapipe/tasks/web/vision/core/image.test.ts index 891fafad0..67f2c7666 100644 --- a/mediapipe/tasks/web/vision/core/image.test.ts +++ b/mediapipe/tasks/web/vision/core/image.test.ts @@ -112,9 +112,7 @@ async function createTestData( shaderContext: MPImageShaderContext, input: ImageType, width: number, height: number): MPImage { return new MPImage( - input instanceof ImageData ? input : null, - input instanceof ImageBitmap ? input : null, - input instanceof WebGLTexture ? input : null, + [input], /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, canvas, shaderContext, width, height); } @@ -193,7 +191,7 @@ async function createTestData( const shaderContext = new MPImageShaderContext(); const image = new MPImage( - /* imageData= */ null, /* imageBitmap= */ null, webGlTexture, + [webGlTexture], /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, canvas, shaderContext, WIDTH, HEIGHT); @@ -211,7 +209,7 @@ async function createTestData( const shaderContext = new MPImageShaderContext(); const image = new MPImage( - /* imageData= */ null, /* imageBitmap= */ null, webGlTexture, + [webGlTexture], /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, canvas, shaderContext, WIDTH, HEIGHT); diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index 9059fcb78..3c87e0d2b 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -24,7 +24,9 @@ export enum MPImageStorageType { WEBGL_TEXTURE } -type MPImageNativeContainer = ImageData|ImageBitmap|WebGLTexture; +/** The supported image formats. For internal usage. */ +export type MPImageNativeContainer = + Uint8ClampedArray|Float32Array|ImageData|ImageBitmap|WebGLTexture; const VERTEX_SHADER = ` attribute vec2 aVertex; @@ -274,9 +276,7 @@ export class MPImage { /** @hideconstructor */ constructor( - private imageData: ImageData|null, - private imageBitmap: ImageBitmap|null, - private webGLTexture: WebGLTexture|null, + private readonly containers: MPImageNativeContainer[], private ownsImageBitmap: boolean, private ownsWebGLTexture: boolean, /** Returns the canvas element that the image is bound to. */ @@ -294,15 +294,7 @@ export class MPImage { * `getType()`. */ hasType(type: MPImageStorageType): boolean { - if (type === MPImageStorageType.IMAGE_DATA) { - return !!this.imageData; - } else if (type === MPImageStorageType.IMAGE_BITMAP) { - return !!this.imageBitmap; - } else if (type === MPImageStorageType.WEBGL_TEXTURE) { - return !!this.webGLTexture; - } else { - throw new Error(`Type is not supported: ${type}`); - } + return !!this.getContainer(type); } /** @@ -336,14 +328,37 @@ export class MPImage { */ getImage(type: MPImageStorageType.WEBGL_TEXTURE): WebGLTexture; getImage(type?: MPImageStorageType): MPImageNativeContainer { - if (type === MPImageStorageType.IMAGE_DATA) { - return this.convertToImageData(); - } else if (type === MPImageStorageType.IMAGE_BITMAP) { - return this.convertToImageBitmap(); - } else if (type === MPImageStorageType.WEBGL_TEXTURE) { - return this.convertToWebGLTexture(); - } else { - throw new Error(`Type is not supported: ${type}`); + switch (type) { + case MPImageStorageType.IMAGE_DATA: + return this.convertToImageData(); + case MPImageStorageType.IMAGE_BITMAP: + return this.convertToImageBitmap(); + case MPImageStorageType.WEBGL_TEXTURE: + return this.convertToWebGLTexture(); + default: + throw new Error(`Type is not supported: ${type}`); + } + } + + private getContainer(type: MPImageStorageType.IMAGE_DATA): ImageData + |undefined; + private getContainer(type: MPImageStorageType.IMAGE_BITMAP): ImageBitmap + |undefined; + private getContainer(type: MPImageStorageType.WEBGL_TEXTURE): WebGLTexture + |undefined; + private getContainer(type: MPImageStorageType): MPImageNativeContainer + |undefined; + private getContainer(type: MPImageStorageType): MPImageNativeContainer + |undefined { + switch (type) { + case MPImageStorageType.IMAGE_DATA: + return this.containers.find(img => img instanceof ImageData); + case MPImageStorageType.IMAGE_BITMAP: + return this.containers.find(img => img instanceof ImageBitmap); + case MPImageStorageType.WEBGL_TEXTURE: + return this.containers.find(img => img instanceof WebGLTexture); + default: + throw new Error(`Type is not supported: ${type}`); } } @@ -355,54 +370,56 @@ export class MPImage { * avoided. */ clone(): MPImage { + const destinationContainers: MPImageNativeContainer[] = []; + // TODO: We might only want to clone one backing datastructure - // even if multiple are defined. - let destinationImageData: ImageData|null = null; - let destinationImageBitmap: ImageBitmap|null = null; - let destinationWebGLTexture: WebGLTexture|null = null; + // even if multiple are defined; + for (const container of this.containers) { + let destinationContainer: MPImageNativeContainer; - if (this.imageData) { - destinationImageData = - new ImageData(this.imageData.data, this.width, this.height); - } + if (container instanceof ImageData) { + destinationContainer = + new ImageData(container.data, this.width, this.height); + } else if (container instanceof WebGLTexture) { + const gl = this.getGL(); + const shaderContext = this.getShaderContext(); - if (this.webGLTexture) { - const gl = this.getGL(); - const shaderContext = this.getShaderContext(); + // Create a new texture and use it to back a framebuffer + gl.activeTexture(gl.TEXTURE1); + destinationContainer = + assertNotNull(gl.createTexture(), 'Failed to create texture'); + gl.bindTexture(gl.TEXTURE_2D, destinationContainer); - // Create a new texture and use it to back a framebuffer - gl.activeTexture(gl.TEXTURE1); - destinationWebGLTexture = - assertNotNull(gl.createTexture(), 'Failed to create texture'); - gl.bindTexture(gl.TEXTURE_2D, destinationWebGLTexture); + gl.texImage2D( + gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, + gl.UNSIGNED_BYTE, null); - gl.texImage2D( - gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, - gl.UNSIGNED_BYTE, null); + shaderContext.bindFramebuffer(gl, destinationContainer); + shaderContext.run(gl, /* flipVertically= */ false, () => { + this.bindTexture(); // This activates gl.TEXTURE0 + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + gl.drawArrays(gl.TRIANGLE_FAN, 0, 4); + this.unbindTexture(); + }); + shaderContext.unbindFramebuffer(); - shaderContext.bindFramebuffer(gl, destinationWebGLTexture); - shaderContext.run(gl, /* flipVertically= */ false, () => { - this.bindTexture(); // This activates gl.TEXTURE0 - gl.clearColor(0, 0, 0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - gl.drawArrays(gl.TRIANGLE_FAN, 0, 4); this.unbindTexture(); - }); - shaderContext.unbindFramebuffer(); + } else if (container instanceof ImageBitmap) { + this.convertToWebGLTexture(); + this.bindTexture(); + destinationContainer = this.copyTextureToBitmap(); + this.unbindTexture(); + } else { + throw new Error(`Type is not supported: ${container}`); + } - this.unbindTexture(); - } - - if (this.imageBitmap) { - this.convertToWebGLTexture(); - this.bindTexture(); - destinationImageBitmap = this.copyTextureToBitmap(); - this.unbindTexture(); + destinationContainers.push(destinationContainer); } return new MPImage( - destinationImageData, destinationImageBitmap, destinationWebGLTexture, - !!destinationImageBitmap, !!destinationWebGLTexture, this.canvas, + destinationContainers, this.hasType(MPImageStorageType.IMAGE_BITMAP), + this.hasType(MPImageStorageType.WEBGL_TEXTURE), this.canvas, this.shaderContext, this.width, this.height); } @@ -439,75 +456,82 @@ export class MPImage { } private convertToImageBitmap(): ImageBitmap { - if (!this.imageBitmap) { - if (!this.webGLTexture) { - this.webGLTexture = this.convertToWebGLTexture(); - } - this.imageBitmap = this.convertWebGLTextureToImageBitmap(); + let imageBitmap = this.getContainer(MPImageStorageType.IMAGE_BITMAP); + if (!imageBitmap) { + this.convertToWebGLTexture(); + imageBitmap = this.convertWebGLTextureToImageBitmap(); + this.containers.push(imageBitmap); this.ownsImageBitmap = true; } - - return this.imageBitmap; + return imageBitmap; } private convertToImageData(): ImageData { - if (!this.imageData) { + let imageData = this.getContainer(MPImageStorageType.IMAGE_DATA); + if (!imageData) { const gl = this.getGL(); const shaderContext = this.getShaderContext(); const pixels = new Uint8Array(this.width * this.height * 4); // Create texture if needed - this.convertToWebGLTexture(); + const webGLTexture = this.convertToWebGLTexture(); // Create a framebuffer from the texture and read back pixels - shaderContext.bindFramebuffer(gl, this.webGLTexture!); + shaderContext.bindFramebuffer(gl, webGLTexture); gl.readPixels( 0, 0, this.width, this.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); shaderContext.unbindFramebuffer(); - this.imageData = new ImageData( + imageData = new ImageData( new Uint8ClampedArray(pixels.buffer), this.width, this.height); + this.containers.push(imageData); } - return this.imageData; + return imageData; } private convertToWebGLTexture(): WebGLTexture { - if (!this.webGLTexture) { + let webGLTexture = this.getContainer(MPImageStorageType.WEBGL_TEXTURE); + if (!webGLTexture) { const gl = this.getGL(); - this.bindTexture(); - const source = (this.imageBitmap || this.imageData)!; + webGLTexture = this.bindTexture(); + const source = this.getContainer(MPImageStorageType.IMAGE_BITMAP) || + this.convertToImageData(); gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source); this.unbindTexture(); } - return this.webGLTexture!; + return webGLTexture; } /** * Binds the backing texture to the canvas. If the texture does not yet * exist, creates it first. */ - private bindTexture() { + private bindTexture(): WebGLTexture { const gl = this.getGL(); gl.viewport(0, 0, this.width, this.height); - gl.activeTexture(gl.TEXTURE0); - if (!this.webGLTexture) { - this.webGLTexture = + + let webGLTexture = this.getContainer(MPImageStorageType.WEBGL_TEXTURE); + if (!webGLTexture) { + webGLTexture = assertNotNull(gl.createTexture(), 'Failed to create texture'); + this.containers.push(webGLTexture); this.ownsWebGLTexture = true; } - gl.bindTexture(gl.TEXTURE_2D, this.webGLTexture); + gl.bindTexture(gl.TEXTURE_2D, webGLTexture); // TODO: Ideally, we would only set these once per texture and // not once every frame. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + + return webGLTexture; } private unbindTexture(): void { @@ -581,15 +605,12 @@ export class MPImage { */ close(): void { if (this.ownsImageBitmap) { - this.imageBitmap!.close(); - } - - if (!this.gl) { - return; + this.getContainer(MPImageStorageType.IMAGE_BITMAP)!.close(); } if (this.ownsWebGLTexture) { - this.gl.deleteTexture(this.webGLTexture!); + const gl = this.getGL(); + gl.deleteTexture(this.getContainer(MPImageStorageType.WEBGL_TEXTURE)!); } } } From b457060c3a7507b530bd1a6cb95be9728a631072 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 27 Apr 2023 10:10:03 -0700 Subject: [PATCH 117/753] Generify tests for MPImage PiperOrigin-RevId: 527611864 --- mediapipe/tasks/web/vision/core/image.test.ts | 225 ++++++++---------- 1 file changed, 104 insertions(+), 121 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/image.test.ts b/mediapipe/tasks/web/vision/core/image.test.ts index 67f2c7666..31d30eefe 100644 --- a/mediapipe/tasks/web/vision/core/image.test.ts +++ b/mediapipe/tasks/web/vision/core/image.test.ts @@ -29,43 +29,64 @@ if (skip) { /** The image types supported by MPImage. */ type ImageType = ImageData|ImageBitmap|WebGLTexture; -async function createTestData( - gl: WebGL2RenderingContext, data: number[], width: number, - height: number): Promise<[ImageData, ImageBitmap, WebGLTexture]> { - const imageData = new ImageData(new Uint8ClampedArray(data), width, height); - const imageBitmap = await createImageBitmap(imageData); - const webGlTexture = gl.createTexture()!; +const IMAGE_2_2 = [1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, 4, 0, 0, 255]; +const IMAGE_2_1 = [1, 0, 0, 255, 2, 0, 0, 255]; +const IMAGE_2_3 = [ + 1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, + 4, 0, 0, 255, 5, 0, 0, 255, 6, 0, 0, 255 +]; - gl.bindTexture(gl.TEXTURE_2D, webGlTexture); - gl.texImage2D( - gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imageBitmap); - gl.bindTexture(gl.TEXTURE_2D, null); +/** The test images and data to use for the unit tests below. */ +class MPImageTestContext { + canvas!: OffscreenCanvas; + gl!: WebGL2RenderingContext; + imageData!: ImageData; + imageBitmap!: ImageBitmap; + webGLTexture!: WebGLTexture; - return [imageData, imageBitmap, webGlTexture]; + async init(pixels = IMAGE_2_2, width = WIDTH, height = HEIGHT): + Promise { + // Initialize a canvas with default dimensions. Note that the canvas size + // can be different from the image size. + this.canvas = new OffscreenCanvas(WIDTH, HEIGHT); + this.gl = this.canvas.getContext('webgl2') as WebGL2RenderingContext; + + const gl = this.gl; + this.imageData = + new ImageData(new Uint8ClampedArray(pixels), width, height); + this.imageBitmap = await createImageBitmap(this.imageData); + this.webGLTexture = gl.createTexture()!; + + gl.bindTexture(gl.TEXTURE_2D, this.webGLTexture); + gl.texImage2D( + gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.imageBitmap); + gl.bindTexture(gl.TEXTURE_2D, null); + } + + get(type: unknown) { + switch (type) { + case ImageData: + return this.imageData; + case ImageBitmap: + return this.imageBitmap; + case WebGLTexture: + return this.webGLTexture; + default: + throw new Error(`Unsupported type: ${type}`); + } + } + + close(): void { + this.gl.deleteTexture(this.webGLTexture); + this.imageBitmap.close(); + } } (skip ? xdescribe : describe)('MPImage', () => { - let canvas: OffscreenCanvas; - let gl: WebGL2RenderingContext; - let imageData: ImageData; - let imageBitmap: ImageBitmap; - let webGlTexture: WebGLTexture; - - beforeEach(async () => { - canvas = new OffscreenCanvas(WIDTH, HEIGHT); - gl = canvas.getContext('webgl2') as WebGL2RenderingContext; - - const images = await createTestData( - gl, [1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, 4, 0, 0, 255], WIDTH, - HEIGHT); - imageData = images[0]; - imageBitmap = images[1]; - webGlTexture = images[2]; - }); + const context = new MPImageTestContext(); afterEach(() => { - gl.deleteTexture(webGlTexture); - imageBitmap.close(); + context.close(); }); function readPixelsFromImageBitmap(imageBitmap: ImageBitmap): ImageData { @@ -78,6 +99,7 @@ async function createTestData( function readPixelsFromWebGLTexture(texture: WebGLTexture): Uint8Array { const pixels = new Uint8Array(WIDTH * WIDTH * 4); + const gl = context.gl; gl.bindTexture(gl.TEXTURE_2D, texture); const framebuffer = gl.createFramebuffer()!; @@ -113,8 +135,8 @@ async function createTestData( height: number): MPImage { return new MPImage( [input], - /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, canvas, - shaderContext, width, height); + /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, + context.canvas, shaderContext, width, height); } function runConversionTest( @@ -136,105 +158,67 @@ async function createTestData( shaderContext.close(); } - it(`converts from ImageData to ImageData`, () => { - runConversionTest(imageData, imageData); - }); + const sources = skip ? [] : [ImageData, ImageBitmap, WebGLTexture]; - it(`converts from ImageData to ImageBitmap`, () => { - runConversionTest(imageData, imageBitmap); - }); + for (let i = 0; i < sources.length; i++) { + for (let j = 0; j < sources.length; j++) { + it(`converts from ${sources[i].name} to ${sources[j].name}`, async () => { + await context.init(); + runConversionTest(context.get(sources[i]), context.get(sources[j])); + }); + } + } - it(`converts from ImageData to WebGLTexture`, () => { - runConversionTest(imageData, webGlTexture); - }); - - it(`converts from ImageBitmap to ImageData`, () => { - runConversionTest(imageBitmap, imageData); - }); - - it(`converts from ImageBitmap to ImageBitmap`, () => { - runConversionTest(imageBitmap, imageBitmap); - }); - - it(`converts from ImageBitmap to WebGLTexture`, () => { - runConversionTest(imageBitmap, webGlTexture); - }); - - it(`converts from WebGLTexture to ImageData`, () => { - runConversionTest(webGlTexture, imageData); - }); - - it(`converts from WebGLTexture to ImageBitmap`, () => { - runConversionTest(webGlTexture, imageBitmap); - }); - - it(`converts from WebGLTexture to WebGLTexture`, () => { - runConversionTest(webGlTexture, webGlTexture); - }); - - it(`clones ImageData`, () => { - runCloneTest(imageData); - }); - - it(`clones ImageBitmap`, () => { - runCloneTest(imageBitmap); - }); - - it(`clones WebGLTextures`, () => { - runCloneTest(webGlTexture); - }); + for (let i = 0; i < sources.length; i++) { + it(`clones ${sources[i].name}`, async () => { + await context.init(); + runCloneTest(context.get(sources[i])); + }); + } it(`does not flip textures twice`, async () => { - const [imageData, , webGlTexture] = await createTestData( - gl, [1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, 4, 0, 0, 255], WIDTH, - HEIGHT); + await context.init(); const shaderContext = new MPImageShaderContext(); const image = new MPImage( - [webGlTexture], - /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, canvas, - shaderContext, WIDTH, HEIGHT); + [context.webGLTexture], + /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, + context.canvas, shaderContext, WIDTH, HEIGHT); const result = image.clone().getImage(MPImageStorageType.IMAGE_DATA); - expect(result).toEqual(imageData); + expect(result).toEqual(context.imageData); - gl.deleteTexture(webGlTexture); shaderContext.close(); }); it(`can clone and get image`, async () => { - const [imageData, , webGlTexture] = await createTestData( - gl, [1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, 4, 0, 0, 255], WIDTH, - HEIGHT); + await context.init(); const shaderContext = new MPImageShaderContext(); const image = new MPImage( - [webGlTexture], - /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, canvas, - shaderContext, WIDTH, HEIGHT); + [context.webGLTexture], + /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, + context.canvas, shaderContext, WIDTH, HEIGHT); // Verify that we can mix the different shader modes by running them out of // order. let result = image.getImage(MPImageStorageType.IMAGE_DATA); - expect(result).toEqual(imageData); + expect(result).toEqual(context.imageData); result = image.clone().getImage(MPImageStorageType.IMAGE_DATA); - expect(result).toEqual(imageData); + expect(result).toEqual(context.imageData); result = image.getImage(MPImageStorageType.IMAGE_DATA); - expect(result).toEqual(imageData); + expect(result).toEqual(context.imageData); - gl.deleteTexture(webGlTexture); shaderContext.close(); }); it('supports hasType()', async () => { - const shaderContext = new MPImageShaderContext(); - const image = createImage(shaderContext, imageData, WIDTH, HEIGHT); + await context.init(); - expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); - expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(false); - expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false); + const shaderContext = new MPImageShaderContext(); + const image = createImage(shaderContext, context.imageData, WIDTH, HEIGHT); image.getImage(MPImageStorageType.WEBGL_TEXTURE); @@ -242,7 +226,7 @@ async function createTestData( expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(true); expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false); - await image.getImage(MPImageStorageType.IMAGE_BITMAP); + image.getImage(MPImageStorageType.IMAGE_BITMAP); expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(true); @@ -253,33 +237,32 @@ async function createTestData( }); it('supports image that is smaller than the canvas', async () => { - const [imageData, imageBitmap, webGlTexture] = await createTestData( - gl, [1, 0, 0, 255, 2, 0, 0, 255], /* width= */ 2, /* height= */ 1); + await context.init(IMAGE_2_1, /* width= */ 2, /* height= */ 1); - runConversionTest(imageData, webGlTexture, /* width= */ 2, /* height= */ 1); runConversionTest( - webGlTexture, imageBitmap, /* width= */ 2, /* height= */ 1); - runConversionTest(imageBitmap, imageData, /* width= */ 2, /* height= */ 1); + context.imageData, context.webGLTexture, /* width= */ 2, + /* height= */ 1); + runConversionTest( + context.webGLTexture, context.imageBitmap, /* width= */ 2, + /* height= */ 1); + runConversionTest( + context.imageBitmap, context.imageData, /* width= */ 2, + /* height= */ 1); - gl.deleteTexture(webGlTexture); - imageBitmap.close(); + context.close(); }); it('supports image that is larger than the canvas', async () => { - const [imageData, imageBitmap, webGlTexture] = await createTestData( - gl, - [ - 1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, - 4, 0, 0, 255, 5, 0, 0, 255, 6, 0, 0, 255 - ], - /* width= */ 2, /* height= */ 3); + await context.init(IMAGE_2_3, /* width= */ 2, /* height= */ 3); - runConversionTest(imageData, webGlTexture, /* width= */ 2, /* height= */ 3); runConversionTest( - webGlTexture, imageBitmap, /* width= */ 2, /* height= */ 3); - runConversionTest(imageBitmap, imageData, /* width= */ 2, /* height= */ 3); - - gl.deleteTexture(webGlTexture); - imageBitmap.close(); + context.imageData, context.webGLTexture, /* width= */ 2, + /* height= */ 3); + runConversionTest( + context.webGLTexture, context.imageBitmap, /* width= */ 2, + /* height= */ 3); + runConversionTest( + context.imageBitmap, context.imageData, /* width= */ 2, + /* height= */ 3); }); }); From d5157a039e2aec378f36993dc5a0cc6c4ab82f17 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 27 Apr 2023 10:29:26 -0700 Subject: [PATCH 118/753] Add .github workspace import PiperOrigin-RevId: 527617546 --- {.github => mediapipe/opensource_only}/stale.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {.github => mediapipe/opensource_only}/stale.yml (100%) diff --git a/.github/stale.yml b/mediapipe/opensource_only/stale.yml similarity index 100% rename from .github/stale.yml rename to mediapipe/opensource_only/stale.yml From a5852b05139dc3a653e0de5190b3330c01708cf3 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 27 Apr 2023 10:48:19 -0700 Subject: [PATCH 119/753] Internal change PiperOrigin-RevId: 527623223 --- .../org_tensorflow_compatibility_fixes.diff | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/third_party/org_tensorflow_compatibility_fixes.diff b/third_party/org_tensorflow_compatibility_fixes.diff index c360b072e..36bc34f9e 100644 --- a/third_party/org_tensorflow_compatibility_fixes.diff +++ b/third_party/org_tensorflow_compatibility_fixes.diff @@ -54,3 +54,17 @@ index 462ec7c2218..f2b583a4cbd 100644 # copybara:comment_end def gpu_delegate_linkopts(): +diff --git a/tensorflow/tsl/platform/windows/error_windows.cc b/tensorflow/tsl/platform/windows/error_windows.cc +index fea37ddb2ea..4070ea55425 100644 +--- a/tensorflow/tsl/platform/windows/error_windows.cc ++++ b/tensorflow/tsl/platform/windows/error_windows.cc +@@ -15,8 +15,8 @@ limitations under the License. + + #include "tensorflow/tsl/platform/windows/error_windows.h" + +-#include + #include ++#include + + #include + \ No newline at end of file From 1b82821f15264c5a32733fc0b6aca994146a52e4 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 27 Apr 2023 11:10:00 -0700 Subject: [PATCH 120/753] Add support for single-channel images to MPImage PiperOrigin-RevId: 527629970 --- mediapipe/tasks/web/vision/core/image.test.ts | 59 +++- mediapipe/tasks/web/vision/core/image.ts | 318 ++++++++++++++++-- 2 files changed, 341 insertions(+), 36 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/image.test.ts b/mediapipe/tasks/web/vision/core/image.test.ts index 31d30eefe..e991aa7dc 100644 --- a/mediapipe/tasks/web/vision/core/image.test.ts +++ b/mediapipe/tasks/web/vision/core/image.test.ts @@ -29,17 +29,19 @@ if (skip) { /** The image types supported by MPImage. */ type ImageType = ImageData|ImageBitmap|WebGLTexture; -const IMAGE_2_2 = [1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, 4, 0, 0, 255]; -const IMAGE_2_1 = [1, 0, 0, 255, 2, 0, 0, 255]; +const IMAGE_2_2 = [1, 1, 1, 255, 2, 2, 2, 255, 3, 3, 3, 255, 4, 4, 4, 255]; +const IMAGE_2_1 = [1, 1, 1, 255, 2, 2, 2, 255]; const IMAGE_2_3 = [ - 1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, - 4, 0, 0, 255, 5, 0, 0, 255, 6, 0, 0, 255 + 1, 1, 1, 255, 2, 2, 2, 255, 3, 3, 3, 255, + 4, 4, 4, 255, 5, 5, 5, 255, 6, 6, 6, 255 ]; /** The test images and data to use for the unit tests below. */ class MPImageTestContext { canvas!: OffscreenCanvas; gl!: WebGL2RenderingContext; + uint8ClampedArray!: Uint8ClampedArray; + float32Array!: Float32Array; imageData!: ImageData; imageBitmap!: ImageBitmap; webGLTexture!: WebGLTexture; @@ -52,6 +54,13 @@ class MPImageTestContext { this.gl = this.canvas.getContext('webgl2') as WebGL2RenderingContext; const gl = this.gl; + + this.uint8ClampedArray = new Uint8ClampedArray(pixels.length / 4); + this.float32Array = new Float32Array(pixels.length / 4); + for (let i = 0; i < this.uint8ClampedArray.length; ++i) { + this.uint8ClampedArray[i] = pixels[i * 4]; + this.float32Array[i] = pixels[i * 4] / 255; + } this.imageData = new ImageData(new Uint8ClampedArray(pixels), width, height); this.imageBitmap = await createImageBitmap(this.imageData); @@ -65,6 +74,10 @@ class MPImageTestContext { get(type: unknown) { switch (type) { + case Uint8ClampedArray: + return this.uint8ClampedArray; + case Float32Array: + return this.float32Array; case ImageData: return this.imageData; case ImageBitmap: @@ -116,7 +129,13 @@ class MPImageTestContext { } function assertEquality(image: MPImage, expected: ImageType): void { - if (expected instanceof ImageData) { + if (expected instanceof Uint8ClampedArray) { + const result = image.getImage(MPImageStorageType.UINT8_CLAMPED_ARRAY); + expect(result).toEqual(expected); + } else if (expected instanceof Float32Array) { + const result = image.getImage(MPImageStorageType.FLOAT32_ARRAY); + expect(result).toEqual(expected); + } else if (expected instanceof ImageData) { const result = image.getImage(MPImageStorageType.IMAGE_DATA); expect(result).toEqual(expected); } else if (expected instanceof ImageBitmap) { @@ -158,7 +177,9 @@ class MPImageTestContext { shaderContext.close(); } - const sources = skip ? [] : [ImageData, ImageBitmap, WebGLTexture]; + const sources = skip ? + [] : + [Uint8ClampedArray, Float32Array, ImageData, ImageBitmap, WebGLTexture]; for (let i = 0; i < sources.length; i++) { for (let j = 0; j < sources.length; j++) { @@ -220,15 +241,41 @@ class MPImageTestContext { const shaderContext = new MPImageShaderContext(); const image = createImage(shaderContext, context.imageData, WIDTH, HEIGHT); + expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); + expect(image.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)).toBe(false); + expect(image.hasType(MPImageStorageType.FLOAT32_ARRAY)).toBe(false); + expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(false); + expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false); + + image.getImage(MPImageStorageType.UINT8_CLAMPED_ARRAY); + + expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); + expect(image.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)).toBe(true); + expect(image.hasType(MPImageStorageType.FLOAT32_ARRAY)).toBe(false); + expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(false); + expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false); + + image.getImage(MPImageStorageType.FLOAT32_ARRAY); + + expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); + expect(image.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)).toBe(true); + expect(image.hasType(MPImageStorageType.FLOAT32_ARRAY)).toBe(true); + expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(false); + expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false); + image.getImage(MPImageStorageType.WEBGL_TEXTURE); expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); + expect(image.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)).toBe(true); + expect(image.hasType(MPImageStorageType.FLOAT32_ARRAY)).toBe(true); expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(true); expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false); image.getImage(MPImageStorageType.IMAGE_BITMAP); expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); + expect(image.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)).toBe(true); + expect(image.hasType(MPImageStorageType.FLOAT32_ARRAY)).toBe(true); expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(true); expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(true); diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index 3c87e0d2b..739f05f0f 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -16,6 +16,12 @@ /** The underlying type of the image. */ export enum MPImageStorageType { + /** Represents the native `UInt8ClampedArray` type. */ + UINT8_CLAMPED_ARRAY, + /** + * Represents the native `Float32Array` type. Values range from [0.0, 1.0]. + */ + FLOAT32_ARRAY, /** Represents the native `ImageData` type. */ IMAGE_DATA, /** Represents the native `ImageBitmap` type. */ @@ -213,6 +219,7 @@ export class MPImageShaderContext { return result; } + /** * Binds a framebuffer to the canvas. If the framebuffer does not yet exist, * creates it first. Binds the provided texture to the framebuffer. @@ -251,6 +258,97 @@ export class MPImageShaderContext { } } +/** + * An interface that can be used to provide custom conversion functions. These + * functions are invoked to convert pixel values between different channel + * counts and value ranges. Any conversion function that is not specified will + * result in a default conversion. + */ +export interface MPImageChannelConverter { + /** + * A conversion function to convert a number in the [0.0, 1.0] range to RGBA. + * The output is an array with four elemeents whose values range from 0 to 255 + * inclusive. + * + * The default conversion function is `[v * 255, v * 255, v * 255, 255]` + * and will log a warning if invoked. + */ + floatToRGBAConverter?: (value: number) => [number, number, number, number]; + + /* + * A conversion function to convert a number in the [0, 255] range to RGBA. + * The output is an array with four elemeents whose values range from 0 to 255 + * inclusive. + * + * The default conversion function is `[v, v , v , 255]` and will log a + * warning if invoked. + */ + uint8ToRGBAConverter?: (value: number) => [number, number, number, number]; + + /** + * A conversion function to convert an RGBA value in the range of 0 to 255 to + * a single value in the [0.0, 1.0] range. + * + * The default conversion function is `(r / 3 + g / 3 + b / 3) / 255` and will + * log a warning if invoked. + */ + rgbaToFloatConverter?: (r: number, g: number, b: number, a: number) => number; + + /** + * A conversion function to convert an RGBA value in the range of 0 to 255 to + * a single value in the [0, 255] range. + * + * The default conversion function is `r / 3 + g / 3 + b / 3` and will log a + * warning if invoked. + */ + rgbaToUint8Converter?: (r: number, g: number, b: number, a: number) => number; + + /** + * A conversion function to convert a single value in the 0.0 to 1.0 range to + * [0, 255]. + * + * The default conversion function is `r * 255` and will log a warning if + * invoked. + */ + floatToUint8Converter?: (value: number) => number; + + /** + * A conversion function to convert a single value in the 0 to 255 range to + * [0.0, 1.0] . + * + * The default conversion function is `r / 255` and will log a warning if + * invoked. + */ + uint8ToFloatConverter?: (value: number) => number; +} + +const DEFAULT_CONVERTER: Required = { + floatToRGBAConverter: v => { + console.log('Using default floatToRGBAConverter'); + return [v * 255, v * 255, v * 255, 255]; + }, + uint8ToRGBAConverter: v => { + console.log('Using default uint8ToRGBAConverter'); + return [v, v, v, 255]; + }, + rgbaToFloatConverter: (r, g, b) => { + console.log('Using default floatToRGBAConverter'); + return (r / 3 + g / 3 + b / 3) / 255; + }, + rgbaToUint8Converter: (r, g, b) => { + console.log('Using default rgbaToUint8Converter'); + return r / 3 + g / 3 + b / 3; + }, + floatToUint8Converter: v => { + console.log('Using default floatToUint8Converter'); + return v * 255; + }, + uint8ToFloatConverter: v => { + console.log('Using default uint8ToFloatConverter'); + return v / 255; + }, +}; + /** * The wrapper class for MediaPipe Image objects. * @@ -270,6 +368,14 @@ export class MPImageShaderContext { * initialized with an `OffscreenCanvas`. As we require WebGL2 support, this * places some limitations on Browser support as outlined here: * https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas/getContext + * + * Some MediaPipe tasks return single channel masks. These masks are stored + * using an underlying `Uint8ClampedArray` an `Float32Array` (represented as + * single-channel arrays). To convert these type to other formats a conversion + * function is invoked to convert pixel values between single channel and four + * channel RGBA values. To customize this conversion, you can specify these + * conversion functions when you invoke `getImage()`. If you use the default + * conversion function a warning will be logged to the console. */ export class MPImage { private gl?: WebGL2RenderingContext; @@ -297,49 +403,110 @@ export class MPImage { return !!this.getContainer(type); } + /** + * Returns the underlying image as a single channel `Uint8ClampedArray`. Note + * that this involves an expensive GPU to CPU transfer if the current image is + * only available as an `ImageBitmap` or `WebGLTexture`. If necessary, this + * function converts RGBA data pixel-by-pixel to a single channel value by + * invoking a conversion function (see class comment for detail). + * + * @param type The type of image to return. + * @param converter A set of conversion functions that will be invoked to + * convert the underlying pixel data if necessary. You may omit this + * function if the requested conversion does not change the pixel format. + * @return The current data as a Uint8ClampedArray. + */ + getImage( + type: MPImageStorageType.UINT8_CLAMPED_ARRAY, + converter?: MPImageChannelConverter): Uint8ClampedArray; + /** + * Returns the underlying image as a single channel `Float32Array`. Note + * that this involves an expensive GPU to CPU transfer if the current image is + * only available as an `ImageBitmap` or `WebGLTexture`. If necessary, this + * function converts RGBA data pixel-by-pixel to a single channel value by + * invoking a conversion function (see class comment for detail). + * + * @param type The type of image to return. + * @param converter A set of conversion functions that will be invoked to + * convert the underlying pixel data if necessary. You may omit this + * function if the requested conversion does not change the pixel format. + * @return The current image as a Float32Array. + */ + getImage( + type: MPImageStorageType.FLOAT32_ARRAY, + converter?: MPImageChannelConverter): Float32Array; /** * Returns the underlying image as an `ImageData` object. Note that this * involves an expensive GPU to CPU transfer if the current image is only - * available as an `ImageBitmap` or `WebGLTexture`. + * available as an `ImageBitmap` or `WebGLTexture`. If necessary, this + * function converts single channel pixel values to RGBA by invoking a + * conversion function (see class comment for detail). * * @return The current image as an ImageData object. */ - getImage(type: MPImageStorageType.IMAGE_DATA): ImageData; + getImage( + type: MPImageStorageType.IMAGE_DATA, + converter?: MPImageChannelConverter): ImageData; /** * Returns the underlying image as an `ImageBitmap`. Note that * conversions to `ImageBitmap` are expensive, especially if the data - * currently resides on CPU. + * currently resides on CPU. If necessary, this function first converts single + * channel pixel values to RGBA by invoking a conversion function (see class + * comment for detail). * * Processing with `ImageBitmap`s requires that the MediaPipe Task was * initialized with an `OffscreenCanvas` with WebGL2 support. See * https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas/getContext * for a list of supported platforms. * + * @param type The type of image to return. + * @param converter A set of conversion functions that will be invoked to + * convert the underlying pixel data if necessary. You may omit this + * function if the requested conversion does not change the pixel format. * @return The current image as an ImageBitmap object. */ - getImage(type: MPImageStorageType.IMAGE_BITMAP): ImageBitmap; + getImage( + type: MPImageStorageType.IMAGE_BITMAP, + converter?: MPImageChannelConverter): ImageBitmap; /** * Returns the underlying image as a `WebGLTexture` object. Note that this * involves a CPU to GPU transfer if the current image is only available as * an `ImageData` object. The returned texture is bound to the current * canvas (see `.canvas`). * + * @param type The type of image to return. + * @param converter A set of conversion functions that will be invoked to + * convert the underlying pixel data if necessary. You may omit this + * function if the requested conversion does not change the pixel format. * @return The current image as a WebGLTexture. */ - getImage(type: MPImageStorageType.WEBGL_TEXTURE): WebGLTexture; - getImage(type?: MPImageStorageType): MPImageNativeContainer { + getImage( + type: MPImageStorageType.WEBGL_TEXTURE, + converter?: MPImageChannelConverter): WebGLTexture; + getImage(type?: MPImageStorageType, converter?: MPImageChannelConverter): + MPImageNativeContainer { + const internalConverter = {...DEFAULT_CONVERTER, ...converter}; switch (type) { + case MPImageStorageType.UINT8_CLAMPED_ARRAY: + return this.convertToUint8ClampedArray(internalConverter); + case MPImageStorageType.FLOAT32_ARRAY: + return this.convertToFloat32Array(internalConverter); case MPImageStorageType.IMAGE_DATA: - return this.convertToImageData(); + return this.convertToImageData(internalConverter); case MPImageStorageType.IMAGE_BITMAP: - return this.convertToImageBitmap(); + return this.convertToImageBitmap(internalConverter); case MPImageStorageType.WEBGL_TEXTURE: - return this.convertToWebGLTexture(); + return this.convertToWebGLTexture(internalConverter); default: throw new Error(`Type is not supported: ${type}`); } } + + private getContainer(type: MPImageStorageType.UINT8_CLAMPED_ARRAY): + Uint8ClampedArray|undefined; + private getContainer(type: MPImageStorageType.FLOAT32_ARRAY): Float32Array + |undefined; private getContainer(type: MPImageStorageType.IMAGE_DATA): ImageData |undefined; private getContainer(type: MPImageStorageType.IMAGE_BITMAP): ImageBitmap @@ -348,9 +515,14 @@ export class MPImage { |undefined; private getContainer(type: MPImageStorageType): MPImageNativeContainer |undefined; + /** Returns the container for the requested storage type iff it exists. */ private getContainer(type: MPImageStorageType): MPImageNativeContainer |undefined { switch (type) { + case MPImageStorageType.UINT8_CLAMPED_ARRAY: + return this.containers.find(img => img instanceof Uint8ClampedArray); + case MPImageStorageType.FLOAT32_ARRAY: + return this.containers.find(img => img instanceof Float32Array); case MPImageStorageType.IMAGE_DATA: return this.containers.find(img => img instanceof ImageData); case MPImageStorageType.IMAGE_BITMAP: @@ -377,7 +549,11 @@ export class MPImage { for (const container of this.containers) { let destinationContainer: MPImageNativeContainer; - if (container instanceof ImageData) { + if (container instanceof Uint8ClampedArray) { + destinationContainer = new Uint8ClampedArray(container); + } else if (container instanceof Float32Array) { + destinationContainer = new Float32Array(container); + } else if (container instanceof ImageData) { destinationContainer = new ImageData(container.data, this.width, this.height); } else if (container instanceof WebGLTexture) { @@ -406,7 +582,7 @@ export class MPImage { this.unbindTexture(); } else if (container instanceof ImageBitmap) { - this.convertToWebGLTexture(); + this.convertToWebGLTexture(DEFAULT_CONVERTER); this.bindTexture(); destinationContainer = this.copyTextureToBitmap(); this.unbindTexture(); @@ -423,7 +599,6 @@ export class MPImage { this.shaderContext, this.width, this.height); } - private getOffscreenCanvas(): OffscreenCanvas { if (!(this.canvas instanceof OffscreenCanvas)) { throw new Error( @@ -455,48 +630,131 @@ export class MPImage { return this.shaderContext; } - private convertToImageBitmap(): ImageBitmap { + private convertToImageBitmap(converter: Required): + ImageBitmap { let imageBitmap = this.getContainer(MPImageStorageType.IMAGE_BITMAP); if (!imageBitmap) { - this.convertToWebGLTexture(); + this.convertToWebGLTexture(converter); imageBitmap = this.convertWebGLTextureToImageBitmap(); this.containers.push(imageBitmap); this.ownsImageBitmap = true; } + return imageBitmap; } - private convertToImageData(): ImageData { + private convertToImageData(converter: Required): + ImageData { let imageData = this.getContainer(MPImageStorageType.IMAGE_DATA); if (!imageData) { - const gl = this.getGL(); - const shaderContext = this.getShaderContext(); - const pixels = new Uint8Array(this.width * this.height * 4); + if (this.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)) { + const source = + this.getContainer(MPImageStorageType.UINT8_CLAMPED_ARRAY)!; + const destination = new Uint8ClampedArray(this.width * this.height * 4); + for (let i = 0; i < this.width * this.height; i++) { + const rgba = converter.uint8ToRGBAConverter(source[i]); + destination[i * 4] = rgba[0]; + destination[i * 4 + 1] = rgba[1]; + destination[i * 4 + 2] = rgba[2]; + destination[i * 4 + 3] = rgba[3]; + } + imageData = new ImageData(destination, this.width, this.height); + this.containers.push(imageData); + } else if (this.hasType(MPImageStorageType.FLOAT32_ARRAY)) { + const source = this.getContainer(MPImageStorageType.FLOAT32_ARRAY)!; + const destination = new Uint8ClampedArray(this.width * this.height * 4); + for (let i = 0; i < this.width * this.height; i++) { + const rgba = converter.floatToRGBAConverter(source[i]); + destination[i * 4] = rgba[0]; + destination[i * 4 + 1] = rgba[1]; + destination[i * 4 + 2] = rgba[2]; + destination[i * 4 + 3] = rgba[3]; + } + imageData = new ImageData(destination, this.width, this.height); + this.containers.push(imageData); + } else if ( + this.hasType(MPImageStorageType.IMAGE_BITMAP) || + this.hasType(MPImageStorageType.WEBGL_TEXTURE)) { + const gl = this.getGL(); + const shaderContext = this.getShaderContext(); + const pixels = new Uint8Array(this.width * this.height * 4); - // Create texture if needed - const webGLTexture = this.convertToWebGLTexture(); + // Create texture if needed + const webGlTexture = this.convertToWebGLTexture(converter); - // Create a framebuffer from the texture and read back pixels - shaderContext.bindFramebuffer(gl, webGLTexture); - gl.readPixels( - 0, 0, this.width, this.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); - shaderContext.unbindFramebuffer(); + // Create a framebuffer from the texture and read back pixels + shaderContext.bindFramebuffer(gl, webGlTexture); + gl.readPixels( + 0, 0, this.width, this.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + shaderContext.unbindFramebuffer(); - imageData = new ImageData( - new Uint8ClampedArray(pixels.buffer), this.width, this.height); - this.containers.push(imageData); + imageData = new ImageData( + new Uint8ClampedArray(pixels.buffer), this.width, this.height); + this.containers.push(imageData); + } else { + throw new Error('Couldn\t find backing image for ImageData conversion'); + } } return imageData; } - private convertToWebGLTexture(): WebGLTexture { + private convertToUint8ClampedArray( + converter: Required): Uint8ClampedArray { + let uint8ClampedArray = + this.getContainer(MPImageStorageType.UINT8_CLAMPED_ARRAY); + if (!uint8ClampedArray) { + if (this.hasType(MPImageStorageType.FLOAT32_ARRAY)) { + const source = this.getContainer(MPImageStorageType.FLOAT32_ARRAY)!; + uint8ClampedArray = new Uint8ClampedArray( + source.map(v => converter.floatToUint8Converter(v))); + } else { + const source = this.convertToImageData(converter).data; + uint8ClampedArray = new Uint8ClampedArray(this.width * this.height); + for (let i = 0; i < this.width * this.height; i++) { + uint8ClampedArray[i] = converter.rgbaToUint8Converter( + source[i * 4], source[i * 4 + 1], source[i * 4 + 2], + source[i * 4 + 3]); + } + } + this.containers.push(uint8ClampedArray); + } + + return uint8ClampedArray; + } + + private convertToFloat32Array(converter: Required): + Float32Array { + let float32Array = this.getContainer(MPImageStorageType.FLOAT32_ARRAY); + if (!float32Array) { + if (this.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)) { + const source = + this.getContainer(MPImageStorageType.UINT8_CLAMPED_ARRAY)!; + float32Array = new Float32Array(source).map( + v => converter.uint8ToFloatConverter(v)); + } else { + const source = this.convertToImageData(converter).data; + float32Array = new Float32Array(this.width * this.height); + for (let i = 0; i < this.width * this.height; i++) { + float32Array[i] = converter.rgbaToFloatConverter( + source[i * 4], source[i * 4 + 1], source[i * 4 + 2], + source[i * 4 + 3]); + } + } + this.containers.push(float32Array); + } + + return float32Array; + } + + private convertToWebGLTexture(converter: Required): + WebGLTexture { let webGLTexture = this.getContainer(MPImageStorageType.WEBGL_TEXTURE); if (!webGLTexture) { const gl = this.getGL(); webGLTexture = this.bindTexture(); const source = this.getContainer(MPImageStorageType.IMAGE_BITMAP) || - this.convertToImageData(); + this.convertToImageData(converter); gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source); this.unbindTexture(); From 82b8e4d7bfd06e0f724bc3dd21827a784e86c258 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 27 Apr 2023 11:35:01 -0700 Subject: [PATCH 121/753] Update the face stylizer config to match the latest encoder and detector config. PiperOrigin-RevId: 527637477 --- .../python/vision/face_stylizer/face_stylizer.py | 2 +- .../vision/face_stylizer/hyperparameters.py | 2 +- .../python/vision/face_stylizer/model_options.py | 15 +++++++++------ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py index 3e850582f..0c8097f14 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py @@ -178,7 +178,7 @@ class FaceStylizer(object): with tf.GradientTape() as tape: outputs = self._decoder( {'inputs': in_latent + self.w_avg}, - training=False, + training=True, ) gen_img = outputs['image'][-1] diff --git a/mediapipe/model_maker/python/vision/face_stylizer/hyperparameters.py b/mediapipe/model_maker/python/vision/face_stylizer/hyperparameters.py index f48a916b0..6a2999a41 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/hyperparameters.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/hyperparameters.py @@ -31,7 +31,7 @@ class HParams(hp.BaseHParams): """ # Parameters from BaseHParams class. - learning_rate: float = 5e-5 + learning_rate: float = 8e-4 batch_size: int = 4 epochs: int = 100 # Parameters for face stylizer. diff --git a/mediapipe/model_maker/python/vision/face_stylizer/model_options.py b/mediapipe/model_maker/python/vision/face_stylizer/model_options.py index 9b3f7beef..f63d4b962 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/model_options.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/model_options.py @@ -21,7 +21,7 @@ from mediapipe.model_maker.python.core.utils import loss_functions def _default_perceptual_quality_loss_weight(): """Default perceptual quality loss weight for face stylizer.""" - return loss_functions.PerceptualLossWeight(l1=2.0, content=20.0, style=10.0) + return loss_functions.PerceptualLossWeight(l1=0.5, content=4.0, style=1.0) # TODO: Add more detailed instructions about hyperparameter tuning. @@ -32,18 +32,21 @@ class FaceStylizerModelOptions: Attributes: swap_layers: The layers of feature to be interpolated between encoding features and StyleGAN input features. - alpha: Weighting coefficient for swapping layer interpolation. + alpha: Weighting coefficient of style latent for swapping layer + interpolation. Its valid range is [0, 1]. The greater weight means + stronger style is applied to the output image. Expect to set it to a small + value, i.e. < 0.1. perception_loss_weight: Weighting coefficients of image perception quality loss. adv_loss_weight: Weighting coeffcieint of adversarial loss versus image - perceptual quality loss. + perceptual quality loss. It expects a small value, i.e. < 0.2. """ swap_layers: Sequence[int] = dataclasses.field( - default_factory=lambda: [4, 5, 6, 7, 8, 9, 10, 11] + default_factory=lambda: [4, 5, 10, 11] ) - alpha: float = 1.0 + alpha: float = 0.1 perception_loss_weight: loss_functions.PerceptualLossWeight = ( dataclasses.field(default_factory=_default_perceptual_quality_loss_weight) ) - adv_loss_weight: float = 1.0 + adv_loss_weight: float = 0.2 From 3ca2427cc8e7d1737cbdd561b060b0ccc478e0a6 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 27 Apr 2023 11:43:58 -0700 Subject: [PATCH 122/753] Blendshapes graph take smoothed face landmarks as input. PiperOrigin-RevId: 527640341 --- .../tasks/cc/vision/face_landmarker/BUILD | 6 +- .../face_landmarker/face_landmarker_graph.cc | 59 ++--- .../face_landmarks_detector_graph.cc | 221 +++++++++++------- .../face_landmarks_detector_graph_test.cc | 72 +----- ...ace_landmarks_detector_graph_options.proto | 7 + 5 files changed, 178 insertions(+), 187 deletions(-) diff --git a/mediapipe/tasks/cc/vision/face_landmarker/BUILD b/mediapipe/tasks/cc/vision/face_landmarker/BUILD index 1287ef223..e4756aab1 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/BUILD +++ b/mediapipe/tasks/cc/vision/face_landmarker/BUILD @@ -73,6 +73,8 @@ cc_library( ":tensors_to_face_landmarks_graph", "//mediapipe/calculators/core:begin_loop_calculator", "//mediapipe/calculators/core:end_loop_calculator", + "//mediapipe/calculators/core:get_vector_item_calculator", + "//mediapipe/calculators/core:get_vector_item_calculator_cc_proto", "//mediapipe/calculators/core:split_vector_calculator", "//mediapipe/calculators/core:split_vector_calculator_cc_proto", "//mediapipe/calculators/image:image_properties_calculator", @@ -86,6 +88,8 @@ cc_library( "//mediapipe/calculators/util:detections_to_rects_calculator_cc_proto", "//mediapipe/calculators/util:landmark_letterbox_removal_calculator", "//mediapipe/calculators/util:landmark_projection_calculator", + "//mediapipe/calculators/util:landmarks_smoothing_calculator", + "//mediapipe/calculators/util:landmarks_smoothing_calculator_cc_proto", "//mediapipe/calculators/util:landmarks_to_detection_calculator", "//mediapipe/calculators/util:rect_transformation_calculator", "//mediapipe/calculators/util:rect_transformation_calculator_cc_proto", @@ -194,8 +198,6 @@ cc_library( "//mediapipe/calculators/util:association_norm_rect_calculator", "//mediapipe/calculators/util:collection_has_min_size_calculator", "//mediapipe/calculators/util:collection_has_min_size_calculator_cc_proto", - "//mediapipe/calculators/util:landmarks_smoothing_calculator", - "//mediapipe/calculators/util:landmarks_smoothing_calculator_cc_proto", "//mediapipe/framework/api2:builder", "//mediapipe/framework/api2:port", "//mediapipe/framework/formats:classification_cc_proto", diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_graph.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_graph.cc index 0515e78bd..0f9caec0d 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_graph.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarker_graph.cc @@ -26,7 +26,6 @@ limitations under the License. #include "mediapipe/calculators/core/get_vector_item_calculator.pb.h" #include "mediapipe/calculators/util/association_calculator.pb.h" #include "mediapipe/calculators/util/collection_has_min_size_calculator.pb.h" -#include "mediapipe/calculators/util/landmarks_smoothing_calculator.pb.h" #include "mediapipe/framework/api2/builder.h" #include "mediapipe/framework/api2/port.h" #include "mediapipe/framework/formats/classification.pb.h" @@ -172,19 +171,6 @@ absl::Status SetSubTaskBaseOptions(const ModelAssetBundleResources& resources, return absl::OkStatus(); } - -void ConfigureLandmarksSmoothingCalculator( - mediapipe::LandmarksSmoothingCalculatorOptions& options) { - // Min cutoff 0.05 results into ~0.01 alpha in landmark EMA filter when - // landmark is static. - options.mutable_one_euro_filter()->set_min_cutoff(0.05f); - // Beta 80.0 in combintation with min_cutoff 0.05 results into ~0.94 - // alpha in landmark EMA filter when landmark is moving fast. - options.mutable_one_euro_filter()->set_beta(80.0f); - // Derivative cutoff 1.0 results into ~0.17 alpha in landmark velocity - // EMA filter. - options.mutable_one_euro_filter()->set_derivate_cutoff(1.0f); -} } // namespace // A "mediapipe.tasks.vision.face_landmarker.FaceLandmarkerGraph" performs face @@ -464,32 +450,17 @@ class FaceLandmarkerGraph : public core::ModelTaskGraph { auto image_size = image_properties.Out(kSizeTag); // Apply smoothing filter only on the single face landmarks, because - // landmakrs smoothing calculator doesn't support multiple landmarks yet. + // landmarks smoothing calculator doesn't support multiple landmarks yet. if (face_detector_options.num_faces() == 1) { - // Get the single face landmarks - auto& get_vector_item = - graph.AddNode("GetNormalizedLandmarkListVectorItemCalculator"); - get_vector_item.GetOptions() - .set_item_index(0); - face_landmarks >> get_vector_item.In(kVectorTag); - auto single_face_landmarks = get_vector_item.Out(kItemTag); - - // Apply smoothing filter on face landmarks. - auto& landmarks_smoothing = graph.AddNode("LandmarksSmoothingCalculator"); - ConfigureLandmarksSmoothingCalculator( - landmarks_smoothing - .GetOptions()); - single_face_landmarks >> landmarks_smoothing.In(kNormLandmarksTag); - image_size >> landmarks_smoothing.In(kImageSizeTag); - auto smoothed_single_face_landmarks = - landmarks_smoothing.Out(kNormFilteredLandmarksTag); - - // Wrap the single face landmarks into a vector of landmarks. - auto& concatenate_vector = - graph.AddNode("ConcatenateNormalizedLandmarkListVectorCalculator"); - smoothed_single_face_landmarks >> concatenate_vector.In(""); - face_landmarks = concatenate_vector.Out("") - .Cast>(); + face_landmarks_detector_graph + .GetOptions() + .set_smooth_landmarks(true); + } else if (face_detector_options.num_faces() > 1 && + face_landmarks_detector_graph + .GetOptions() + .smooth_landmarks()) { + return absl::InvalidArgumentError( + "Currently face landmarks smoothing only support a single face."); } if (tasks_options.base_options().use_stream_mode()) { @@ -533,9 +504,10 @@ class FaceLandmarkerGraph : public core::ModelTaskGraph { // Back edge. face_rects_for_next_frame >> previous_loopback.In(kLoopTag); } else { - // While not in stream mode, the input images are not guaranteed to be in - // series, and we don't want to enable the tracking and rect associations - // between input images. Always use the face detector graph. + // While not in stream mode, the input images are not guaranteed to be + // in series, and we don't want to enable the tracking and rect + // associations between input images. Always use the face detector + // graph. image_in >> face_detector.In(kImageTag); if (norm_rect_in) { *norm_rect_in >> face_detector.In(kNormRectTag); @@ -571,7 +543,8 @@ class FaceLandmarkerGraph : public core::ModelTaskGraph { } // TODO: Replace PassThroughCalculator with a calculator that - // converts the pixel data to be stored on the target storage (CPU vs GPU). + // converts the pixel data to be stored on the target storage (CPU vs + // GPU). auto& pass_through = graph.AddNode("PassThroughCalculator"); image_in >> pass_through.In(""); diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph.cc index 8f518217f..20d241b97 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph.cc @@ -19,10 +19,13 @@ limitations under the License. #include #include +#include "mediapipe/calculators/core/get_vector_item_calculator.h" +#include "mediapipe/calculators/core/get_vector_item_calculator.pb.h" #include "mediapipe/calculators/core/split_vector_calculator.pb.h" #include "mediapipe/calculators/tensor/tensors_to_floats_calculator.pb.h" #include "mediapipe/calculators/tensor/tensors_to_landmarks_calculator.pb.h" #include "mediapipe/calculators/util/detections_to_rects_calculator.pb.h" +#include "mediapipe/calculators/util/landmarks_smoothing_calculator.pb.h" #include "mediapipe/calculators/util/rect_transformation_calculator.pb.h" #include "mediapipe/calculators/util/thresholding_calculator.pb.h" #include "mediapipe/framework/api2/builder.h" @@ -79,6 +82,9 @@ constexpr char kBatchEndTag[] = "BATCH_END"; constexpr char kItemTag[] = "ITEM"; constexpr char kDetectionTag[] = "DETECTION"; constexpr char kBlendshapesTag[] = "BLENDSHAPES"; +constexpr char kNormFilteredLandmarksTag[] = "NORM_FILTERED_LANDMARKS"; +constexpr char kSizeTag[] = "SIZE"; +constexpr char kVectorTag[] = "VECTOR"; // a landmarks tensor and a scores tensor constexpr int kFaceLandmarksOutputTensorsNum = 2; @@ -88,7 +94,6 @@ struct SingleFaceLandmarksOutputs { Stream rect_next_frame; Stream presence; Stream presence_score; - std::optional> face_blendshapes; }; struct MultiFaceLandmarksOutputs { @@ -148,6 +153,19 @@ void ConfigureFaceRectTransformationCalculator( options->set_square_long(true); } +void ConfigureLandmarksSmoothingCalculator( + mediapipe::LandmarksSmoothingCalculatorOptions& options) { + // Min cutoff 0.05 results into ~0.01 alpha in landmark EMA filter when + // landmark is static. + options.mutable_one_euro_filter()->set_min_cutoff(0.05f); + // Beta 80.0 in combintation with min_cutoff 0.05 results into ~0.94 + // alpha in landmark EMA filter when landmark is moving fast. + options.mutable_one_euro_filter()->set_beta(80.0f); + // Derivative cutoff 1.0 results into ~0.17 alpha in landmark velocity + // EMA filter. + options.mutable_one_euro_filter()->set_derivate_cutoff(1.0f); +} + } // namespace // A "mediapipe.tasks.vision.face_landmarker.SingleFaceLandmarksDetectorGraph" @@ -171,62 +189,6 @@ void ConfigureFaceRectTransformationCalculator( // Boolean value indicates whether the face is present. // PRESENCE_SCORE - float // Float value indicates the probability that the face is present. -// BLENDSHAPES - ClassificationList @optional -// Blendshape classification, available when face_blendshapes_graph_options -// is set. -// All 52 blendshape coefficients: -// 0 - _neutral (ignore it) -// 1 - browDownLeft -// 2 - browDownRight -// 3 - browInnerUp -// 4 - browOuterUpLeft -// 5 - browOuterUpRight -// 6 - cheekPuff -// 7 - cheekSquintLeft -// 8 - cheekSquintRight -// 9 - eyeBlinkLeft -// 10 - eyeBlinkRight -// 11 - eyeLookDownLeft -// 12 - eyeLookDownRight -// 13 - eyeLookInLeft -// 14 - eyeLookInRight -// 15 - eyeLookOutLeft -// 16 - eyeLookOutRight -// 17 - eyeLookUpLeft -// 18 - eyeLookUpRight -// 19 - eyeSquintLeft -// 20 - eyeSquintRight -// 21 - eyeWideLeft -// 22 - eyeWideRight -// 23 - jawForward -// 24 - jawLeft -// 25 - jawOpen -// 26 - jawRight -// 27 - mouthClose -// 28 - mouthDimpleLeft -// 29 - mouthDimpleRight -// 30 - mouthFrownLeft -// 31 - mouthFrownRight -// 32 - mouthFunnel -// 33 - mouthLeft -// 34 - mouthLowerDownLeft -// 35 - mouthLowerDownRight -// 36 - mouthPressLeft -// 37 - mouthPressRight -// 38 - mouthPucker -// 39 - mouthRight -// 40 - mouthRollLower -// 41 - mouthRollUpper -// 42 - mouthShrugLower -// 43 - mouthShrugUpper -// 44 - mouthSmileLeft -// 45 - mouthSmileRight -// 46 - mouthStretchLeft -// 47 - mouthStretchRight -// 48 - mouthUpperUpLeft -// 49 - mouthUpperUpRight -// 50 - noseSneerLeft -// 51 - noseSneerRight // // Example: // node { @@ -238,7 +200,6 @@ void ConfigureFaceRectTransformationCalculator( // output_stream: "FACE_RECT_NEXT_FRAME:face_rect_next_frame" // output_stream: "PRESENCE:presence" // output_stream: "PRESENCE_SCORE:presence_score" -// output_stream: "BLENDSHAPES:blendshapes" // options { // [mediapipe.tasks.vision.face_landmarker.proto.FaceLandmarksDetectorGraphOptions.ext] // { @@ -278,10 +239,6 @@ class SingleFaceLandmarksDetectorGraph : public core::ModelTaskGraph { graph.Out(kFaceRectNextFrameTag).Cast(); outs.presence >> graph.Out(kPresenceTag).Cast(); outs.presence_score >> graph.Out(kPresenceScoreTag).Cast(); - if (outs.face_blendshapes) { - outs.face_blendshapes.value() >> - graph.Out(kBlendshapesTag).Cast(); - } return graph.GetConfig(); } @@ -378,7 +335,7 @@ class SingleFaceLandmarksDetectorGraph : public core::ModelTaskGraph { auto& landmark_projection = graph.AddNode("LandmarkProjectionCalculator"); landmarks_letterbox_removed >> landmark_projection.In(kNormLandmarksTag); face_rect >> landmark_projection.In(kNormRectTag); - auto projected_landmarks = AllowIf( + Stream projected_landmarks = AllowIf( landmark_projection[Output(kNormLandmarksTag)], presence, graph); @@ -409,25 +366,11 @@ class SingleFaceLandmarksDetectorGraph : public core::ModelTaskGraph { AllowIf(face_rect_transformation.Out("").Cast(), presence, graph); - std::optional> face_blendshapes; - if (subgraph_options.has_face_blendshapes_graph_options()) { - auto& face_blendshapes_graph = graph.AddNode( - "mediapipe.tasks.vision.face_landmarker.FaceBlendshapesGraph"); - face_blendshapes_graph.GetOptions() - .Swap(subgraph_options.mutable_face_blendshapes_graph_options()); - projected_landmarks >> face_blendshapes_graph.In(kLandmarksTag); - image_size >> face_blendshapes_graph.In(kImageSizeTag); - face_blendshapes = - std::make_optional(face_blendshapes_graph.Out(kBlendshapesTag) - .Cast()); - } - return {{ /* landmarks= */ projected_landmarks, /* rect_next_frame= */ face_rect_next_frame, /* presence= */ presence, /* presence_score= */ presence_score, - /* face_blendshapes= */ face_blendshapes, }}; } }; @@ -465,6 +408,59 @@ REGISTER_MEDIAPIPE_GRAPH( // BLENDSHAPES - std::vector @optional // Vector of face blendshape classification, available when // face_blendshapes_graph_options is set. +// All 52 blendshape coefficients: +// 0 - _neutral (ignore it) +// 1 - browDownLeft +// 2 - browDownRight +// 3 - browInnerUp +// 4 - browOuterUpLeft +// 5 - browOuterUpRight +// 6 - cheekPuff +// 7 - cheekSquintLeft +// 8 - cheekSquintRight +// 9 - eyeBlinkLeft +// 10 - eyeBlinkRight +// 11 - eyeLookDownLeft +// 12 - eyeLookDownRight +// 13 - eyeLookInLeft +// 14 - eyeLookInRight +// 15 - eyeLookOutLeft +// 16 - eyeLookOutRight +// 17 - eyeLookUpLeft +// 18 - eyeLookUpRight +// 19 - eyeSquintLeft +// 20 - eyeSquintRight +// 21 - eyeWideLeft +// 22 - eyeWideRight +// 23 - jawForward +// 24 - jawLeft +// 25 - jawOpen +// 26 - jawRight +// 27 - mouthClose +// 28 - mouthDimpleLeft +// 29 - mouthDimpleRight +// 30 - mouthFrownLeft +// 31 - mouthFrownRight +// 32 - mouthFunnel +// 33 - mouthLeft +// 34 - mouthLowerDownLeft +// 35 - mouthLowerDownRight +// 36 - mouthPressLeft +// 37 - mouthPressRight +// 38 - mouthPucker +// 39 - mouthRight +// 40 - mouthRollLower +// 41 - mouthRollUpper +// 42 - mouthShrugLower +// 43 - mouthShrugUpper +// 44 - mouthSmileLeft +// 45 - mouthSmileRight +// 46 - mouthStretchLeft +// 47 - mouthStretchRight +// 48 - mouthUpperUpLeft +// 49 - mouthUpperUpRight +// 50 - noseSneerLeft +// 51 - noseSneerRight // // Example: // node { @@ -566,8 +562,9 @@ class MultiFaceLandmarksDetectorGraph : public core::ModelTaskGraph { graph.AddNode("EndLoopNormalizedLandmarkListVectorCalculator"); batch_end >> end_loop_landmarks.In(kBatchEndTag); landmarks >> end_loop_landmarks.In(kItemTag); - auto landmark_lists = end_loop_landmarks.Out(kIterableTag) - .Cast>(); + Stream> landmark_lists = + end_loop_landmarks.Out(kIterableTag) + .Cast>(); auto& end_loop_rects_next_frame = graph.AddNode("EndLoopNormalizedRectCalculator"); @@ -576,16 +573,78 @@ class MultiFaceLandmarksDetectorGraph : public core::ModelTaskGraph { auto face_rects_next_frame = end_loop_rects_next_frame.Out(kIterableTag) .Cast>(); + // Apply smoothing filter only on the single face landmarks, because + // landmarks smoothing calculator doesn't support multiple landmarks yet. + // Notice the landmarks smoothing calculator cannot be put inside the for + // loop calculator, because the smoothing calculator utilize the timestamp + // to smoote landmarks across frames but the for loop calculator makes fake + // timestamps for the streams. + if (face_landmark_subgraph + .GetOptions() + .smooth_landmarks()) { + // Get the single face landmarks + auto& get_vector_item = + graph.AddNode("GetNormalizedLandmarkListVectorItemCalculator"); + get_vector_item.GetOptions() + .set_item_index(0); + landmark_lists >> get_vector_item.In(kVectorTag); + Stream single_landmarks = + get_vector_item.Out(kItemTag).Cast(); + + auto& image_properties = graph.AddNode("ImagePropertiesCalculator"); + image_in >> image_properties.In(kImageTag); + auto image_size = image_properties.Out(kSizeTag); + + // Apply smoothing filter on face landmarks. + auto& landmarks_smoothing = graph.AddNode("LandmarksSmoothingCalculator"); + ConfigureLandmarksSmoothingCalculator( + landmarks_smoothing + .GetOptions()); + single_landmarks >> landmarks_smoothing.In(kNormLandmarksTag); + image_size >> landmarks_smoothing.In(kImageSizeTag); + single_landmarks = landmarks_smoothing.Out(kNormFilteredLandmarksTag) + .Cast(); + + // Wrap the single face landmarks into a vector of landmarks. + auto& concatenate_vector = + graph.AddNode("ConcatenateNormalizedLandmarkListVectorCalculator"); + single_landmarks >> concatenate_vector.In(""); + landmark_lists = concatenate_vector.Out("") + .Cast>(); + } + std::optional>> face_blendshapes_vector; if (face_landmark_subgraph .GetOptions() .has_face_blendshapes_graph_options()) { - auto blendshapes = face_landmark_subgraph.Out(kBlendshapesTag); + auto& begin_loop_multi_face_landmarks = + graph.AddNode("BeginLoopNormalizedLandmarkListVectorCalculator"); + landmark_lists >> begin_loop_multi_face_landmarks.In(kIterableTag); + image_in >> begin_loop_multi_face_landmarks.In(kCloneTag); + auto image = begin_loop_multi_face_landmarks.Out(kCloneTag); + auto batch_end = begin_loop_multi_face_landmarks.Out(kBatchEndTag); + auto landmarks = begin_loop_multi_face_landmarks.Out(kItemTag); + + auto& image_properties = graph.AddNode("ImagePropertiesCalculator"); + image >> image_properties.In(kImageTag); + auto image_size = image_properties.Out(kSizeTag); + + auto& face_blendshapes_graph = graph.AddNode( + "mediapipe.tasks.vision.face_landmarker.FaceBlendshapesGraph"); + face_blendshapes_graph.GetOptions() + .Swap(face_landmark_subgraph + .GetOptions() + .mutable_face_blendshapes_graph_options()); + landmarks >> face_blendshapes_graph.In(kLandmarksTag); + image_size >> face_blendshapes_graph.In(kImageSizeTag); + auto face_blendshapes = face_blendshapes_graph.Out(kBlendshapesTag) + .Cast(); + auto& end_loop_blendshapes = graph.AddNode("EndLoopClassificationListCalculator"); batch_end >> end_loop_blendshapes.In(kBatchEndTag); - blendshapes >> end_loop_blendshapes.In(kItemTag); + face_blendshapes >> end_loop_blendshapes.In(kItemTag); face_blendshapes_vector = std::make_optional(end_loop_blendshapes.Out(kIterableTag) .Cast>()); diff --git a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph_test.cc b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph_test.cc index c498934f2..affa7bedd 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph_test.cc +++ b/mediapipe/tasks/cc/vision/face_landmarker/face_landmarks_detector_graph_test.cc @@ -99,8 +99,7 @@ constexpr float kBlendshapesDiffMargin = 0.1; // Helper function to create a Single Face Landmark TaskRunner. absl::StatusOr> CreateSingleFaceLandmarksTaskRunner( - absl::string_view landmarks_model_name, - std::optional blendshapes_model_name) { + absl::string_view landmarks_model_name) { Graph graph; auto& face_landmark_detection = graph.AddNode( @@ -112,14 +111,6 @@ absl::StatusOr> CreateSingleFaceLandmarksTaskRunner( JoinPath("./", kTestDataDirectory, landmarks_model_name)); options->set_min_detection_confidence(0.5); - if (blendshapes_model_name.has_value()) { - options->mutable_face_blendshapes_graph_options() - ->mutable_base_options() - ->mutable_model_asset() - ->set_file_name( - JoinPath("./", kTestDataDirectory, *blendshapes_model_name)); - } - face_landmark_detection.GetOptions() .Swap(options.get()); @@ -137,11 +128,6 @@ absl::StatusOr> CreateSingleFaceLandmarksTaskRunner( face_landmark_detection.Out(kFaceRectNextFrameTag) .SetName(kFaceRectNextFrameName) >> graph[Output(kFaceRectNextFrameTag)]; - if (blendshapes_model_name.has_value()) { - face_landmark_detection.Out(kBlendshapesTag).SetName(kBlendshapesName) >> - graph[Output(kBlendshapesTag)]; - } - return TaskRunner::Create( graph.GetConfig(), absl::make_unique()); } @@ -227,8 +213,6 @@ struct SingeFaceTestParams { std::string test_name; // The filename of landmarks model name. std::string landmarks_model_name; - // The filename of blendshape model name. - std::optional blendshape_model_name; // The filename of the test image. std::string test_image_name; // RoI on image to detect faces. @@ -237,13 +221,8 @@ struct SingeFaceTestParams { bool expected_presence; // The expected output landmarks positions. NormalizedLandmarkList expected_landmarks; - // The expected output blendshape classification; - std::optional expected_blendshapes; // The max value difference between expected_positions and detected positions. float landmarks_diff_threshold; - // The max value difference between expected blendshapes and actual - // blendshapes. - float blendshapes_diff_threshold; }; struct MultiFaceTestParams { @@ -279,8 +258,7 @@ TEST_P(SingleFaceLandmarksDetectionTest, Succeeds) { GetParam().test_image_name))); MP_ASSERT_OK_AND_ASSIGN( auto task_runner, - CreateSingleFaceLandmarksTaskRunner(GetParam().landmarks_model_name, - GetParam().blendshape_model_name)); + CreateSingleFaceLandmarksTaskRunner(GetParam().landmarks_model_name)); auto output_packets = task_runner->Process( {{kImageName, MakePacket(std::move(image))}, @@ -301,15 +279,6 @@ TEST_P(SingleFaceLandmarksDetectionTest, Succeeds) { Approximately(Partially(EqualsProto(expected_landmarks)), /*margin=*/kAbsMargin, /*fraction=*/GetParam().landmarks_diff_threshold)); - if (GetParam().expected_blendshapes) { - const ClassificationList& actual_blendshapes = - (*output_packets)[kBlendshapesName].Get(); - const ClassificationList& expected_blendshapes = - *GetParam().expected_blendshapes; - EXPECT_THAT(actual_blendshapes, - Approximately(EqualsProto(expected_blendshapes), - GetParam().blendshapes_diff_threshold)); - } } } @@ -360,34 +329,15 @@ TEST_P(MultiFaceLandmarksDetectionTest, Succeeds) { INSTANTIATE_TEST_SUITE_P( FaceLandmarksDetectionTest, SingleFaceLandmarksDetectionTest, Values(SingeFaceTestParams{ - /* test_name= */ "PortraitV2", - /* landmarks_model_name= */ - kFaceLandmarksV2Model, - /* blendshape_model_name= */ std::nullopt, - /* test_image_name= */ kPortraitImageName, - /* norm_rect= */ MakeNormRect(0.4987, 0.2211, 0.2877, 0.2303, 0), - /* expected_presence= */ true, - /* expected_landmarks= */ - GetExpectedLandmarkList(kPortraitExpectedFaceLandmarksName), - /* expected_blendshapes= */ std::nullopt, - /* landmarks_diff_threshold= */ kFractionDiff, - /* blendshapes_diff_threshold= */ kBlendshapesDiffMargin}, - SingeFaceTestParams{ - /* test_name= */ "PortraitV2WithBlendshapes", - /* landmarks_model_name= */ - kFaceLandmarksV2Model, - /* blendshape_model_name= */ kFaceBlendshapesModel, - /* test_image_name= */ kPortraitImageName, - /* norm_rect= */ - MakeNormRect(0.48906386, 0.22731927, 0.42905223, 0.34357703, - 0.008304443), - /* expected_presence= */ true, - /* expected_landmarks= */ - GetExpectedLandmarkList(kPortraitExpectedFaceLandmarksName), - /* expected_blendshapes= */ - GetBlendshapes(kPortraitExpectedBlendshapesName), - /* landmarks_diff_threshold= */ kFractionDiff, - /* blendshapes_diff_threshold= */ kBlendshapesDiffMargin}), + /* test_name= */ "PortraitV2", + /* landmarks_model_name= */ + kFaceLandmarksV2Model, + /* test_image_name= */ kPortraitImageName, + /* norm_rect= */ MakeNormRect(0.4987, 0.2211, 0.2877, 0.2303, 0), + /* expected_presence= */ true, + /* expected_landmarks= */ + GetExpectedLandmarkList(kPortraitExpectedFaceLandmarksName), + /* landmarks_diff_threshold= */ kFractionDiff}), [](const TestParamInfo& info) { return info.param.test_name; diff --git a/mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarks_detector_graph_options.proto b/mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarks_detector_graph_options.proto index 23a541a31..32e3636df 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarks_detector_graph_options.proto +++ b/mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarks_detector_graph_options.proto @@ -37,6 +37,13 @@ message FaceLandmarksDetectorGraphOptions { // successfully detecting a face in the image. optional float min_detection_confidence = 2 [default = 0.5]; + // Whether to smooth the detected landmarks over timestamps. Note that + // landmarks smoothing is only applicable for a single face. If multiple faces + // landmarks are given, and smooth_landmarks is true, only the first face + // landmarks would be smoothed, and the remaining landmarks are discarded in + // the returned landmarks list. + optional bool smooth_landmarks = 4; + // Optional options for FaceBlendshapeGraph. If this options is set, the // FaceLandmarksDetectorGraph would output the face blendshapes. optional FaceBlendshapesGraphOptions face_blendshapes_graph_options = 3; From 212f110c65818db7f2d08c42a9539ecb2b6c0e1d Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 27 Apr 2023 11:58:17 -0700 Subject: [PATCH 123/753] Add nose in facemesh drawing PiperOrigin-RevId: 527644154 --- mediapipe/python/solutions/drawing_styles.py | 30 ++++++++++++++++++- mediapipe/python/solutions/face_mesh.py | 1 + .../python/solutions/face_mesh_connections.py | 7 +++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/mediapipe/python/solutions/drawing_styles.py b/mediapipe/python/solutions/drawing_styles.py index 5d75d5b30..a4c39b37f 100644 --- a/mediapipe/python/solutions/drawing_styles.py +++ b/mediapipe/python/solutions/drawing_styles.py @@ -30,6 +30,8 @@ _GRAY = (128, 128, 128) _PURPLE = (128, 64, 128) _PEACH = (180, 229, 255) _WHITE = (224, 224, 224) +_CYAN = (192, 255, 48) +_MAGENTA = (192, 48, 255) # Hands _THICKNESS_WRIST_MCP = 3 @@ -109,6 +111,23 @@ _FACEMESH_CONTOURS_CONNECTION_STYLE = { DrawingSpec(color=_WHITE, thickness=_THICKNESS_CONTOURS) } +_FACEMESH_CONTOURS_CONNECTION_STYLE_1 = { + face_mesh_connections.FACEMESH_LIPS: + DrawingSpec(color=_BLUE, thickness=_THICKNESS_CONTOURS), + face_mesh_connections.FACEMESH_LEFT_EYE: + DrawingSpec(color=_CYAN, thickness=_THICKNESS_CONTOURS), + face_mesh_connections.FACEMESH_LEFT_EYEBROW: + DrawingSpec(color=_GREEN, thickness=_THICKNESS_CONTOURS), + face_mesh_connections.FACEMESH_RIGHT_EYE: + DrawingSpec(color=_MAGENTA, thickness=_THICKNESS_CONTOURS), + face_mesh_connections.FACEMESH_RIGHT_EYEBROW: + DrawingSpec(color=_RED, thickness=_THICKNESS_CONTOURS), + face_mesh_connections.FACEMESH_FACE_OVAL: + DrawingSpec(color=_WHITE, thickness=_THICKNESS_CONTOURS), + face_mesh_connections.FACEMESH_NOSE: + DrawingSpec(color=_YELLOW, thickness=_THICKNESS_CONTOURS) +} + # Pose _THICKNESS_POSE_LANDMARKS = 2 _POSE_LANDMARKS_LEFT = frozenset([ @@ -161,15 +180,24 @@ def get_default_hand_connections_style( def get_default_face_mesh_contours_style( + i: int = 0, ) -> Mapping[Tuple[int, int], DrawingSpec]: """Returns the default face mesh contours drawing style. + Args: + i: The id for default style. Currently there are two default styles. + Returns: A mapping from each face mesh contours connection to its default drawing spec. """ + default_style = ( + _FACEMESH_CONTOURS_CONNECTION_STYLE_1 + if i == 1 + else _FACEMESH_CONTOURS_CONNECTION_STYLE + ) face_mesh_contours_connection_style = {} - for k, v in _FACEMESH_CONTOURS_CONNECTION_STYLE.items(): + for k, v in default_style.items(): for connection in k: face_mesh_contours_connection_style[connection] = v return face_mesh_contours_connection_style diff --git a/mediapipe/python/solutions/face_mesh.py b/mediapipe/python/solutions/face_mesh.py index 997c0661d..e56122191 100644 --- a/mediapipe/python/solutions/face_mesh.py +++ b/mediapipe/python/solutions/face_mesh.py @@ -45,6 +45,7 @@ from mediapipe.python.solutions.face_mesh_connections import FACEMESH_LEFT_EYE from mediapipe.python.solutions.face_mesh_connections import FACEMESH_LEFT_EYEBROW from mediapipe.python.solutions.face_mesh_connections import FACEMESH_LEFT_IRIS from mediapipe.python.solutions.face_mesh_connections import FACEMESH_LIPS +from mediapipe.python.solutions.face_mesh_connections import FACEMESH_NOSE from mediapipe.python.solutions.face_mesh_connections import FACEMESH_RIGHT_EYE from mediapipe.python.solutions.face_mesh_connections import FACEMESH_RIGHT_EYEBROW from mediapipe.python.solutions.face_mesh_connections import FACEMESH_RIGHT_IRIS diff --git a/mediapipe/python/solutions/face_mesh_connections.py b/mediapipe/python/solutions/face_mesh_connections.py index 1ebd541df..d44fb79be 100644 --- a/mediapipe/python/solutions/face_mesh_connections.py +++ b/mediapipe/python/solutions/face_mesh_connections.py @@ -57,6 +57,13 @@ FACEMESH_FACE_OVAL = frozenset([(10, 338), (338, 297), (297, 332), (332, 284), (234, 127), (127, 162), (162, 21), (21, 54), (54, 103), (103, 67), (67, 109), (109, 10)]) +FACEMESH_NOSE = frozenset([(168, 6), (6, 197), (197, 195), (195, 5), + (5, 4), (4, 1), (1, 19), (19, 94), (94, 2), (98, 97), + (97, 2), (2, 326), (326, 327), (327, 294), + (294, 278), (278, 344), (344, 440), (440, 275), + (275, 4), (4, 45), (45, 220), (220, 115), (115, 48), + (48, 64), (64, 98)]) + FACEMESH_CONTOURS = frozenset().union(*[ FACEMESH_LIPS, FACEMESH_LEFT_EYE, FACEMESH_LEFT_EYEBROW, FACEMESH_RIGHT_EYE, FACEMESH_RIGHT_EYEBROW, FACEMESH_FACE_OVAL From 4e1270c18f3f110cf4d453adc72dc77530fa4336 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 27 Apr 2023 14:13:05 -0700 Subject: [PATCH 124/753] Internal PiperOrigin-RevId: 527680530 --- third_party/external_files.bzl | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/third_party/external_files.bzl b/third_party/external_files.bzl index e8ff7819c..a57664e09 100644 --- a/third_party/external_files.bzl +++ b/third_party/external_files.bzl @@ -276,8 +276,8 @@ def external_files(): http_file( name = "com_google_mediapipe_efficientdet_lite0_fp16_no_nms_tflite", - sha256 = "237a58389081333e5cf4154e42b593ce7dd357445536fcaf4ca5bc51c2c50f1c", - urls = ["https://storage.googleapis.com/mediapipe-assets/efficientdet_lite0_fp16_no_nms.tflite?generation=1682476299542472"], + sha256 = "bcda125c96d3767bca894c8cbe7bc458379c9974c9fd8bdc6204e7124a74082a", + urls = ["https://storage.googleapis.com/mediapipe-assets/efficientdet_lite0_fp16_no_nms.tflite?generation=1682627837744424"], ) http_file( @@ -328,12 +328,6 @@ def external_files(): urls = ["https://storage.googleapis.com/mediapipe-assets/expected_pose_landmarks.prototxt?generation=16812442325229901681244235071100"], ) - http_file( - name = "com_google_mediapipe_expected_pose_landmarks_prototxt_orig", - sha256 = "c230e0933e6cb4af69ec21314f3f9930fe13e7bb4bf1dbdb74427e4138c24c1e", - urls = ["https://storage.googleapis.com/mediapipe-assets/expected_pose_landmarks.prototxt.orig?generation=1681244235071100"], - ) - http_file( name = "com_google_mediapipe_expected_right_down_hand_landmarks_prototxt", sha256 = "f281b745175aaa7f458def6cf4c89521fb56302dd61a05642b3b4a4f237ffaa3", @@ -424,6 +418,12 @@ def external_files(): urls = ["https://storage.googleapis.com/mediapipe-assets/face_stylization_dummy.tflite?generation=1678323589048063"], ) + http_file( + name = "com_google_mediapipe_face_stylizer_task", + sha256 = "b34f3896cbe860468538cf5a562c0468964f182b8bb07cb527224312969d1625", + urls = ["https://storage.googleapis.com/mediapipe-assets/face_stylizer.task?generation=1682627841126340"], + ) + http_file( name = "com_google_mediapipe_feature_tensor_meta_json", sha256 = "b2c30ddfd495956ce81085f8a143422f4310b002cfbf1c594ff2ee0576e29d6f", @@ -964,6 +964,12 @@ def external_files(): urls = ["https://storage.googleapis.com/mediapipe-assets/portrait_selfie_segmentation_landscape_expected_category_mask.jpg?generation=1678606939469429"], ) + http_file( + name = "com_google_mediapipe_portrait_small_jpg", + sha256 = "873a1a5e4cc86c040101362c5dea6a71cf524563b0700640175e5c3763a4246a", + urls = ["https://storage.googleapis.com/mediapipe-assets/portrait_small.jpg?generation=1682627845552867"], + ) + http_file( name = "com_google_mediapipe_pose_detection_tflite", sha256 = "9ba9dd3d42efaaba86b4ff0122b06f29c4122e756b329d89dca1e297fd8f866c", From 8e82e91095fa73b4876780b4213c7caa934c8b77 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Fri, 28 Apr 2023 03:13:14 +0530 Subject: [PATCH 125/753] Added config for fat simulator builds --- .bazelrc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.bazelrc b/.bazelrc index 724dd23fd..44bc3d0a1 100644 --- a/.bazelrc +++ b/.bazelrc @@ -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 From 2a0aa86ca9893b35ce4a4c5aa657d72ae0dab922 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Fri, 28 Apr 2023 03:14:41 +0530 Subject: [PATCH 126/753] Added http_archive to download opencv sources --- WORKSPACE | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/WORKSPACE b/WORKSPACE index 760898185..6ea213952 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -375,6 +375,18 @@ 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.1 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. +http_archive( + name = "ios_opencv_source", + sha256 = "5fbc26ee09e148a4d494b225d04217f7c913ca1a4d46115b70cca3565d7bbe05", + build_file = "@//third_party:opencv_ios_source.BUILD", + type = "zip", + url = "https://github.com/opencv/opencv/archive/refs/tags/4.5.1.zip", +) + http_archive( name = "stblib", strip_prefix = "stb-b42009b3b9d4ca35bc703f5310eedc74f584be58", From ad4513784c77a044d06628ca772932998d411909 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Fri, 28 Apr 2023 03:16:08 +0530 Subject: [PATCH 127/753] Added build file for ios opencv from sources --- third_party/opencv_ios_source.BUILD | 127 +++++ third_party/opencv_ios_source.bzl | 151 ++++++ third_party/opencv_ios_xcframework_files.bzl | 468 +++++++++++++++++++ 3 files changed, 746 insertions(+) create mode 100644 third_party/opencv_ios_source.BUILD create mode 100644 third_party/opencv_ios_source.bzl create mode 100644 third_party/opencv_ios_xcframework_files.bzl diff --git a/third_party/opencv_ios_source.BUILD b/third_party/opencv_ios_source.BUILD new file mode 100644 index 000000000..293846ce8 --- /dev/null +++ b/third_party/opencv_ios_source.BUILD @@ -0,0 +1,127 @@ +# Description: +# OpenCV xcframework for video/image processing on iOS. + +licenses(["notice"]) # BSD license + +exports_files(["LICENSE"]) + +load( + "@build_bazel_rules_apple//apple:apple.bzl", + "apple_static_xcframework_import", +) + +load( + "@//third_party:opencv_ios_source.bzl", + "select_headers", + "unzip_opencv_xcframework", +) + +# Build opencv2.xcframework from source using a convenience script provided in +# OPENCV sources and zip the xcframework. We only build the modules required by MediaPipe by specifying +# the modules to be ignored as command line arguments. +# We also specify the simulator and device architectures we are building for. +# Currently we only support iOS arm64 (M1 Macs) and x86_64(Intel Macs) simulators +# and arm64 iOS devices. +# Bitcode and Swift support. Swift support will be added in when the final binary +# for MediaPipe iOS Task libraries are built. Shipping with OPENCV built with +# Swift support throws linker errors when the MediaPipe framework is used from +# an iOS project. +genrule( + name = "build_opencv_xcframework", + srcs = glob(["opencv-4.5.1/**"]), + outs = ["opencv2.xcframework.zip"], + cmd = "&&".join([ + "$(location opencv-4.5.1/platforms/apple/build_xcframework.py) \ + --iphonesimulator_archs arm64,x86_64 \ + --iphoneos_archs arm64 \ + --without dnn \ + --without ml \ + --without stitching \ + --without photo \ + --without objdetect \ + --without gapi \ + --without flann \ + --disable PROTOBUF \ + --disable-bitcode \ + --disable-swift \ + --build_only_specified_archs \ + --out $(@D)", + "cd $(@D)", + "zip --symlinks -r opencv2.xcframework.zip opencv2.xcframework", + ]), +) + +# Unzips `opencv2.xcframework.zip` built from source by `build_opencv_xcframework` +# genrule and returns an exhaustive list of all its files including symlinks. +unzip_opencv_xcframework ( + name = "opencv2_unzipped_xcframework_files", + zip_file = "opencv2.xcframework.zip", +) + +# Imports the files of the unzipped `opencv2.xcframework` as an apple static +# framework which can be linked to iOS targets. +apple_static_xcframework_import( + name = "opencv_xcframework", + xcframework_imports = [":opencv2_unzipped_xcframework_files"], + visibility = ["//visibility:public"], +) + +# Filters the headers for each platform in `opencv2.xcframework` which will be +# used as headers in a `cc_library` that can be linked to C++ targets. +select_headers( + name = "opencv_xcframework_device_headers", + srcs = [":opencv_xcframework"], + platform = "ios-arm64", +) + +select_headers( + name = "opencv_xcframework_simulator_headers", + srcs = [":opencv_xcframework"], + platform = "ios-arm64_x86_64-simulator", +) + +# `cc_library` that can be linked to C++ targets to import opencv headers. +cc_library( + name = "opencv", + hdrs = select({ + "@//mediapipe:ios_x86_64" : [ + ":opencv_xcframework_simulator_headers" + ], + "@//mediapipe:ios_sim_arm64" : [ + ":opencv_xcframework_simulator_headers" + ], + "@//mediapipe:ios_arm64" : [ + ":opencv_xcframework_simulator_headers" + ], + # A value from above is chosen arbitarily. + "//conditions:default": [ + ":opencv_xcframework_simulator_headers" + ], + }), + copts = [ + "-std=c++11", + "-x objective-c++", + ], + include_prefix = "opencv2", + linkopts = [ + "-framework AssetsLibrary", + "-framework CoreFoundation", + "-framework CoreGraphics", + "-framework CoreMedia", + "-framework Accelerate", + "-framework CoreImage", + "-framework AVFoundation", + "-framework CoreVideo", + "-framework QuartzCore", + ], + strip_include_prefix = select({ + "@//mediapipe:ios_x86_64" : "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers", + "@//mediapipe:ios_sim_arm64" :"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers", + "@//mediapipe:ios_arm64" : "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers", + # Random value is selected for default cases. + "//conditions:default": "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers", + }), + visibility = ["//visibility:public"], + deps = [":opencv_xcframework"], + # data = [":opencv_xcframework"] +) \ No newline at end of file diff --git a/third_party/opencv_ios_source.bzl b/third_party/opencv_ios_source.bzl new file mode 100644 index 000000000..8474c2878 --- /dev/null +++ b/third_party/opencv_ios_source.bzl @@ -0,0 +1,151 @@ +# Copyright 2023 The MediaPipe Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Custom rules for building iOS OpenCV xcframework from sources.""" + +load( + "@//third_party:opencv_ios_xcframework_files.bzl", + "OPENCV_XCFRAMEWORK_IOS_SIMULATOR_FILE_PATHS", + "OPENCV_XCFRAMEWORK_IOS_DEVICE_FILE_PATHS", + "OPENCV_XCFRAMEWORK_INFO_PLIST_PATH" +) + +_OPENCV_XCFRAMEWORK_DIR_NAME = "opencv2.xcframework" +_OPENCV_FRAMEWORK_DIR_NAME = "opencv2.framework" +_OPENCV_SIMULATOR_PLATFORM_DIR_NAME = "ios-arm64_x86_64-simulator" +_OPENCV_DEVICE_PLATFORM_DIR_NAME = "ios-arm64" +_OPENCV_PLATFORM_DIR_NAMES = [_OPENCV_SIMULATOR_PLATFORM_DIR_NAME, _OPENCV_DEVICE_PLATFORM_DIR_NAME] + +def _select_headers_impl(ctx): + _files = [f for f in ctx.files.srcs + if (f.basename.endswith(".h") or f.basename.endswith(".hpp")) + and f.dirname.find(ctx.attr.platform) != -1] + return [DefaultInfo(files = depset(_files))] + +# This rule selects only the headers from an apple static xcframework filtered by +# an input platform string. +select_headers = rule( + implementation = _select_headers_impl, + attrs = { + "srcs": attr.label_list(mandatory = True, allow_files=True), + "platform": attr.string(mandatory = True), + }, +) + +# This function declares and returns symlinks to the directories within each platform +# in `opencv2.xcframework` expected to be present. +# The symlinks are created according to the structure stipulated by apple xcframeworks +# do that they can be correctly consumed by `apple_static_xcframework_import` rule. +def _opencv2_directory_symlinks(ctx, platforms): + basenames = ['Resources', 'Headers', 'Modules', 'Versions/Current'] + symlinks = [] + + for platform in platforms: + symlinks = symlinks + [ + ctx.actions.declare_symlink( + _OPENCV_XCFRAMEWORK_DIR_NAME + "/{}/{}/{}".format(platform, _OPENCV_FRAMEWORK_DIR_NAME, name) + ) for name in basenames] + + return symlinks + +# This function declares and returns all the files for each platform expected +# to be present in `opencv2.xcframework` after the unzipping action is run. +def _opencv2_file_list(ctx, platform_filepath_lists): + binary_name = "opencv2" + output_files = [] + binaries_to_symlink = [] + + for (platform, filepaths) in platform_filepath_lists: + for path in filepaths: + file = ctx.actions.declare_file(path) + output_files.append(file) + if path.endswith(binary_name): + symlink_output = ctx.actions.declare_file( + _OPENCV_XCFRAMEWORK_DIR_NAME + "/{}/{}/{}".format( + platform, _OPENCV_FRAMEWORK_DIR_NAME ,binary_name)) + binaries_to_symlink.append((symlink_output, file)) + + return output_files, binaries_to_symlink + +def _unzip_opencv_xcframework_impl(ctx): + + # Array to iterate over the various platforms to declare output files and + # symlinks. + platform_filepath_lists = [ + (_OPENCV_SIMULATOR_PLATFORM_DIR_NAME, OPENCV_XCFRAMEWORK_IOS_SIMULATOR_FILE_PATHS), + (_OPENCV_DEVICE_PLATFORM_DIR_NAME, OPENCV_XCFRAMEWORK_IOS_DEVICE_FILE_PATHS) + ] + + # Gets an exhaustive list of output files which are present in the xcframework. + # Also gets array of `(binary simlink, binary)` pairs which are to be symlinked + # using `ctx.actions.symlink()`. + output_files, binaries_to_symlink = _opencv2_file_list(ctx, platform_filepath_lists) + output_files.append(ctx.actions.declare_file(OPENCV_XCFRAMEWORK_INFO_PLIST_PATH)) + + # xcframeworks have a directory structure in which the `opencv2.framework` folders for each + # platform contain directories which are symlinked to the respective folders of the version + # in use. Simply unzipping the zip of the framework will not make Bazel treat these + # as symlinks. They have to be explicity declared as symlinks using `ctx.actions.declare_symlink()`. + directory_symlinks = _opencv2_directory_symlinks( + ctx, [_OPENCV_SIMULATOR_PLATFORM_DIR_NAME, _OPENCV_DEVICE_PLATFORM_DIR_NAME]) + + output_files = output_files + directory_symlinks + + args = ctx.actions.args() + + # Add the path of the zip file to be unzipped as an argument to be passed to + # `run_shell` action. + args.add(ctx.file.zip_file.path) + + # Add the path to the directory in which the framework is to be unzipped to. + args.add(ctx.file.zip_file.dirname) + + ctx.actions.run_shell( + inputs = [ctx.file.zip_file], + outputs = output_files, + arguments = [args], + progress_message = "Unzipping %s" % ctx.file.zip_file.short_path, + command = "unzip -qq $1 -d $2", + ) + + # The symlinks of the opencv2 binaries for each platform in the xcframework + # have to be symlinked using the `ctx.actions.symlink` unlike the directory + # symlinks which can be expected to be valid when unzipping is completed. + # Otherwise, when tests are run, the linker complaints that the binary is + # not found. + binary_symlink_files = [] + for (symlink_output, binary_file) in binaries_to_symlink: + ctx.actions.symlink(output = symlink_output, target_file = binary_file) + binary_symlink_files.append(symlink_output) + + # Return all the declared output files and symlinks as the output of this + # rule. + return [ DefaultInfo(files=depset(output_files + binary_symlink_files)) ] + + +# This rule unzips an `opencv2.xcframework.zip` created by a genrule that +# invokes a python script in the opencv 4.5.1 github archive. +# It returns all the contents of opencv2.xcframework as a list of files in the +# output. This rule works by explicitly declaring files at hardcoded +# paths in the opencv2 xcframework bundle which are expected to be present when +# the zip file is unzipped. This is a prerequisite since the outputs of this rule +# will be consumed by apple_static_xcframework_import which can only take a list +# of files as inputs. +unzip_opencv_xcframework = rule( + implementation = _unzip_opencv_xcframework_impl, + attrs = { + "zip_file": attr.label(mandatory = True, allow_single_file=True), + }, +) + diff --git a/third_party/opencv_ios_xcframework_files.bzl b/third_party/opencv_ios_xcframework_files.bzl new file mode 100644 index 000000000..19dd6f214 --- /dev/null +++ b/third_party/opencv_ios_xcframework_files.bzl @@ -0,0 +1,468 @@ +# Copyright 2023 The MediaPipe Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""List of file paths in the `opencv2.xcframework` bundle.""" + +OPENCV_XCFRAMEWORK_INFO_PLIST_PATH = "opencv2.xcframework/Info.plist" + +OPENCV_XCFRAMEWORK_IOS_SIMULATOR_FILE_PATHS = [ +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Resources/Info.plist", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Moments.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfRect2d.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfFloat4.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfPoint2i.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/tracking.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/legacy/constants_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/background_segm.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/video.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Double3.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfByte.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Range.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Core.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Size2f.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/world.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/opencv2-Swift.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/fast_math.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda_types.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/check.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cv_cpu_dispatch.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utility.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/softfloat.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cv_cpu_helper.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cvstd.inl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/msa_macros.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_rvv.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/simd_utils.impl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_wasm.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_neon.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_avx.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_avx512.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_vsx.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/interface.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_msa.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_cpp.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_forward.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_sse.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_sse_em.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/hal.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/async.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/bufferpool.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/ovx.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/optim.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/va_intel.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cvdef.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/warp.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/filters.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/dynamic_smem.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/reduce.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/utility.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/warp_shuffle.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/border_interpolate.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/transform.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/saturate_cast.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/vec_math.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/functional.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/limits.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/type_traits.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/vec_distance.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/block.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/reduce.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/reduce_key_val.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/color_detail.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/type_traits_detail.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/vec_distance_detail.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/transform_detail.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/emulation.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/color.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/datamov_utils.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/funcattrib.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/common.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/vec_traits.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/simd_functions.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/warp_reduce.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/scan.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/traits.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opengl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cvstd_wrapper.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda.inl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/eigen.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda_stream_accessor.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/ocl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/affine.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/mat.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/logger.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/allocator_stats.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/allocator_stats.impl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/logtag.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/filesystem.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/tls.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/trace.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/instrumentation.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/logger.defines.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/quaternion.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/neon_utils.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/sse_utils.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/version.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/opencl_info.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_gl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_definitions.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_hsa_extension.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_clamdblas.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_core.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_20.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_core_wrappers.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_gl_wrappers.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_clamdfft.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_gl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_core.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/ocl_defs.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/opencl_svm.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/ocl_genbase.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/detail/async_promise.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/detail/exception_ptr.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/simd_intrinsics.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/matx.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/directx.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/base.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/operations.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/vsx_utils.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/persistence.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/mat.inl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/types_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cvstd.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/types.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/bindings_utils.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/quaternion.inl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/saturate.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/core_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/core.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Converters.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Mat.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Algorithm.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/opencv.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Mat+Converters.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/ByteVector.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/imgproc.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/imgproc_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/hal/interface.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/hal/hal.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/detail/gcgraph.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/types_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/highgui.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/features2d.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point2f.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/KeyPoint.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Rect2f.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Float6.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfKeyPoint.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfRect2i.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/FloatVector.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/TermCriteria.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/opencv2.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Int4.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfDMatch.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Scalar.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point3f.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfDouble.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/IntVector.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/RotatedRect.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfFloat6.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/cvconfig.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/DoubleVector.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Size2d.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MinMaxLocResult.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfInt4.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Rect2i.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point2i.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfPoint3.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfRotatedRect.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/DMatch.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/TickMeter.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point3i.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/ios.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/legacy/constants_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/macosx.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/imgcodecs.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/imgcodecs_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/CvType.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/CVObjcUtil.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Size2i.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Float4.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/registry.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/cap_ios.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/legacy/constants_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/videoio.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/videoio_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfFloat.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Rect2d.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfPoint2f.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point2d.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/highgui/highgui.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/highgui/highgui_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Double2.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/CvCamera2.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/features2d/hal/interface.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/features2d/features2d.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/opencv_modules.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfInt.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/ArrayUtil.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfPoint3f.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point3d.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/x86_64-apple-ios-simulator.swiftinterface", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios-simulator.abi.json", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/x86_64-apple-ios-simulator.swiftdoc", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios-simulator.swiftinterface", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios-simulator.swiftdoc", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/x86_64-apple-ios-simulator.abi.json", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/module.modulemap", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/opencv2", +] + +OPENCV_XCFRAMEWORK_IOS_DEVICE_FILE_PATHS = [ +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Resources/Info.plist", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Moments.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfRect2d.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfFloat4.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfPoint2i.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/tracking.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/legacy/constants_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/background_segm.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/video.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Double3.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfByte.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Range.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Core.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Size2f.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/world.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/opencv2-Swift.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/fast_math.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda_types.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/check.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cv_cpu_dispatch.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utility.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/softfloat.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cv_cpu_helper.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cvstd.inl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/msa_macros.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_rvv.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/simd_utils.impl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_wasm.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_neon.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_avx.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_avx512.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_vsx.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/interface.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_msa.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_cpp.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_forward.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_sse.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_sse_em.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/hal.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/async.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/bufferpool.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/ovx.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/optim.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/va_intel.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cvdef.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/warp.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/filters.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/dynamic_smem.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/reduce.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/utility.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/warp_shuffle.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/border_interpolate.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/transform.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/saturate_cast.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/vec_math.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/functional.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/limits.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/type_traits.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/vec_distance.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/block.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/reduce.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/reduce_key_val.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/color_detail.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/type_traits_detail.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/vec_distance_detail.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/transform_detail.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/emulation.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/color.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/datamov_utils.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/funcattrib.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/common.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/vec_traits.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/simd_functions.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/warp_reduce.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/scan.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/traits.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opengl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cvstd_wrapper.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda.inl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/eigen.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda_stream_accessor.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/ocl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/affine.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/mat.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/logger.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/allocator_stats.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/allocator_stats.impl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/logtag.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/filesystem.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/tls.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/trace.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/instrumentation.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/logger.defines.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/quaternion.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/neon_utils.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/sse_utils.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/version.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/opencl_info.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_gl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_definitions.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_hsa_extension.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_clamdblas.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_core.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_20.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_core_wrappers.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_gl_wrappers.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_clamdfft.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_gl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_core.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/ocl_defs.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/opencl_svm.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/ocl_genbase.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/detail/async_promise.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/detail/exception_ptr.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/simd_intrinsics.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/matx.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/directx.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/base.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/operations.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/vsx_utils.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/persistence.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/mat.inl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/types_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cvstd.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/types.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/bindings_utils.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/quaternion.inl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/saturate.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/core_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/core.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Converters.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Mat.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Algorithm.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/opencv.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Mat+Converters.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/ByteVector.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/imgproc.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/imgproc_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/hal/interface.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/hal/hal.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/detail/gcgraph.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/types_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/highgui.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/features2d.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point2f.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/KeyPoint.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Rect2f.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Float6.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfKeyPoint.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfRect2i.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/FloatVector.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/TermCriteria.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/opencv2.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Int4.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfDMatch.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Scalar.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point3f.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfDouble.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/IntVector.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/RotatedRect.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfFloat6.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/cvconfig.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/DoubleVector.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Size2d.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MinMaxLocResult.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfInt4.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Rect2i.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point2i.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfPoint3.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfRotatedRect.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/DMatch.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/TickMeter.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point3i.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/ios.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/legacy/constants_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/macosx.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/imgcodecs.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/imgcodecs_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/CvType.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/CVObjcUtil.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Size2i.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Float4.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/registry.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/cap_ios.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/legacy/constants_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/videoio.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/videoio_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfFloat.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Rect2d.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfPoint2f.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point2d.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/highgui/highgui.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/highgui/highgui_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Double2.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/CvCamera2.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/features2d/hal/interface.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/features2d/features2d.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/opencv_modules.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfInt.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/ArrayUtil.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfPoint3f.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point3d.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios.swiftinterface", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios.swiftdoc", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios.abi.json", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios.private.swiftinterface", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/module.modulemap", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/opencv2", +] \ No newline at end of file From aafb0162f484d75991438d14339c9ddeff77743e Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Fri, 28 Apr 2023 03:17:22 +0530 Subject: [PATCH 128/753] Added config settings to select building iOS xcframework from source for certain configs --- third_party/BUILD | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/third_party/BUILD b/third_party/BUILD index 7522bab1b..3c3710d9e 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -61,10 +61,56 @@ config_setting( visibility = ["//visibility:public"], ) +config_setting( + name = "opencv_ios_arm64_source_build", + values = { + "apple_platform_type": "ios", + "cpu": "ios_arm64" + }, + define_values = { + "OPENCV": "source", + }, +) + +config_setting( + name = "opencv_ios_sim_arm64_source_build", + values = { + "config": "ios_sim_arm64", + }, + define_values = { + "OPENCV": "source", + }, +) + +config_setting( + name = "opencv_ios_x86_64_source_build", + values = { + "apple_platform_type": "ios", + "cpu": "ios_x86_64" + }, + define_values = { + "OPENCV": "source", + }, +) + +config_setting( + name = "opencv_ios_sim_fat_source_build", + values = { + "config": "ios_sim_fat", + }, + define_values = { + "OPENCV": "source", + }, +) + alias( name = "opencv", actual = select({ ":opencv_source_build": ":opencv_cmake", + ":opencv_ios_sim_arm64_source_build" : "@ios_opencv_source//:opencv", + ":opencv_ios_sim_fat_source_build" : "@ios_opencv_source//:opencv", + ":opencv_ios_sim_arm64_source_build" : "@ios_opencv_source//:opencv", + ":opencv_ios_arm64_source_build" : "@ios_opencv_source//:opencv", "//conditions:default": ":opencv_binary", }), visibility = ["//visibility:public"], From bdede4f94ec3971d0c5f1471ff8fefd96b59a433 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Fri, 28 Apr 2023 03:26:29 +0530 Subject: [PATCH 129/753] Updated select conditions --- mediapipe/BUILD | 1 + mediapipe/tasks/ios/vision/core/BUILD | 17 +++++++++++++++-- third_party/BUILD | 9 +++++---- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/mediapipe/BUILD b/mediapipe/BUILD index 3187c0cf7..fd0cbab36 100644 --- a/mediapipe/BUILD +++ b/mediapipe/BUILD @@ -141,6 +141,7 @@ config_setting( "ios_armv7", "ios_arm64", "ios_arm64e", + "ios_sim_arm64", ] ] diff --git a/mediapipe/tasks/ios/vision/core/BUILD b/mediapipe/tasks/ios/vision/core/BUILD index 4b72fc91d..0ea54fbcf 100644 --- a/mediapipe/tasks/ios/vision/core/BUILD +++ b/mediapipe/tasks/ios/vision/core/BUILD @@ -61,6 +61,19 @@ objc_library( "//mediapipe/tasks/ios/core:MPPTaskRunner", "//third_party/apple_frameworks:UIKit", "@com_google_absl//absl/status:statusor", - "@ios_opencv//:OpencvFramework", - ], + ] + select({ + "@//third_party:opencv_ios_sim_arm64_source_build" : [ + "@ios_opencv_source//:opencv_xcframework" + ], + "@//third_party:opencv_ios_sim_fat_source_build" : [ + "@ios_opencv_source//:opencv_xcframework" + ], + "@//third_party:opencv_ios_arm64_source_build" : [ + "@ios_opencv_source//:opencv_xcframework" + ], + "//conditions:default": [ + "@ios_opencv//:OpencvFramework" + ], + }) + ) diff --git a/third_party/BUILD b/third_party/BUILD index 3c3710d9e..ce1e1bf73 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -65,7 +65,7 @@ config_setting( name = "opencv_ios_arm64_source_build", values = { "apple_platform_type": "ios", - "cpu": "ios_arm64" + "cpu": "ios_arm64", }, define_values = { "OPENCV": "source", @@ -75,7 +75,8 @@ config_setting( config_setting( name = "opencv_ios_sim_arm64_source_build", values = { - "config": "ios_sim_arm64", + "apple_platform_type": "ios", + "cpu": "ios_sim_arm64", }, define_values = { "OPENCV": "source", @@ -96,7 +97,8 @@ config_setting( config_setting( name = "opencv_ios_sim_fat_source_build", values = { - "config": "ios_sim_fat", + "apple_platform_type": "ios", + "ios_multi_cpus": "sim_arm64, x86_64" }, define_values = { "OPENCV": "source", @@ -109,7 +111,6 @@ alias( ":opencv_source_build": ":opencv_cmake", ":opencv_ios_sim_arm64_source_build" : "@ios_opencv_source//:opencv", ":opencv_ios_sim_fat_source_build" : "@ios_opencv_source//:opencv", - ":opencv_ios_sim_arm64_source_build" : "@ios_opencv_source//:opencv", ":opencv_ios_arm64_source_build" : "@ios_opencv_source//:opencv", "//conditions:default": ":opencv_binary", }), From fec11735a35d19fcf75a07c08424c5ce876d9155 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Fri, 28 Apr 2023 03:30:21 +0530 Subject: [PATCH 130/753] Updated formatting --- third_party/opencv_ios_source.BUILD | 2 +- third_party/opencv_ios_source.bzl | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/third_party/opencv_ios_source.BUILD b/third_party/opencv_ios_source.BUILD index 293846ce8..0021e5116 100644 --- a/third_party/opencv_ios_source.BUILD +++ b/third_party/opencv_ios_source.BUILD @@ -124,4 +124,4 @@ cc_library( visibility = ["//visibility:public"], deps = [":opencv_xcframework"], # data = [":opencv_xcframework"] -) \ No newline at end of file +) diff --git a/third_party/opencv_ios_source.bzl b/third_party/opencv_ios_source.bzl index 8474c2878..8ddbffe2c 100644 --- a/third_party/opencv_ios_source.bzl +++ b/third_party/opencv_ios_source.bzl @@ -148,4 +148,3 @@ unzip_opencv_xcframework = rule( "zip_file": attr.label(mandatory = True, allow_single_file=True), }, ) - From 82840b8e2874a823a4b95f6d039a0dbfabf9cf52 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Fri, 28 Apr 2023 03:30:47 +0530 Subject: [PATCH 131/753] Removed comments --- third_party/opencv_ios_source.BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/third_party/opencv_ios_source.BUILD b/third_party/opencv_ios_source.BUILD index 0021e5116..26a2b15e9 100644 --- a/third_party/opencv_ios_source.BUILD +++ b/third_party/opencv_ios_source.BUILD @@ -123,5 +123,4 @@ cc_library( }), visibility = ["//visibility:public"], deps = [":opencv_xcframework"], - # data = [":opencv_xcframework"] ) From b7e46ec52846c046766d0197a056689c721f842b Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 27 Apr 2023 15:55:56 -0700 Subject: [PATCH 132/753] Update WASM files for Alpha 13 PiperOrigin-RevId: 527707613 --- third_party/wasm_files.bzl | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/third_party/wasm_files.bzl b/third_party/wasm_files.bzl index a484d2f82..b1b357f05 100644 --- a/third_party/wasm_files.bzl +++ b/third_party/wasm_files.bzl @@ -12,72 +12,72 @@ def wasm_files(): http_file( name = "com_google_mediapipe_wasm_audio_wasm_internal_js", - sha256 = "b810de53d7ccf991b9c70fcdf7e88b5c3f2942ae766436f22be48159b6a7e687", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.js?generation=1681849488227617"], + sha256 = "1c555ecdb8faffca703d191626a6830e56fd0ab996d8837d7240d50098cc3109", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.js?generation=1682632113236604"], ) http_file( name = "com_google_mediapipe_wasm_audio_wasm_internal_wasm", - sha256 = "26d91147e5c6c8a92e0a4ebf59599068a3cff6108847b793ef33ac23e98eddb9", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.wasm?generation=1681849491546937"], + sha256 = "aee8e7832b876a32a323f26b9f45002d2cc9d9e25db109ae360ec57fb3ed0c2e", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.wasm?generation=1682632115959200"], ) http_file( name = "com_google_mediapipe_wasm_audio_wasm_nosimd_internal_js", - sha256 = "b38e37b3024692558eaaba159921fedd3297d1a09bba1c16a06fed327845b0bd", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.js?generation=1681849494099698"], + sha256 = "73df132f8d6ba62a406f120c514700e5a65d69a114e86de11dc9759024eedd7c", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.js?generation=1682632118022450"], ) http_file( name = "com_google_mediapipe_wasm_audio_wasm_nosimd_internal_wasm", - sha256 = "6a8e73d2e926565046e16adf1748f0f8ec5135fafe7eb8b9c83892e64c1a449a", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.wasm?generation=1681849496451970"], + sha256 = "7a4400c0b16f768161574b2ce512179e0afc4f8aa313232db7a4b7c572de2abb", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.wasm?generation=1682632120654892"], ) http_file( name = "com_google_mediapipe_wasm_text_wasm_internal_js", - sha256 = "785cba67b623b1dc66dc3621e97fd6b30edccbb408184a3094d0aa68ddd5becb", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.js?generation=1681849498746265"], + sha256 = "18ffadd94fa7844a106b2a9197f8258c39e601f99f01945c543fc0d879baad7f", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.js?generation=1682632123000744"], ) http_file( name = "com_google_mediapipe_wasm_text_wasm_internal_wasm", - sha256 = "a858b8a2e8b40e9c936b66566c5aefd396536c4e936459ab9ae7e239621adc14", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.wasm?generation=1681849501370461"], + sha256 = "96591ca0b64da9b565554384306663f1067b0c0a823d7e856fa58b28b659405a", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.wasm?generation=1682632125672531"], ) http_file( name = "com_google_mediapipe_wasm_text_wasm_nosimd_internal_js", - sha256 = "5292f1442d5e5c037e7cffb78a8c2d71255348ca2c3bd759b314bdbedd5590c2", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.js?generation=1681849503379116"], + sha256 = "668569cd80d6680c6e418ce42109d85151d6ec88ed06940206151585dba895df", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.js?generation=1682632128111024"], ) http_file( name = "com_google_mediapipe_wasm_text_wasm_nosimd_internal_wasm", - sha256 = "e44b48ab29ee1d8befec804e9a63445c56266b679d19fb476d556ca621f0e493", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.wasm?generation=1681849505997020"], + sha256 = "f548cfe74a77aa609b988c212e7a60aa2b078194c3eeda0a3d5802165c2b5fe7", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.wasm?generation=1682632130623184"], ) http_file( name = "com_google_mediapipe_wasm_vision_wasm_internal_js", - sha256 = "205855eba70464a92b9d00e90acac15c51a9f76192f900e697304ac6dea8f714", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.js?generation=1681849508414277"], + sha256 = "347d3ae5a947846431b6e8ea15966156b9cbf1a9ae800932954507b6c12c6ecf", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.js?generation=1682632132979491"], ) http_file( name = "com_google_mediapipe_wasm_vision_wasm_internal_wasm", - sha256 = "c0cbd0df3adb2a9cd1331d14f522d2bae9f8adc9f1b35f92cbbc4b782b190cef", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.wasm?generation=1681849510936608"], + sha256 = "849092df0b599e00d074f4d8c2d7ef16912061298d27e5748ccf353b0f93b168", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.wasm?generation=1682632135762121"], ) http_file( name = "com_google_mediapipe_wasm_vision_wasm_nosimd_internal_js", - sha256 = "0969812de4d3573198fa2eba4f5b0a7e97e98f97bd4215d876543f4925e57b84", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.js?generation=1681849513292639"], + sha256 = "7a130f5c20a320157d109a8aa767904df9717c24e77c99c4313a1716c3685e65", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.js?generation=1682632137850608"], ) http_file( name = "com_google_mediapipe_wasm_vision_wasm_nosimd_internal_wasm", - sha256 = "f2ab62c3f8dabab0a573dadf5c105ff81a03c29c70f091f8cf273ae030c0a86f", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.wasm?generation=1681849515999000"], + sha256 = "c45e706965e0572b41e1518e6243e6dee0d6834e0ac81f49370951d23e52e387", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.wasm?generation=1682632140714614"], ) From 5e41d47f3a041086ca2a09290b3e39afef7a009d Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 27 Apr 2023 17:14:20 -0700 Subject: [PATCH 133/753] Add "close()" method to MP Web Tasks PiperOrigin-RevId: 527726737 --- mediapipe/tasks/web/core/task_runner.ts | 5 +++++ mediapipe/tasks/web/core/task_runner_test_utils.ts | 3 ++- mediapipe/web/graph_runner/graph_runner.ts | 11 +++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/mediapipe/tasks/web/core/task_runner.ts b/mediapipe/tasks/web/core/task_runner.ts index 9a36b6487..91a38cd44 100644 --- a/mediapipe/tasks/web/core/task_runner.ts +++ b/mediapipe/tasks/web/core/task_runner.ts @@ -256,6 +256,11 @@ export abstract class TaskRunner { this.baseOptions.setAcceleration(acceleration); } + + /** Closes and cleans up the resources held by this task. */ + close(): void { + this.graphRunner.closeGraph(); + } } diff --git a/mediapipe/tasks/web/core/task_runner_test_utils.ts b/mediapipe/tasks/web/core/task_runner_test_utils.ts index d911b2c89..edf1d0d32 100644 --- a/mediapipe/tasks/web/core/task_runner_test_utils.ts +++ b/mediapipe/tasks/web/core/task_runner_test_utils.ts @@ -36,7 +36,8 @@ export function createSpyWasmModule(): SpyWasmModule { '_setAutoRenderToScreen', 'stringToNewUTF8', '_attachProtoListener', '_attachProtoVectorListener', '_free', '_waitUntilIdle', '_addStringToInputStream', '_registerModelResourcesGraphService', - '_configureAudio', '_malloc', '_addProtoToInputStream', '_getGraphConfig' + '_configureAudio', '_malloc', '_addProtoToInputStream', '_getGraphConfig', + '_closeGraph' ]); spyWasmModule._getGraphConfig.and.callFake(() => { (spyWasmModule.simpleListeners![CALCULATOR_GRAPH_CONFIG_LISTENER_NAME] as diff --git a/mediapipe/web/graph_runner/graph_runner.ts b/mediapipe/web/graph_runner/graph_runner.ts index 0115312b4..615971cb3 100644 --- a/mediapipe/web/graph_runner/graph_runner.ts +++ b/mediapipe/web/graph_runner/graph_runner.ts @@ -63,6 +63,7 @@ export declare interface WasmModule { _bindTextureToCanvas: () => boolean; _changeBinaryGraph: (size: number, dataPtr: number) => void; _changeTextGraph: (size: number, dataPtr: number) => void; + _closeGraph: () => void; _free: (ptr: number) => void; _malloc: (size: number) => number; _processFrame: (width: number, height: number, timestamp: number) => void; @@ -1148,6 +1149,16 @@ export class GraphRunner { finishProcessing(): void { this.wasmModule._waitUntilIdle(); } + + /** + * Closes the input streams and all calculators for this graph and frees up + * any C++ resources. The graph will not be usable once closed. + */ + closeGraph(): void { + this.wasmModule._closeGraph(); + this.wasmModule.simpleListeners = undefined; + this.wasmModule.emptyPacketListeners = undefined; + } } // Quick private helper to run the given script safely From 28b9b8d8a37f55089210a725ef444fe7f20114d5 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 27 Apr 2023 18:44:51 -0700 Subject: [PATCH 134/753] Open-sources LanguageDetector model. PiperOrigin-RevId: 527745108 --- mediapipe/tasks/testdata/text/BUILD | 6 ++++++ third_party/external_files.bzl | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/testdata/text/BUILD b/mediapipe/tasks/testdata/text/BUILD index f1f60afdc..f1f0dc814 100644 --- a/mediapipe/tasks/testdata/text/BUILD +++ b/mediapipe/tasks/testdata/text/BUILD @@ -29,6 +29,7 @@ mediapipe_files(srcs = [ "30k-clean.model", "albert_with_metadata.tflite", "bert_text_classifier.tflite", + "language_detector.tflite", "mobilebert_embedding_with_metadata.tflite", "mobilebert_with_metadata.tflite", "regex_one_embedding_with_metadata.tflite", @@ -105,3 +106,8 @@ filegroup( name = "universal_sentence_encoder_qa", srcs = ["universal_sentence_encoder_qa_with_metadata.tflite"], ) + +filegroup( + name = "language_detector", + srcs = ["language_detector.tflite"], +) diff --git a/third_party/external_files.bzl b/third_party/external_files.bzl index a57664e09..ff338bae2 100644 --- a/third_party/external_files.bzl +++ b/third_party/external_files.bzl @@ -276,8 +276,8 @@ def external_files(): http_file( name = "com_google_mediapipe_efficientdet_lite0_fp16_no_nms_tflite", - sha256 = "bcda125c96d3767bca894c8cbe7bc458379c9974c9fd8bdc6204e7124a74082a", - urls = ["https://storage.googleapis.com/mediapipe-assets/efficientdet_lite0_fp16_no_nms.tflite?generation=1682627837744424"], + sha256 = "237a58389081333e5cf4154e42b593ce7dd357445536fcaf4ca5bc51c2c50f1c", + urls = ["https://storage.googleapis.com/mediapipe-assets/efficientdet_lite0_fp16_no_nms.tflite?generation=1682632067597216"], ) http_file( From 5d9761cbfd11382800c2d537b8e84e30a88dcd5e Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 27 Apr 2023 18:56:55 -0700 Subject: [PATCH 135/753] Update tests and demos to call "close". PiperOrigin-RevId: 527746909 --- .../tasks/web/audio/audio_classifier/audio_classifier_test.ts | 4 ++++ .../tasks/web/audio/audio_embedder/audio_embedder_test.ts | 4 ++++ .../web/text/language_detector/language_detector_test.ts | 4 ++++ .../tasks/web/text/text_classifier/text_classifier_test.ts | 4 ++++ mediapipe/tasks/web/text/text_embedder/text_embedder_test.ts | 4 ++++ .../tasks/web/vision/face_detector/face_detector_test.ts | 4 ++++ .../tasks/web/vision/face_landmarker/face_landmarker_test.ts | 4 ++++ .../tasks/web/vision/face_stylizer/face_stylizer_test.ts | 4 ++++ .../web/vision/gesture_recognizer/gesture_recognizer_test.ts | 4 ++++ .../tasks/web/vision/hand_landmarker/hand_landmarker_test.ts | 4 ++++ .../web/vision/image_classifier/image_classifier_test.ts | 4 ++++ .../tasks/web/vision/image_embedder/image_embedder_test.ts | 4 ++++ .../tasks/web/vision/image_segmenter/image_segmenter_test.ts | 4 ++++ .../interactive_segmenter/interactive_segmenter_test.ts | 4 ++++ .../tasks/web/vision/object_detector/object_detector_test.ts | 4 ++++ 15 files changed, 60 insertions(+) diff --git a/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_test.ts b/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_test.ts index a0e906095..ba4f4535b 100644 --- a/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_test.ts +++ b/mediapipe/tasks/web/audio/audio_classifier/audio_classifier_test.ts @@ -86,6 +86,10 @@ describe('AudioClassifier', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + audioClassifier.close(); + }); + it('initializes graph', async () => { verifyGraph(audioClassifier); verifyListenersRegistered(audioClassifier); diff --git a/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_test.ts b/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_test.ts index 8c79ceb21..0944e75e6 100644 --- a/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_test.ts +++ b/mediapipe/tasks/web/audio/audio_embedder/audio_embedder_test.ts @@ -76,6 +76,10 @@ describe('AudioEmbedder', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + audioEmbedder.close(); + }); + it('initializes graph', () => { verifyGraph(audioEmbedder); verifyListenersRegistered(audioEmbedder); diff --git a/mediapipe/tasks/web/text/language_detector/language_detector_test.ts b/mediapipe/tasks/web/text/language_detector/language_detector_test.ts index 71ab60a59..94eafb04e 100644 --- a/mediapipe/tasks/web/text/language_detector/language_detector_test.ts +++ b/mediapipe/tasks/web/text/language_detector/language_detector_test.ts @@ -62,6 +62,10 @@ describe('LanguageDetector', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + languageDetector.close(); + }); + it('initializes graph', async () => { verifyGraph(languageDetector); verifyListenersRegistered(languageDetector); diff --git a/mediapipe/tasks/web/text/text_classifier/text_classifier_test.ts b/mediapipe/tasks/web/text/text_classifier/text_classifier_test.ts index 2b22c0006..843745188 100644 --- a/mediapipe/tasks/web/text/text_classifier/text_classifier_test.ts +++ b/mediapipe/tasks/web/text/text_classifier/text_classifier_test.ts @@ -61,6 +61,10 @@ describe('TextClassifier', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + textClassifier.close(); + }); + it('initializes graph', async () => { verifyGraph(textClassifier); verifyListenersRegistered(textClassifier); diff --git a/mediapipe/tasks/web/text/text_embedder/text_embedder_test.ts b/mediapipe/tasks/web/text/text_embedder/text_embedder_test.ts index 7adeeb1b0..53c09826b 100644 --- a/mediapipe/tasks/web/text/text_embedder/text_embedder_test.ts +++ b/mediapipe/tasks/web/text/text_embedder/text_embedder_test.ts @@ -61,6 +61,10 @@ describe('TextEmbedder', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + textEmbedder.close(); + }); + it('initializes graph', async () => { verifyGraph(textEmbedder); verifyListenersRegistered(textEmbedder); diff --git a/mediapipe/tasks/web/vision/face_detector/face_detector_test.ts b/mediapipe/tasks/web/vision/face_detector/face_detector_test.ts index 9f9d00732..28f602965 100644 --- a/mediapipe/tasks/web/vision/face_detector/face_detector_test.ts +++ b/mediapipe/tasks/web/vision/face_detector/face_detector_test.ts @@ -66,6 +66,10 @@ describe('FaceDetector', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + faceDetector.close(); + }); + it('initializes graph', async () => { verifyGraph(faceDetector); verifyListenersRegistered(faceDetector); diff --git a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_test.ts b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_test.ts index b6f16a721..7070d1dd7 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_test.ts @@ -94,6 +94,10 @@ describe('FaceLandmarker', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + faceLandmarker.close(); + }); + it('initializes graph', async () => { verifyGraph(faceLandmarker); verifyListenersRegistered(faceLandmarker); diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts index 3ef35728d..167fd674e 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts @@ -66,6 +66,10 @@ describe('FaceStylizer', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + faceStylizer.close(); + }); + it('initializes graph', async () => { verifyGraph(faceStylizer); verifyListenersRegistered(faceStylizer); diff --git a/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_test.ts b/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_test.ts index 4b064500e..95ba06cca 100644 --- a/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_test.ts +++ b/mediapipe/tasks/web/vision/gesture_recognizer/gesture_recognizer_test.ts @@ -113,6 +113,10 @@ describe('GestureRecognizer', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + gestureRecognizer.close(); + }); + it('initializes graph', async () => { verifyGraph(gestureRecognizer); verifyListenersRegistered(gestureRecognizer); diff --git a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_test.ts b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_test.ts index 7499444f4..91cba1f1f 100644 --- a/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/hand_landmarker/hand_landmarker_test.ts @@ -83,6 +83,10 @@ describe('HandLandmarker', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + handLandmarker.close(); + }); + it('initializes graph', async () => { verifyGraph(handLandmarker); verifyListenersRegistered(handLandmarker); diff --git a/mediapipe/tasks/web/vision/image_classifier/image_classifier_test.ts b/mediapipe/tasks/web/vision/image_classifier/image_classifier_test.ts index 40e50c531..889de4bca 100644 --- a/mediapipe/tasks/web/vision/image_classifier/image_classifier_test.ts +++ b/mediapipe/tasks/web/vision/image_classifier/image_classifier_test.ts @@ -66,6 +66,10 @@ describe('ImageClassifier', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + imageClassifier.close(); + }); + it('initializes graph', async () => { verifyGraph(imageClassifier); verifyListenersRegistered(imageClassifier); diff --git a/mediapipe/tasks/web/vision/image_embedder/image_embedder_test.ts b/mediapipe/tasks/web/vision/image_embedder/image_embedder_test.ts index 7dc0c32ef..6aa6f11cd 100644 --- a/mediapipe/tasks/web/vision/image_embedder/image_embedder_test.ts +++ b/mediapipe/tasks/web/vision/image_embedder/image_embedder_test.ts @@ -62,6 +62,10 @@ describe('ImageEmbedder', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + imageEmbedder.close(); + }); + it('initializes graph', async () => { verifyGraph(imageEmbedder); verifyListenersRegistered(imageEmbedder); diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts index f7d1f1f87..1327c1b3c 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts @@ -68,6 +68,10 @@ describe('ImageSegmenter', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + imageSegmenter.close(); + }); + it('initializes graph', async () => { verifyGraph(imageSegmenter); diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts index 3e108309d..0a9477605 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts @@ -84,6 +84,10 @@ describe('InteractiveSegmenter', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + interactiveSegmenter.close(); + }); + it('initializes graph', async () => { verifyGraph(interactiveSegmenter); diff --git a/mediapipe/tasks/web/vision/object_detector/object_detector_test.ts b/mediapipe/tasks/web/vision/object_detector/object_detector_test.ts index a9d951e94..1613f27d7 100644 --- a/mediapipe/tasks/web/vision/object_detector/object_detector_test.ts +++ b/mediapipe/tasks/web/vision/object_detector/object_detector_test.ts @@ -66,6 +66,10 @@ describe('ObjectDetector', () => { {baseOptions: {modelAssetBuffer: new Uint8Array([])}}); }); + afterEach(() => { + objectDetector.close(); + }); + it('initializes graph', async () => { verifyGraph(objectDetector); verifyListenersRegistered(objectDetector); From 305866ccaeaa614e700f9b9a698af9514bdf17b7 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Thu, 27 Apr 2023 21:11:53 -0700 Subject: [PATCH 136/753] Updated BUILD files to use the open sourced Language Detector model --- mediapipe/tasks/python/test/text/BUILD | 2 +- mediapipe/tasks/testdata/text/BUILD | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/mediapipe/tasks/python/test/text/BUILD b/mediapipe/tasks/python/test/text/BUILD index 8d25f2781..be352c84d 100644 --- a/mediapipe/tasks/python/test/text/BUILD +++ b/mediapipe/tasks/python/test/text/BUILD @@ -54,7 +54,7 @@ py_test( name = "language_detector_test", srcs = ["language_detector_test.py"], data = [ - "//mediapipe/tasks/testdata/text:language_detector_model", + "//mediapipe/tasks/testdata/text:language_detector", ], deps = [ "//mediapipe/tasks/python/components/containers:category", diff --git a/mediapipe/tasks/testdata/text/BUILD b/mediapipe/tasks/testdata/text/BUILD index 0a50a229a..701ed0dfa 100644 --- a/mediapipe/tasks/testdata/text/BUILD +++ b/mediapipe/tasks/testdata/text/BUILD @@ -80,11 +80,6 @@ filegroup( ], ) -filegroup( - name = "language_detector_model", - srcs = ["language_detector.tflite"], -) - filegroup( name = "text_classifier_models", srcs = [ From 3b06772d9a2616c86d34c8605d023e7862f6a8e9 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Thu, 27 Apr 2023 21:13:31 -0700 Subject: [PATCH 137/753] Fixed BUILD --- mediapipe/tasks/testdata/text/BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/mediapipe/tasks/testdata/text/BUILD b/mediapipe/tasks/testdata/text/BUILD index 701ed0dfa..f1f0dc814 100644 --- a/mediapipe/tasks/testdata/text/BUILD +++ b/mediapipe/tasks/testdata/text/BUILD @@ -32,7 +32,6 @@ mediapipe_files(srcs = [ "language_detector.tflite", "mobilebert_embedding_with_metadata.tflite", "mobilebert_with_metadata.tflite", - "language_detector.tflite", "regex_one_embedding_with_metadata.tflite", "test_model_text_classifier_bool_output.tflite", "test_model_text_classifier_with_regex_tokenizer.tflite", From cf22c971439e93a7347e366eabc0889dba6229d1 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Fri, 28 Apr 2023 00:28:31 -0700 Subject: [PATCH 138/753] Add the TFLite conversion API to BlazeFaceStylizer in model maker. PiperOrigin-RevId: 527806005 --- .../vision/face_stylizer/face_stylizer.py | 30 +++++++++++++++++++ .../face_stylizer/face_stylizer_test.py | 11 +++++++ 2 files changed, 41 insertions(+) diff --git a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py index 0c8097f14..2c0c1057c 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py @@ -13,6 +13,7 @@ # limitations under the License. """APIs to train face stylization model.""" +import os from typing import Callable, Optional import numpy as np @@ -199,3 +200,32 @@ class FaceStylizer(object): tvars = self._decoder.trainable_variables grads = tape.gradient(style_loss, tvars) optimizer.apply_gradients(list(zip(grads, tvars))) + + # TODO: Add a metadata writer for face sytlizer model. + def export_model(self, model_name: str = 'model.tflite'): + """Converts and saves the model to a TFLite file with metadata included. + + Note that only the TFLite file is needed for deployment. This function + also saves a metadata.json file to the same directory as the TFLite file + which can be used to interpret the metadata content in the TFLite file. + + Args: + model_name: File name to save TFLite model with metadata. The full export + path is {self._hparams.export_dir}/{model_name}. + """ + if not tf.io.gfile.exists(self._hparams.export_dir): + tf.io.gfile.makedirs(self._hparams.export_dir) + tflite_file = os.path.join(self._hparams.export_dir, model_name) + + # Create an end-to-end model by concatenating encoder and decoder + inputs = tf.keras.Input(shape=(256, 256, 3)) + x = self._encoder(inputs) + x = self._decoder({'inputs': x + self.w_avg}) + outputs = x['image'][-1] + model = tf.keras.Model(inputs=inputs, outputs=outputs) + + tflite_model = model_util.convert_to_tflite( + model=model, + preprocess=self._preprocessor, + ) + model_util.save_tflite(tflite_model, tflite_file) diff --git a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_test.py b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_test.py index c244a3ee4..8a3023269 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_test.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_test.py @@ -50,6 +50,17 @@ class FaceStylizerTest(tf.test.TestCase): ) self._evaluate_saved_model(model) + def test_export_face_stylizer_tflite_model(self): + with self.test_session(use_gpu=True): + face_stylizer_options = face_stylizer.FaceStylizerOptions( + model=face_stylizer.SupportedModels.BLAZE_FACE_STYLIZER_256, + hparams=face_stylizer.HParams(epochs=0), + ) + model = face_stylizer.FaceStylizer.create( + train_data=self._train_data, options=face_stylizer_options + ) + model.export_model() + if __name__ == '__main__': tf.test.main() From b2fbb2ddab7200517a0018840a669598005e3c31 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Fri, 28 Apr 2023 09:41:42 -0700 Subject: [PATCH 139/753] Internal change PiperOrigin-RevId: 527909361 --- .../cc/vision/pose_landmarker/pose_landmarker_graph_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph_test.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph_test.cc index 6f7488a5f..a2206c336 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph_test.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph_test.cc @@ -84,7 +84,7 @@ constexpr char kSegmentationMaskTag[] = "SEGMENTATION_MASK"; constexpr char kSegmentationMaskName[] = "segmentation_mask"; constexpr float kLiteModelFractionDiff = 0.05; // percentage -constexpr float kGoldenMaskSimilarity = 1.0; +constexpr float kGoldenMaskSimilarity = .98; template ProtoT GetExpectedProto(absl::string_view filename) { From 3dce259bf69eab7c96c6dac362ed21ab6688d8bc Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Fri, 28 Apr 2023 10:59:41 -0700 Subject: [PATCH 140/753] Internal change PiperOrigin-RevId: 527931585 --- mediapipe/calculators/tensorflow/BUILD | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/mediapipe/calculators/tensorflow/BUILD b/mediapipe/calculators/tensorflow/BUILD index 0b30689eb..c4b9ab9f2 100644 --- a/mediapipe/calculators/tensorflow/BUILD +++ b/mediapipe/calculators/tensorflow/BUILD @@ -400,6 +400,16 @@ 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 tensorflow_jellyfish_deps and xprofilez_with_server because they failed +# Boq conformance test. Weigh your use case to see if this will work for you. +cc_library( + name = "tensorflow_inference_calculator_for_boq", srcs = ["tensorflow_inference_calculator.cc"], deps = [ ":tensorflow_inference_calculator_cc_proto", @@ -585,6 +595,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__"], From a54409810053e9b2d4ba871d4fae7e95797574c4 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 28 Apr 2023 14:02:53 -0700 Subject: [PATCH 141/753] Update FaceStylizer to return MPImage PiperOrigin-RevId: 527980696 --- mediapipe/tasks/web/vision/core/BUILD | 1 + mediapipe/tasks/web/vision/core/image.ts | 5 ++ .../web/vision/core/vision_task_runner.ts | 62 ++++++++++++++----- .../tasks/web/vision/face_stylizer/BUILD | 2 + .../web/vision/face_stylizer/face_stylizer.ts | 27 ++++---- .../face_stylizer/face_stylizer_test.ts | 35 ++++++++--- mediapipe/tasks/web/vision/index.ts | 4 +- mediapipe/tasks/web/vision/types.ts | 2 +- 8 files changed, 96 insertions(+), 42 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/BUILD b/mediapipe/tasks/web/vision/core/BUILD index f010a8bdd..daeef060d 100644 --- a/mediapipe/tasks/web/vision/core/BUILD +++ b/mediapipe/tasks/web/vision/core/BUILD @@ -60,6 +60,7 @@ mediapipe_ts_library( name = "vision_task_runner", srcs = ["vision_task_runner.ts"], deps = [ + ":image", ":image_processing_options", ":vision_task_options", "//mediapipe/framework/formats:rect_jspb_proto", diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index 739f05f0f..7a12a923b 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -59,8 +59,11 @@ function assertNotNull(value: T|null, msg: string): T { return value; } +// TODO: Move internal-only types to different module. + /** * Utility class that encapsulates the buffers used by `MPImageShaderContext`. + * For internal use only. */ class MPImageShaderBuffers { constructor( @@ -87,6 +90,8 @@ class MPImageShaderBuffers { /** * A class that encapsulates the shaders used by an MPImage. Can be re-used * across MPImages that use the same WebGL2Rendering context. + * + * For internal use only. */ export class MPImageShaderContext { private gl?: WebGL2RenderingContext; diff --git a/mediapipe/tasks/web/vision/core/vision_task_runner.ts b/mediapipe/tasks/web/vision/core/vision_task_runner.ts index a79cee559..5099d2960 100644 --- a/mediapipe/tasks/web/vision/core/vision_task_runner.ts +++ b/mediapipe/tasks/web/vision/core/vision_task_runner.ts @@ -17,6 +17,7 @@ import {NormalizedRect} from '../../../../framework/formats/rect_pb'; import {TaskRunner} from '../../../../tasks/web/core/task_runner'; import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; +import {MPImage, MPImageShaderContext} from '../../../../tasks/web/vision/core/image'; import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; import {GraphRunner, ImageSource, WasmMediaPipeConstructor} from '../../../../web/graph_runner/graph_runner'; import {SupportImage, WasmImage} from '../../../../web/graph_runner/graph_runner_image_lib'; @@ -51,6 +52,8 @@ function createCanvas(): HTMLCanvasElement|OffscreenCanvas|undefined { /** Base class for all MediaPipe Vision Tasks. */ export abstract class VisionTaskRunner extends TaskRunner { + private readonly shaderContext = new MPImageShaderContext(); + protected static async createVisionInstance( type: WasmMediaPipeConstructor, fileset: WasmFileset, options: VisionTaskOptions): Promise { @@ -219,30 +222,55 @@ export abstract class VisionTaskRunner extends TaskRunner { this.finishProcessing(); } - /** Converts the RGB or RGBA Uint8Array of a WasmImage to ImageData. */ - protected convertToImageData(wasmImage: WasmImage): ImageData { + /** + * Converts a WasmImage to an MPImage. + * + * Converts the underlying Uint8ClampedArray-backed images to ImageData + * (adding an alpha channel if necessary), passes through WebGLTextures and + * throws for Float32Array-backed images. + */ + protected convertToMPImage(wasmImage: WasmImage): MPImage { const {data, width, height} = wasmImage; - if (!(data instanceof Uint8ClampedArray)) { - throw new Error( - 'Only Uint8ClampedArray-based images can be converted to ImageData'); - } - if (data.length === width * height * 4) { - return new ImageData(data, width, height); - } else if (data.length === width * height * 3) { - const rgba = new Uint8ClampedArray(width * height * 4); - for (let i = 0; i < width * height; ++i) { - rgba[4 * i] = data[3 * i]; - rgba[4 * i + 1] = data[3 * i + 1]; - rgba[4 * i + 2] = data[3 * i + 2]; - rgba[4 * i + 3] = 255; + if (data instanceof Uint8ClampedArray) { + let rgba: Uint8ClampedArray; + if (data.length === width * height * 4) { + rgba = data; + } else if (data.length === width * height * 3) { + // TODO: Convert in C++ + rgba = new Uint8ClampedArray(width * height * 4); + for (let i = 0; i < width * height; ++i) { + rgba[4 * i] = data[3 * i]; + rgba[4 * i + 1] = data[3 * i + 1]; + rgba[4 * i + 2] = data[3 * i + 2]; + rgba[4 * i + 3] = 255; + } + } else { + throw new Error( + `Unsupported channel count: ${data.length / width / height}`); } - return new ImageData(rgba, width, height); + + return new MPImage( + [new ImageData(rgba, width, height)], + /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, + this.graphRunner.wasmModule.canvas!, this.shaderContext, width, + height); + } else if (data instanceof WebGLTexture) { + return new MPImage( + [data], /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, + this.graphRunner.wasmModule.canvas!, this.shaderContext, width, + height); } else { throw new Error( - `Unsupported channel count: ${data.length / width / height}`); + `Cannot convert type ${data.constructor.name} to MPImage.`); } } + + /** Closes and cleans up the resources held by this task. */ + override close(): void { + this.shaderContext.close(); + super.close(); + } } diff --git a/mediapipe/tasks/web/vision/face_stylizer/BUILD b/mediapipe/tasks/web/vision/face_stylizer/BUILD index 7716d617f..0c0167dbd 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/BUILD +++ b/mediapipe/tasks/web/vision/face_stylizer/BUILD @@ -17,6 +17,7 @@ mediapipe_ts_library( "//mediapipe/tasks/cc/core/proto:base_options_jspb_proto", "//mediapipe/tasks/cc/vision/face_stylizer/proto:face_stylizer_graph_options_jspb_proto", "//mediapipe/tasks/web/core", + "//mediapipe/tasks/web/vision/core:image", "//mediapipe/tasks/web/vision/core:image_processing_options", "//mediapipe/tasks/web/vision/core:types", "//mediapipe/tasks/web/vision/core:vision_task_runner", @@ -46,6 +47,7 @@ mediapipe_ts_library( "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", + "//mediapipe/tasks/web/vision/core:image", "//mediapipe/web/graph_runner:graph_runner_image_lib_ts", ], ) diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts index 13558e235..2a9adb315 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts @@ -19,6 +19,7 @@ import {CalculatorOptions} from '../../../../framework/calculator_options_pb'; import {BaseOptions as BaseOptionsProto} from '../../../../tasks/cc/core/proto/base_options_pb'; import {FaceStylizerGraphOptions as FaceStylizerGraphOptionsProto} from '../../../../tasks/cc/vision/face_stylizer/proto/face_stylizer_graph_options_pb'; import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; +import {MPImage} from '../../../../tasks/web/vision/core/image'; import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; import {VisionGraphRunner, VisionTaskRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; import {ImageSource, WasmModule} from '../../../../web/graph_runner/graph_runner'; @@ -39,15 +40,13 @@ const FACE_STYLIZER_GRAPH = // tslint:disable:jspb-use-builder-pattern /** - * A callback that receives an image from the face stylizer, or `null` if no - * face was detected. The lifetime of the underlying data is limited to the - * duration of the callback. If asynchronous processing is needed, all data - * needs to be copied before the callback returns. - * - * The `WebGLTexture` output type is reserved for future usage. + * A callback that receives an `MPImage` object from the face stylizer, or + * `null` if no face was detected. The lifetime of the underlying data is + * limited to the duration of the callback. If asynchronous processing is + * needed, all data needs to be copied before the callback returns (via + * `image.clone()`). */ -export type FaceStylizerCallback = - (image: ImageData|WebGLTexture|null, width: number, height: number) => void; +export type FaceStylizerCallback = (image: MPImage|null) => void; /** Performs face stylization on images. */ export class FaceStylizer extends VisionTaskRunner { @@ -270,18 +269,14 @@ export class FaceStylizer extends VisionTaskRunner { graphConfig.addNode(segmenterNode); this.graphRunner.attachImageListener( - STYLIZED_IMAGE_STREAM, (image, timestamp) => { - if (image.data instanceof WebGLTexture) { - this.userCallback(image.data, image.width, image.height); - } else { - const imageData = this.convertToImageData(image); - this.userCallback(imageData, image.width, image.height); - } + STYLIZED_IMAGE_STREAM, (wasmImage, timestamp) => { + const mpImage = this.convertToMPImage(wasmImage); + this.userCallback(mpImage); this.setLatestOutputTimestamp(timestamp); }); this.graphRunner.attachEmptyPacketListener( STYLIZED_IMAGE_STREAM, timestamp => { - this.userCallback(null, /* width= */ 0, /* height= */ 0); + this.userCallback(null); this.setLatestOutputTimestamp(timestamp); }); diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts index 167fd674e..7d30ef2a9 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts @@ -19,6 +19,7 @@ import 'jasmine'; // Placeholder for internal dependency on encodeByteArray import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; import {addJasmineCustomFloatEqualityTester, createSpyWasmModule, MediapipeTasksFake, SpyWasmModule, verifyGraph, verifyListenersRegistered} from '../../../../tasks/web/core/task_runner_test_utils'; +import {MPImageStorageType} from '../../../../tasks/web/vision/core/image'; import {WasmImage} from '../../../../web/graph_runner/graph_runner_image_lib'; import {FaceStylizer} from './face_stylizer'; @@ -114,11 +115,33 @@ describe('FaceStylizer', () => { }); // Invoke the face stylizeer - faceStylizer.stylize({} as HTMLImageElement, (image, width, height) => { + faceStylizer.stylize({} as HTMLImageElement, image => { expect(faceStylizer.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); - expect(image).toBeInstanceOf(ImageData); - expect(width).toEqual(1); - expect(height).toEqual(1); + expect(image).not.toBeNull(); + expect(image!.hasType(MPImageStorageType.IMAGE_DATA)).toBeTrue(); + expect(image!.width).toEqual(1); + expect(image!.height).toEqual(1); + done(); + }); + }); + + it('invokes callback even when no faes are detected', (done) => { + if (typeof ImageData === 'undefined') { + console.log('ImageData tests are not supported on Node'); + done(); + return; + } + + // Pass the test data to our listener + faceStylizer.fakeWasmModule._waitUntilIdle.and.callFake(() => { + verifyListenersRegistered(faceStylizer); + faceStylizer.emptyPacketListener!(/* timestamp= */ 1337); + }); + + // Invoke the face stylizeer + faceStylizer.stylize({} as HTMLImageElement, image => { + expect(faceStylizer.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); + expect(image).toBeNull(); done(); }); }); @@ -131,11 +154,9 @@ describe('FaceStylizer', () => { }); // Invoke the face stylizeer - faceStylizer.stylize({} as HTMLImageElement, (image, width, height) => { + faceStylizer.stylize({} as HTMLImageElement, image => { expect(faceStylizer.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); expect(image).toBeNull(); - expect(width).toEqual(0); - expect(height).toEqual(0); done(); }); }); diff --git a/mediapipe/tasks/web/vision/index.ts b/mediapipe/tasks/web/vision/index.ts index 2ea0e7278..632a294d6 100644 --- a/mediapipe/tasks/web/vision/index.ts +++ b/mediapipe/tasks/web/vision/index.ts @@ -16,7 +16,7 @@ import {FilesetResolver as FilesetResolverImpl} from '../../../tasks/web/core/fileset_resolver'; import {DrawingUtils as DrawingUtilsImpl} from '../../../tasks/web/vision/core/drawing_utils'; -import {MPImage as MPImageImpl} from '../../../tasks/web/vision/core/image'; +import {MPImage as MPImageImpl, MPImageStorageType as MPImageStorageTypeImpl} from '../../../tasks/web/vision/core/image'; import {FaceDetector as FaceDetectorImpl} from '../../../tasks/web/vision/face_detector/face_detector'; import {FaceLandmarker as FaceLandmarkerImpl, FaceLandmarksConnections as FaceLandmarksConnectionsImpl} from '../../../tasks/web/vision/face_landmarker/face_landmarker'; import {FaceStylizer as FaceStylizerImpl} from '../../../tasks/web/vision/face_stylizer/face_stylizer'; @@ -34,6 +34,7 @@ import {PoseLandmarker as PoseLandmarkerImpl} from '../../../tasks/web/vision/po const DrawingUtils = DrawingUtilsImpl; const FilesetResolver = FilesetResolverImpl; const MPImage = MPImageImpl; +const MPImageStorageType = MPImageStorageTypeImpl; const FaceDetector = FaceDetectorImpl; const FaceLandmarker = FaceLandmarkerImpl; const FaceLandmarksConnections = FaceLandmarksConnectionsImpl; @@ -51,6 +52,7 @@ export { DrawingUtils, FilesetResolver, MPImage, + MPImageStorageType, FaceDetector, FaceLandmarker, FaceLandmarksConnections, diff --git a/mediapipe/tasks/web/vision/types.ts b/mediapipe/tasks/web/vision/types.ts index 1c0466bc1..381052881 100644 --- a/mediapipe/tasks/web/vision/types.ts +++ b/mediapipe/tasks/web/vision/types.ts @@ -16,7 +16,7 @@ export * from '../../../tasks/web/core/fileset_resolver'; export * from '../../../tasks/web/vision/core/drawing_utils'; -export * from '../../../tasks/web/vision/core/image'; +export {MPImage, MPImageChannelConverter, MPImageStorageType} from '../../../tasks/web/vision/core/image'; export * from '../../../tasks/web/vision/face_detector/face_detector'; export * from '../../../tasks/web/vision/face_landmarker/face_landmarker'; export * from '../../../tasks/web/vision/face_stylizer/face_stylizer'; From 2c1d9c6582d78ba099038bb38cc4e6469796d630 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 28 Apr 2023 14:45:32 -0700 Subject: [PATCH 142/753] Update ImageSegmenter to return MPImage PiperOrigin-RevId: 527990991 --- mediapipe/tasks/web/vision/core/BUILD | 1 + .../tasks/web/vision/core/render_utils.ts | 10 +++- .../web/vision/core/vision_task_runner.ts | 46 ++++++++++--------- .../tasks/web/vision/image_segmenter/BUILD | 3 +- .../vision/image_segmenter/image_segmenter.ts | 18 ++------ .../image_segmenter_result.d.ts | 23 ++++------ .../image_segmenter/image_segmenter_test.ts | 34 ++++++++------ 7 files changed, 70 insertions(+), 65 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/BUILD b/mediapipe/tasks/web/vision/core/BUILD index daeef060d..c53247ba7 100644 --- a/mediapipe/tasks/web/vision/core/BUILD +++ b/mediapipe/tasks/web/vision/core/BUILD @@ -91,6 +91,7 @@ mediapipe_ts_library( mediapipe_ts_library( name = "render_utils", srcs = ["render_utils.ts"], + deps = [":image"], ) jasmine_node_test( diff --git a/mediapipe/tasks/web/vision/core/render_utils.ts b/mediapipe/tasks/web/vision/core/render_utils.ts index 13af61761..892cd8645 100644 --- a/mediapipe/tasks/web/vision/core/render_utils.ts +++ b/mediapipe/tasks/web/vision/core/render_utils.ts @@ -16,9 +16,11 @@ * limitations under the License. */ +import {MPImageChannelConverter} from '../../../../tasks/web/vision/core/image'; + // Pre-baked color table for a maximum of 12 classes. const CM_ALPHA = 128; -const COLOR_MAP = [ +const COLOR_MAP: Array<[number, number, number, number]> = [ [0, 0, 0, CM_ALPHA], // class 0 is BG = transparent [255, 0, 0, CM_ALPHA], // class 1 is red [0, 255, 0, CM_ALPHA], // class 2 is light green @@ -74,3 +76,9 @@ export function drawCategoryMask( } ctx.putImageData(new ImageData(rgbaArray, width, height), 0, 0); } + +/** The color converter we use in our demos. */ +export const RENDER_UTIL_CONVERTER: MPImageChannelConverter = { + floatToRGBAConverter: v => [128, 0, 0, v * 255], + uint8ToRGBAConverter: v => COLOR_MAP[v % COLOR_MAP.length], +}; diff --git a/mediapipe/tasks/web/vision/core/vision_task_runner.ts b/mediapipe/tasks/web/vision/core/vision_task_runner.ts index 5099d2960..285dbf900 100644 --- a/mediapipe/tasks/web/vision/core/vision_task_runner.ts +++ b/mediapipe/tasks/web/vision/core/vision_task_runner.ts @@ -231,39 +231,41 @@ export abstract class VisionTaskRunner extends TaskRunner { */ protected convertToMPImage(wasmImage: WasmImage): MPImage { const {data, width, height} = wasmImage; + const pixels = width * height; + let container: ImageData|WebGLTexture|Uint8ClampedArray; if (data instanceof Uint8ClampedArray) { - let rgba: Uint8ClampedArray; - if (data.length === width * height * 4) { - rgba = data; - } else if (data.length === width * height * 3) { + if (data.length === pixels) { + container = data; // Mask + } else if (data.length === pixels * 3) { // TODO: Convert in C++ - rgba = new Uint8ClampedArray(width * height * 4); - for (let i = 0; i < width * height; ++i) { + const rgba = new Uint8ClampedArray(pixels * 4); + for (let i = 0; i < pixels; ++i) { rgba[4 * i] = data[3 * i]; rgba[4 * i + 1] = data[3 * i + 1]; rgba[4 * i + 2] = data[3 * i + 2]; rgba[4 * i + 3] = 255; } + container = new ImageData(rgba, width, height); + } else if (data.length ===pixels * 4) { + container = new ImageData(data, width, height); } else { - throw new Error( - `Unsupported channel count: ${data.length / width / height}`); + throw new Error(`Unsupported channel count: ${data.length/pixels}`); } - - return new MPImage( - [new ImageData(rgba, width, height)], - /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, - this.graphRunner.wasmModule.canvas!, this.shaderContext, width, - height); - } else if (data instanceof WebGLTexture) { - return new MPImage( - [data], /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, - this.graphRunner.wasmModule.canvas!, this.shaderContext, width, - height); - } else { - throw new Error( - `Cannot convert type ${data.constructor.name} to MPImage.`); + } else if (data instanceof Float32Array) { + if (data.length === pixels) { + container = data; // Mask + } else { + throw new Error(`Unsupported channel count: ${data.length/pixels}`); + } + } else { // WebGLTexture + container = data; } + + return new MPImage( + [container], /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, + this.graphRunner.wasmModule.canvas!, this.shaderContext, width, + height); } /** Closes and cleans up the resources held by this task. */ diff --git a/mediapipe/tasks/web/vision/image_segmenter/BUILD b/mediapipe/tasks/web/vision/image_segmenter/BUILD index 3db15641f..6c1829bd3 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/BUILD +++ b/mediapipe/tasks/web/vision/image_segmenter/BUILD @@ -20,7 +20,6 @@ mediapipe_ts_library( "//mediapipe/tasks/cc/vision/image_segmenter/proto:segmenter_options_jspb_proto", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/vision/core:image_processing_options", - "//mediapipe/tasks/web/vision/core:types", "//mediapipe/tasks/web/vision/core:vision_task_runner", "//mediapipe/util:label_map_jspb_proto", "//mediapipe/web/graph_runner:graph_runner_ts", @@ -36,6 +35,7 @@ mediapipe_ts_declaration( deps = [ "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:classifier_options", + "//mediapipe/tasks/web/vision/core:image", "//mediapipe/tasks/web/vision/core:vision_task_options", ], ) @@ -52,6 +52,7 @@ mediapipe_ts_library( "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", + "//mediapipe/tasks/web/vision/core:image", "//mediapipe/web/graph_runner:graph_runner_image_lib_ts", ], ) diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts index 4089a2b17..924628158 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts @@ -22,7 +22,6 @@ import {ImageSegmenterGraphOptions as ImageSegmenterGraphOptionsProto} from '../ import {SegmenterOptions as SegmenterOptionsProto} from '../../../../tasks/cc/vision/image_segmenter/proto/segmenter_options_pb'; import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; -import {SegmentationMask} from '../../../../tasks/web/vision/core/types'; import {VisionGraphRunner, VisionTaskRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; import {LabelMapItem} from '../../../../util/label_map_pb'; import {ImageSource, WasmModule} from '../../../../web/graph_runner/graph_runner'; @@ -33,7 +32,6 @@ import {ImageSegmenterResult} from './image_segmenter_result'; export * from './image_segmenter_options'; export * from './image_segmenter_result'; -export {SegmentationMask}; export {ImageSource}; // Used in the public API const IMAGE_STREAM = 'image_in'; @@ -60,7 +58,7 @@ export type ImageSegmenterCallback = (result: ImageSegmenterResult) => void; /** Performs image segmentation on images. */ export class ImageSegmenter extends VisionTaskRunner { - private result: ImageSegmenterResult = {width: 0, height: 0}; + private result: ImageSegmenterResult = {}; private labels: string[] = []; private outputCategoryMask = DEFAULT_OUTPUT_CATEGORY_MASK; private outputConfidenceMasks = DEFAULT_OUTPUT_CONFIDENCE_MASKS; @@ -313,7 +311,7 @@ export class ImageSegmenter extends VisionTaskRunner { } private reset(): void { - this.result = {width: 0, height: 0}; + this.result = {}; } /** Updates the MediaPipe graph configuration. */ @@ -341,12 +339,8 @@ export class ImageSegmenter extends VisionTaskRunner { this.graphRunner.attachImageVectorListener( CONFIDENCE_MASKS_STREAM, (masks, timestamp) => { - this.result.confidenceMasks = masks.map(m => m.data); - if (masks.length >= 0) { - this.result.width = masks[0].width; - this.result.height = masks[0].height; - } - + this.result.confidenceMasks = + masks.map(wasmImage => this.convertToMPImage(wasmImage)); this.setLatestOutputTimestamp(timestamp); }); this.graphRunner.attachEmptyPacketListener( @@ -361,9 +355,7 @@ export class ImageSegmenter extends VisionTaskRunner { this.graphRunner.attachImageListener( CATEGORY_MASK_STREAM, (mask, timestamp) => { - this.result.categoryMask = mask.data; - this.result.width = mask.width; - this.result.height = mask.height; + this.result.categoryMask = this.convertToMPImage(mask); this.setLatestOutputTimestamp(timestamp); }); this.graphRunner.attachEmptyPacketListener( diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts index b731e032d..454ec27ea 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts @@ -14,24 +14,21 @@ * limitations under the License. */ +import {MPImage} from '../../../../tasks/web/vision/core/image'; + /** The output result of ImageSegmenter. */ export declare interface ImageSegmenterResult { /** - * Multiple masks as Float32Arrays or WebGLTextures where, for each mask, each - * pixel represents the prediction confidence, usually in the [0, 1] range. + * Multiple masks represented as `Float32Array` or `WebGLTexture`-backed + * `MPImage`s where, for each mask, each pixel represents the prediction + * confidence, usually in the [0, 1] range. */ - confidenceMasks?: Float32Array[]|WebGLTexture[]; + confidenceMasks?: MPImage[]; /** - * A category mask as a Uint8ClampedArray or WebGLTexture where each - * pixel represents the class which the pixel in the original image was - * predicted to belong to. + * A category mask represented as a `Uint8ClampedArray` or + * `WebGLTexture`-backed `MPImage` where each pixel represents the class which + * the pixel in the original image was predicted to belong to. */ - categoryMask?: Uint8ClampedArray|WebGLTexture; - - /** The width of the masks. */ - width: number; - - /** The height of the masks. */ - height: number; + categoryMask?: MPImage; } diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts index 1327c1b3c..7f7f19069 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts @@ -20,6 +20,7 @@ import 'jasmine'; import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; import {addJasmineCustomFloatEqualityTester, createSpyWasmModule, MediapipeTasksFake, SpyWasmModule, verifyGraph} from '../../../../tasks/web/core/task_runner_test_utils'; import {WasmImage} from '../../../../web/graph_runner/graph_runner_image_lib'; +import {MPImage} from '../../../../tasks/web/vision/core/image'; import {ImageSegmenter} from './image_segmenter'; import {ImageSegmenterOptions} from './image_segmenter_options'; @@ -182,10 +183,10 @@ describe('ImageSegmenter', () => { return new Promise(resolve => { imageSegmenter.segment({} as HTMLImageElement, result => { expect(imageSegmenter.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); - expect(result.categoryMask).toEqual(mask); + expect(result.categoryMask).toBeInstanceOf(MPImage); expect(result.confidenceMasks).not.toBeDefined(); - expect(result.width).toEqual(2); - expect(result.height).toEqual(2); + expect(result.categoryMask!.width).toEqual(2); + expect(result.categoryMask!.height).toEqual(2); resolve(); }); }); @@ -214,18 +215,21 @@ describe('ImageSegmenter', () => { imageSegmenter.segment({} as HTMLImageElement, result => { expect(imageSegmenter.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); expect(result.categoryMask).not.toBeDefined(); - expect(result.confidenceMasks).toEqual([mask1, mask2]); - expect(result.width).toEqual(2); - expect(result.height).toEqual(2); + + expect(result.confidenceMasks![0]).toBeInstanceOf(MPImage); + expect(result.confidenceMasks![0].width).toEqual(2); + expect(result.confidenceMasks![0].height).toEqual(2); + + expect(result.confidenceMasks![1]).toBeInstanceOf(MPImage); resolve(); }); }); }); it('supports combined category and confidence masks', async () => { - const categoryMask = new Uint8ClampedArray([1, 0]); - const confidenceMask1 = new Float32Array([0.0, 1.0]); - const confidenceMask2 = new Float32Array([1.0, 0.0]); + const categoryMask = new Uint8ClampedArray([1]); + const confidenceMask1 = new Float32Array([0.0]); + const confidenceMask2 = new Float32Array([1.0]); await imageSegmenter.setOptions( {outputCategoryMask: true, outputConfidenceMasks: true}); @@ -248,12 +252,12 @@ describe('ImageSegmenter', () => { // Invoke the image segmenter imageSegmenter.segment({} as HTMLImageElement, result => { expect(imageSegmenter.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); - expect(result.categoryMask).toEqual(categoryMask); - expect(result.confidenceMasks).toEqual([ - confidenceMask1, confidenceMask2 - ]); - expect(result.width).toEqual(1); - expect(result.height).toEqual(1); + expect(result.categoryMask).toBeInstanceOf(MPImage); + expect(result.categoryMask!.width).toEqual(1); + expect(result.categoryMask!.height).toEqual(1); + + expect(result.confidenceMasks![0]).toBeInstanceOf(MPImage); + expect(result.confidenceMasks![1]).toBeInstanceOf(MPImage); resolve(); }); }); From dcef6df1cbf5be95fc7f74b714d328c3b73aa7a9 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 28 Apr 2023 16:11:34 -0700 Subject: [PATCH 143/753] Update InteractiveSegmenter to return MPImage PiperOrigin-RevId: 528010944 --- .../tasks/web/vision/core/render_utils.ts | 32 ++--------------- mediapipe/tasks/web/vision/core/types.d.ts | 10 ------ .../web/vision/interactive_segmenter/BUILD | 2 ++ .../interactive_segmenter.ts | 20 ++++------- .../interactive_segmenter_result.d.ts | 23 ++++++------- .../interactive_segmenter_test.ts | 34 +++++++++++-------- 6 files changed, 40 insertions(+), 81 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/render_utils.ts b/mediapipe/tasks/web/vision/core/render_utils.ts index 892cd8645..066494f57 100644 --- a/mediapipe/tasks/web/vision/core/render_utils.ts +++ b/mediapipe/tasks/web/vision/core/render_utils.ts @@ -35,11 +35,10 @@ const COLOR_MAP: Array<[number, number, number, number]> = [ [255, 255, 255, CM_ALPHA] // class 11 is white; could do black instead? ]; - /** Helper function to draw a confidence mask */ export function drawConfidenceMask( - ctx: CanvasRenderingContext2D, image: Float32Array, width: number, - height: number): void { + ctx: CanvasRenderingContext2D, image: Float32Array, width: number, + height: number): void { const uint8ClampedArray = new Uint8ClampedArray(width * height * 4); for (let i = 0; i < image.length; i++) { uint8ClampedArray[4 * i] = 128; @@ -50,33 +49,6 @@ export function drawConfidenceMask( ctx.putImageData(new ImageData(uint8ClampedArray, width, height), 0, 0); } -/** - * Helper function to draw a category mask. For GPU, we only have F32Arrays - * for now. - */ -export function drawCategoryMask( - ctx: CanvasRenderingContext2D, image: Uint8ClampedArray|Float32Array, - width: number, height: number): void { - const rgbaArray = new Uint8ClampedArray(width * height * 4); - const isFloatArray = image instanceof Float32Array; - for (let i = 0; i < image.length; i++) { - const colorIndex = isFloatArray ? Math.round(image[i] * 255) : image[i]; - let color = COLOR_MAP[colorIndex % COLOR_MAP.length]; - - if (!color) { - // TODO: We should fix this. - console.warn('No color for ', colorIndex); - color = COLOR_MAP[colorIndex % COLOR_MAP.length]; - } - - rgbaArray[4 * i] = color[0]; - rgbaArray[4 * i + 1] = color[1]; - rgbaArray[4 * i + 2] = color[2]; - rgbaArray[4 * i + 3] = color[3]; - } - ctx.putImageData(new ImageData(rgbaArray, width, height), 0, 0); -} - /** The color converter we use in our demos. */ export const RENDER_UTIL_CONVERTER: MPImageChannelConverter = { floatToRGBAConverter: v => [128, 0, 0, v * 255], diff --git a/mediapipe/tasks/web/vision/core/types.d.ts b/mediapipe/tasks/web/vision/core/types.d.ts index 1cc2e36fd..c985a9f36 100644 --- a/mediapipe/tasks/web/vision/core/types.d.ts +++ b/mediapipe/tasks/web/vision/core/types.d.ts @@ -16,16 +16,6 @@ import {NormalizedKeypoint} from '../../../../tasks/web/components/containers/keypoint'; -/** - * The segmentation tasks return the segmentation either as a WebGLTexture (when - * the output is on GPU) or as a typed JavaScript arrays for CPU-based - * category or confidence masks. `Uint8ClampedArray`s are used to represent - * CPU-based category masks and `Float32Array`s are used for CPU-based - * confidence masks. - */ -export type SegmentationMask = Uint8ClampedArray|Float32Array|WebGLTexture; - - /** A Region-Of-Interest (ROI) to represent a region within an image. */ export declare interface RegionOfInterest { /** The ROI in keypoint format. */ diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/BUILD b/mediapipe/tasks/web/vision/interactive_segmenter/BUILD index ead85d38a..c3be79ebf 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/BUILD +++ b/mediapipe/tasks/web/vision/interactive_segmenter/BUILD @@ -37,6 +37,7 @@ mediapipe_ts_declaration( deps = [ "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:classifier_options", + "//mediapipe/tasks/web/vision/core:image", "//mediapipe/tasks/web/vision/core:vision_task_options", ], ) @@ -53,6 +54,7 @@ mediapipe_ts_library( "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", + "//mediapipe/tasks/web/vision/core:image", "//mediapipe/util:render_data_jspb_proto", "//mediapipe/web/graph_runner:graph_runner_image_lib_ts", ], diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts index 70d2c1f4e..f127792ce 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts @@ -21,7 +21,7 @@ import {ImageSegmenterGraphOptions as ImageSegmenterGraphOptionsProto} from '../ import {SegmenterOptions as SegmenterOptionsProto} from '../../../../tasks/cc/vision/image_segmenter/proto/segmenter_options_pb'; import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; -import {RegionOfInterest, SegmentationMask} from '../../../../tasks/web/vision/core/types'; +import {RegionOfInterest} from '../../../../tasks/web/vision/core/types'; import {VisionGraphRunner, VisionTaskRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; import {Color as ColorProto} from '../../../../util/color_pb'; import {RenderAnnotation as RenderAnnotationProto, RenderData as RenderDataProto} from '../../../../util/render_data_pb'; @@ -33,7 +33,7 @@ import {InteractiveSegmenterResult} from './interactive_segmenter_result'; export * from './interactive_segmenter_options'; export * from './interactive_segmenter_result'; -export {SegmentationMask, RegionOfInterest}; +export {RegionOfInterest}; export {ImageSource}; const IMAGE_IN_STREAM = 'image_in'; @@ -83,7 +83,7 @@ export type InteractiveSegmenterCallback = * - batch is always 1 */ export class InteractiveSegmenter extends VisionTaskRunner { - private result: InteractiveSegmenterResult = {width: 0, height: 0}; + private result: InteractiveSegmenterResult = {}; private outputCategoryMask = DEFAULT_OUTPUT_CATEGORY_MASK; private outputConfidenceMasks = DEFAULT_OUTPUT_CONFIDENCE_MASKS; private readonly options: ImageSegmenterGraphOptionsProto; @@ -253,7 +253,7 @@ export class InteractiveSegmenter extends VisionTaskRunner { } private reset(): void { - this.result = {width: 0, height: 0}; + this.result = {}; } /** Updates the MediaPipe graph configuration. */ @@ -283,12 +283,8 @@ export class InteractiveSegmenter extends VisionTaskRunner { this.graphRunner.attachImageVectorListener( CONFIDENCE_MASKS_STREAM, (masks, timestamp) => { - this.result.confidenceMasks = masks.map(m => m.data); - if (masks.length >= 0) { - this.result.width = masks[0].width; - this.result.height = masks[0].height; - } - + this.result.confidenceMasks = + masks.map(wasmImage => this.convertToMPImage(wasmImage)); this.setLatestOutputTimestamp(timestamp); }); this.graphRunner.attachEmptyPacketListener( @@ -303,9 +299,7 @@ export class InteractiveSegmenter extends VisionTaskRunner { this.graphRunner.attachImageListener( CATEGORY_MASK_STREAM, (mask, timestamp) => { - this.result.categoryMask = mask.data; - this.result.width = mask.width; - this.result.height = mask.height; + this.result.categoryMask = this.convertToMPImage(mask); this.setLatestOutputTimestamp(timestamp); }); this.graphRunner.attachEmptyPacketListener( diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts index f1f134a77..bc2962936 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts @@ -14,24 +14,21 @@ * limitations under the License. */ +import {MPImage} from '../../../../tasks/web/vision/core/image'; + /** The output result of InteractiveSegmenter. */ export declare interface InteractiveSegmenterResult { /** - * Multiple masks as Float32Arrays or WebGLTextures where, for each mask, each - * pixel represents the prediction confidence, usually in the [0, 1] range. + * Multiple masks represented as `Float32Array` or `WebGLTexture`-backed + * `MPImage`s where, for each mask, each pixel represents the prediction + * confidence, usually in the [0, 1] range. */ - confidenceMasks?: Float32Array[]|WebGLTexture[]; + confidenceMasks?: MPImage[]; /** - * A category mask as a Uint8ClampedArray or WebGLTexture where each - * pixel represents the class which the pixel in the original image was - * predicted to belong to. + * A category mask represented as a `Uint8ClampedArray` or + * `WebGLTexture`-backed `MPImage` where each pixel represents the class which + * the pixel in the original image was predicted to belong to. */ - categoryMask?: Uint8ClampedArray|WebGLTexture; - - /** The width of the masks. */ - width: number; - - /** The height of the masks. */ - height: number; + categoryMask?: MPImage; } diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts index 0a9477605..cbaf76630 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts @@ -19,6 +19,7 @@ import 'jasmine'; // Placeholder for internal dependency on encodeByteArray import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; import {addJasmineCustomFloatEqualityTester, createSpyWasmModule, MediapipeTasksFake, SpyWasmModule, verifyGraph} from '../../../../tasks/web/core/task_runner_test_utils'; +import {MPImage} from '../../../../tasks/web/vision/core/image'; import {RenderData as RenderDataProto} from '../../../../util/render_data_pb'; import {WasmImage} from '../../../../web/graph_runner/graph_runner_image_lib'; @@ -170,10 +171,10 @@ describe('InteractiveSegmenter', () => { interactiveSegmenter.segment({} as HTMLImageElement, ROI, result => { expect(interactiveSegmenter.fakeWasmModule._waitUntilIdle) .toHaveBeenCalled(); - expect(result.categoryMask).toEqual(mask); + expect(result.categoryMask).toBeInstanceOf(MPImage); + expect(result.categoryMask!.width).toEqual(2); + expect(result.categoryMask!.height).toEqual(2); expect(result.confidenceMasks).not.toBeDefined(); - expect(result.width).toEqual(2); - expect(result.height).toEqual(2); resolve(); }); }); @@ -202,18 +203,21 @@ describe('InteractiveSegmenter', () => { expect(interactiveSegmenter.fakeWasmModule._waitUntilIdle) .toHaveBeenCalled(); expect(result.categoryMask).not.toBeDefined(); - expect(result.confidenceMasks).toEqual([mask1, mask2]); - expect(result.width).toEqual(2); - expect(result.height).toEqual(2); + + expect(result.confidenceMasks![0]).toBeInstanceOf(MPImage); + expect(result.confidenceMasks![0].width).toEqual(2); + expect(result.confidenceMasks![0].height).toEqual(2); + + expect(result.confidenceMasks![1]).toBeInstanceOf(MPImage); resolve(); }); }); }); it('supports combined category and confidence masks', async () => { - const categoryMask = new Uint8ClampedArray([1, 0]); - const confidenceMask1 = new Float32Array([0.0, 1.0]); - const confidenceMask2 = new Float32Array([1.0, 0.0]); + const categoryMask = new Uint8ClampedArray([1]); + const confidenceMask1 = new Float32Array([0.0]); + const confidenceMask2 = new Float32Array([1.0]); await interactiveSegmenter.setOptions( {outputCategoryMask: true, outputConfidenceMasks: true}); @@ -238,12 +242,12 @@ describe('InteractiveSegmenter', () => { {} as HTMLImageElement, ROI, result => { expect(interactiveSegmenter.fakeWasmModule._waitUntilIdle) .toHaveBeenCalled(); - expect(result.categoryMask).toEqual(categoryMask); - expect(result.confidenceMasks).toEqual([ - confidenceMask1, confidenceMask2 - ]); - expect(result.width).toEqual(1); - expect(result.height).toEqual(1); + expect(result.categoryMask).toBeInstanceOf(MPImage); + expect(result.categoryMask!.width).toEqual(1); + expect(result.categoryMask!.height).toEqual(1); + + expect(result.confidenceMasks![0]).toBeInstanceOf(MPImage); + expect(result.confidenceMasks![1]).toBeInstanceOf(MPImage); resolve(); }); }); From 874cc9dea36e1aef9c6f0cfd3c48d3cdc1dc6d3a Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 28 Apr 2023 17:11:03 -0700 Subject: [PATCH 144/753] Update PoseLandmarker to return MPImage PiperOrigin-RevId: 528022223 --- mediapipe/tasks/web/vision/core/render_utils.ts | 14 -------------- mediapipe/tasks/web/vision/pose_landmarker/BUILD | 2 ++ .../web/vision/pose_landmarker/pose_landmarker.ts | 2 +- .../pose_landmarker/pose_landmarker_result.d.ts | 3 ++- .../vision/pose_landmarker/pose_landmarker_test.ts | 11 +++++------ 5 files changed, 10 insertions(+), 22 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/render_utils.ts b/mediapipe/tasks/web/vision/core/render_utils.ts index 066494f57..05f2a4df1 100644 --- a/mediapipe/tasks/web/vision/core/render_utils.ts +++ b/mediapipe/tasks/web/vision/core/render_utils.ts @@ -35,20 +35,6 @@ const COLOR_MAP: Array<[number, number, number, number]> = [ [255, 255, 255, CM_ALPHA] // class 11 is white; could do black instead? ]; -/** Helper function to draw a confidence mask */ -export function drawConfidenceMask( - ctx: CanvasRenderingContext2D, image: Float32Array, width: number, - height: number): void { - const uint8ClampedArray = new Uint8ClampedArray(width * height * 4); - for (let i = 0; i < image.length; i++) { - uint8ClampedArray[4 * i] = 128; - uint8ClampedArray[4 * i + 1] = 0; - uint8ClampedArray[4 * i + 2] = 0; - uint8ClampedArray[4 * i + 3] = image[i] * 255; - } - ctx.putImageData(new ImageData(uint8ClampedArray, width, height), 0, 0); -} - /** The color converter we use in our demos. */ export const RENDER_UTIL_CONVERTER: MPImageChannelConverter = { floatToRGBAConverter: v => [128, 0, 0, v * 255], diff --git a/mediapipe/tasks/web/vision/pose_landmarker/BUILD b/mediapipe/tasks/web/vision/pose_landmarker/BUILD index 932fce8bc..8d128ac1a 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/BUILD +++ b/mediapipe/tasks/web/vision/pose_landmarker/BUILD @@ -45,6 +45,7 @@ mediapipe_ts_declaration( "//mediapipe/tasks/web/components/containers:category", "//mediapipe/tasks/web/components/containers:landmark", "//mediapipe/tasks/web/core", + "//mediapipe/tasks/web/vision/core:image", "//mediapipe/tasks/web/vision/core:vision_task_options", ], ) @@ -62,6 +63,7 @@ mediapipe_ts_library( "//mediapipe/tasks/web/components/processors:landmark_result", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", + "//mediapipe/tasks/web/vision/core:image", "//mediapipe/tasks/web/vision/core:vision_task_runner", ], ) diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts index 0b119780c..44effa879 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts @@ -417,7 +417,7 @@ export class PoseLandmarker extends VisionTaskRunner { this.graphRunner.attachImageVectorListener( SEGMENTATION_MASK_STREAM, (masks, timestamp) => { this.result.segmentationMasks = - masks.map(m => m.data) as Float32Array[] | WebGLBuffer[]; + masks.map(wasmImage => this.convertToMPImage(wasmImage)); this.setLatestOutputTimestamp(timestamp); }); this.graphRunner.attachEmptyPacketListener( diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts index 4ddd085df..66d0498a6 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts @@ -16,6 +16,7 @@ import {Category} from '../../../../tasks/web/components/containers/category'; import {Landmark, NormalizedLandmark} from '../../../../tasks/web/components/containers/landmark'; +import {MPImage} from '../../../../tasks/web/vision/core/image'; export {Category, Landmark, NormalizedLandmark}; @@ -34,5 +35,5 @@ export declare interface PoseLandmarkerResult { auxilaryLandmarks: NormalizedLandmark[]; /** Segmentation mask for the detected pose. */ - segmentationMasks?: Float32Array[]|WebGLTexture[]; + segmentationMasks?: MPImage[]; } diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts index 1a5afba50..2d76f656f 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts @@ -18,6 +18,7 @@ import 'jasmine'; import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; import {createLandmarks, createWorldLandmarks} from '../../../../tasks/web/components/processors/landmark_result_test_lib'; import {addJasmineCustomFloatEqualityTester, createSpyWasmModule, MediapipeTasksFake, SpyWasmModule, verifyGraph} from '../../../../tasks/web/core/task_runner_test_utils'; +import {MPImage} from '../../../../tasks/web/vision/core/image'; import {VisionGraphRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; import {PoseLandmarker} from './pose_landmarker'; @@ -221,12 +222,10 @@ describe('PoseLandmarker', () => { .toHaveBeenCalledTimes(1); expect(poseLandmarker.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); - expect(result).toEqual({ - 'landmarks': [{'x': 0, 'y': 0, 'z': 0}], - 'worldLandmarks': [{'x': 0, 'y': 0, 'z': 0}], - 'auxilaryLandmarks': [{'x': 0, 'y': 0, 'z': 0}], - 'segmentationMasks': [new Float32Array([0, 1, 2, 3])], - }); + expect(result.landmarks).toEqual([{'x': 0, 'y': 0, 'z': 0}]); + expect(result.worldLandmarks).toEqual([{'x': 0, 'y': 0, 'z': 0}]); + expect(result.auxilaryLandmarks).toEqual([{'x': 0, 'y': 0, 'z': 0}]); + expect(result.segmentationMasks![0]).toBeInstanceOf(MPImage); done(); }); }); From b1f93b3b2785b5e056bc31b11342b660659688f6 Mon Sep 17 00:00:00 2001 From: Esha Uboweja Date: Fri, 28 Apr 2023 17:23:08 -0700 Subject: [PATCH 145/753] Fixes `HAND_ROIS_FROM_LANDMARKS` output to be `hand_rects_from_landmarks` output stream. PiperOrigin-RevId: 528024796 --- .../modules/hand_landmark/hand_landmark_tracking_cpu.pbtxt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/modules/hand_landmark/hand_landmark_tracking_cpu.pbtxt b/mediapipe/modules/hand_landmark/hand_landmark_tracking_cpu.pbtxt index 2ee8316d5..1d322665e 100644 --- a/mediapipe/modules/hand_landmark/hand_landmark_tracking_cpu.pbtxt +++ b/mediapipe/modules/hand_landmark/hand_landmark_tracking_cpu.pbtxt @@ -56,7 +56,7 @@ output_stream: "HANDEDNESS:multi_handedness" output_stream: "PALM_DETECTIONS:palm_detections" # Regions of interest calculated based on landmarks. # (std::vector) -output_stream: "HAND_ROIS_FROM_LANDMARKS:hand_rects" +output_stream: "HAND_ROIS_FROM_LANDMARKS:hand_rects_from_landmarks" # Regions of interest calculated based on palm detections. # (std::vector) output_stream: "HAND_ROIS_FROM_PALM_DETECTIONS:hand_rects_from_palm_detections" From e15add2475161f709157606e93936a1029edd60c Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 28 Apr 2023 18:58:26 -0700 Subject: [PATCH 146/753] Shorten MPImage API PiperOrigin-RevId: 528039371 --- mediapipe/tasks/web/vision/core/image.test.ts | 80 +++++------ mediapipe/tasks/web/vision/core/image.ts | 129 ++++++++---------- .../face_stylizer/face_stylizer_test.ts | 4 +- mediapipe/tasks/web/vision/index.ts | 6 +- mediapipe/tasks/web/vision/types.ts | 2 +- 5 files changed, 105 insertions(+), 116 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/image.test.ts b/mediapipe/tasks/web/vision/core/image.test.ts index e991aa7dc..73eb44240 100644 --- a/mediapipe/tasks/web/vision/core/image.test.ts +++ b/mediapipe/tasks/web/vision/core/image.test.ts @@ -16,7 +16,7 @@ import 'jasmine'; -import {MPImage, MPImageShaderContext, MPImageStorageType} from './image'; +import {MPImage, MPImageShaderContext, MPImageType} from './image'; const WIDTH = 2; const HEIGHT = 2; @@ -130,20 +130,20 @@ class MPImageTestContext { function assertEquality(image: MPImage, expected: ImageType): void { if (expected instanceof Uint8ClampedArray) { - const result = image.getImage(MPImageStorageType.UINT8_CLAMPED_ARRAY); + const result = image.get(MPImageType.UINT8_CLAMPED_ARRAY); expect(result).toEqual(expected); } else if (expected instanceof Float32Array) { - const result = image.getImage(MPImageStorageType.FLOAT32_ARRAY); + const result = image.get(MPImageType.FLOAT32_ARRAY); expect(result).toEqual(expected); } else if (expected instanceof ImageData) { - const result = image.getImage(MPImageStorageType.IMAGE_DATA); + const result = image.get(MPImageType.IMAGE_DATA); expect(result).toEqual(expected); } else if (expected instanceof ImageBitmap) { - const result = image.getImage(MPImageStorageType.IMAGE_BITMAP); + const result = image.get(MPImageType.IMAGE_BITMAP); expect(readPixelsFromImageBitmap(result)) .toEqual(readPixelsFromImageBitmap(expected)); } else { // WebGLTexture - const result = image.getImage(MPImageStorageType.WEBGL_TEXTURE); + const result = image.get(MPImageType.WEBGL_TEXTURE); expect(readPixelsFromWebGLTexture(result)) .toEqual(readPixelsFromWebGLTexture(expected)); } @@ -206,7 +206,7 @@ class MPImageTestContext { /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, context.canvas, shaderContext, WIDTH, HEIGHT); - const result = image.clone().getImage(MPImageStorageType.IMAGE_DATA); + const result = image.clone().get(MPImageType.IMAGE_DATA); expect(result).toEqual(context.imageData); shaderContext.close(); @@ -223,61 +223,61 @@ class MPImageTestContext { // Verify that we can mix the different shader modes by running them out of // order. - let result = image.getImage(MPImageStorageType.IMAGE_DATA); + let result = image.get(MPImageType.IMAGE_DATA); expect(result).toEqual(context.imageData); - result = image.clone().getImage(MPImageStorageType.IMAGE_DATA); + result = image.clone().get(MPImageType.IMAGE_DATA); expect(result).toEqual(context.imageData); - result = image.getImage(MPImageStorageType.IMAGE_DATA); + result = image.get(MPImageType.IMAGE_DATA); expect(result).toEqual(context.imageData); shaderContext.close(); }); - it('supports hasType()', async () => { + it('supports has()', async () => { await context.init(); const shaderContext = new MPImageShaderContext(); const image = createImage(shaderContext, context.imageData, WIDTH, HEIGHT); - expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); - expect(image.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)).toBe(false); - expect(image.hasType(MPImageStorageType.FLOAT32_ARRAY)).toBe(false); - expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(false); - expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false); + expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); + expect(image.has(MPImageType.UINT8_CLAMPED_ARRAY)).toBe(false); + expect(image.has(MPImageType.FLOAT32_ARRAY)).toBe(false); + expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(false); + expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(false); - image.getImage(MPImageStorageType.UINT8_CLAMPED_ARRAY); + image.get(MPImageType.UINT8_CLAMPED_ARRAY); - expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); - expect(image.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)).toBe(true); - expect(image.hasType(MPImageStorageType.FLOAT32_ARRAY)).toBe(false); - expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(false); - expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false); + expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); + expect(image.has(MPImageType.UINT8_CLAMPED_ARRAY)).toBe(true); + expect(image.has(MPImageType.FLOAT32_ARRAY)).toBe(false); + expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(false); + expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(false); - image.getImage(MPImageStorageType.FLOAT32_ARRAY); + image.get(MPImageType.FLOAT32_ARRAY); - expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); - expect(image.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)).toBe(true); - expect(image.hasType(MPImageStorageType.FLOAT32_ARRAY)).toBe(true); - expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(false); - expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false); + expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); + expect(image.has(MPImageType.UINT8_CLAMPED_ARRAY)).toBe(true); + expect(image.has(MPImageType.FLOAT32_ARRAY)).toBe(true); + expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(false); + expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(false); - image.getImage(MPImageStorageType.WEBGL_TEXTURE); + image.get(MPImageType.WEBGL_TEXTURE); - expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); - expect(image.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)).toBe(true); - expect(image.hasType(MPImageStorageType.FLOAT32_ARRAY)).toBe(true); - expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(true); - expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false); + expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); + expect(image.has(MPImageType.UINT8_CLAMPED_ARRAY)).toBe(true); + expect(image.has(MPImageType.FLOAT32_ARRAY)).toBe(true); + expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(true); + expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(false); - image.getImage(MPImageStorageType.IMAGE_BITMAP); + image.get(MPImageType.IMAGE_BITMAP); - expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true); - expect(image.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)).toBe(true); - expect(image.hasType(MPImageStorageType.FLOAT32_ARRAY)).toBe(true); - expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(true); - expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(true); + expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); + expect(image.has(MPImageType.UINT8_CLAMPED_ARRAY)).toBe(true); + expect(image.has(MPImageType.FLOAT32_ARRAY)).toBe(true); + expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(true); + expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(true); image.close(); shaderContext.close(); diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index 7a12a923b..3927b910f 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -15,7 +15,7 @@ */ /** The underlying type of the image. */ -export enum MPImageStorageType { +export enum MPImageType { /** Represents the native `UInt8ClampedArray` type. */ UINT8_CLAMPED_ARRAY, /** @@ -31,7 +31,7 @@ export enum MPImageStorageType { } /** The supported image formats. For internal usage. */ -export type MPImageNativeContainer = +export type MPImageContainer = Uint8ClampedArray|Float32Array|ImageData|ImageBitmap|WebGLTexture; const VERTEX_SHADER = ` @@ -359,9 +359,9 @@ const DEFAULT_CONVERTER: Required = { * * Images are stored as `ImageData`, `ImageBitmap` or `WebGLTexture` objects. * You can convert the underlying type to any other type by passing the - * desired type to `getImage()`. As type conversions can be expensive, it is + * desired type to `get()`. As type conversions can be expensive, it is * recommended to limit these conversions. You can verify what underlying - * types are already available by invoking `hasType()`. + * types are already available by invoking `has()`. * * Images that are returned from a MediaPipe Tasks are owned by by the * underlying C++ Task. If you need to extend the lifetime of these objects, @@ -379,15 +379,18 @@ const DEFAULT_CONVERTER: Required = { * single-channel arrays). To convert these type to other formats a conversion * function is invoked to convert pixel values between single channel and four * channel RGBA values. To customize this conversion, you can specify these - * conversion functions when you invoke `getImage()`. If you use the default + * conversion functions when you invoke `get()`. If you use the default * conversion function a warning will be logged to the console. */ export class MPImage { private gl?: WebGL2RenderingContext; + /** The underlying type of the image. */ + static TYPE = MPImageType; + /** @hideconstructor */ constructor( - private readonly containers: MPImageNativeContainer[], + private readonly containers: MPImageContainer[], private ownsImageBitmap: boolean, private ownsWebGLTexture: boolean, /** Returns the canvas element that the image is bound to. */ @@ -402,9 +405,9 @@ export class MPImage { /** * Returns whether this `MPImage` stores the image in the desired format. * This method can be called to reduce expensive conversion before invoking - * `getType()`. + * `get()`. */ - hasType(type: MPImageStorageType): boolean { + has(type: MPImageType): boolean { return !!this.getContainer(type); } @@ -421,8 +424,7 @@ export class MPImage { * function if the requested conversion does not change the pixel format. * @return The current data as a Uint8ClampedArray. */ - getImage( - type: MPImageStorageType.UINT8_CLAMPED_ARRAY, + get(type: MPImageType.UINT8_CLAMPED_ARRAY, converter?: MPImageChannelConverter): Uint8ClampedArray; /** * Returns the underlying image as a single channel `Float32Array`. Note @@ -437,8 +439,7 @@ export class MPImage { * function if the requested conversion does not change the pixel format. * @return The current image as a Float32Array. */ - getImage( - type: MPImageStorageType.FLOAT32_ARRAY, + get(type: MPImageType.FLOAT32_ARRAY, converter?: MPImageChannelConverter): Float32Array; /** * Returns the underlying image as an `ImageData` object. Note that this @@ -449,8 +450,7 @@ export class MPImage { * * @return The current image as an ImageData object. */ - getImage( - type: MPImageStorageType.IMAGE_DATA, + get(type: MPImageType.IMAGE_DATA, converter?: MPImageChannelConverter): ImageData; /** * Returns the underlying image as an `ImageBitmap`. Note that @@ -470,8 +470,7 @@ export class MPImage { * function if the requested conversion does not change the pixel format. * @return The current image as an ImageBitmap object. */ - getImage( - type: MPImageStorageType.IMAGE_BITMAP, + get(type: MPImageType.IMAGE_BITMAP, converter?: MPImageChannelConverter): ImageBitmap; /** * Returns the underlying image as a `WebGLTexture` object. Note that this @@ -485,22 +484,21 @@ export class MPImage { * function if the requested conversion does not change the pixel format. * @return The current image as a WebGLTexture. */ - getImage( - type: MPImageStorageType.WEBGL_TEXTURE, + get(type: MPImageType.WEBGL_TEXTURE, converter?: MPImageChannelConverter): WebGLTexture; - getImage(type?: MPImageStorageType, converter?: MPImageChannelConverter): - MPImageNativeContainer { + get(type?: MPImageType, + converter?: MPImageChannelConverter): MPImageContainer { const internalConverter = {...DEFAULT_CONVERTER, ...converter}; switch (type) { - case MPImageStorageType.UINT8_CLAMPED_ARRAY: + case MPImageType.UINT8_CLAMPED_ARRAY: return this.convertToUint8ClampedArray(internalConverter); - case MPImageStorageType.FLOAT32_ARRAY: + case MPImageType.FLOAT32_ARRAY: return this.convertToFloat32Array(internalConverter); - case MPImageStorageType.IMAGE_DATA: + case MPImageType.IMAGE_DATA: return this.convertToImageData(internalConverter); - case MPImageStorageType.IMAGE_BITMAP: + case MPImageType.IMAGE_BITMAP: return this.convertToImageBitmap(internalConverter); - case MPImageStorageType.WEBGL_TEXTURE: + case MPImageType.WEBGL_TEXTURE: return this.convertToWebGLTexture(internalConverter); default: throw new Error(`Type is not supported: ${type}`); @@ -508,31 +506,25 @@ export class MPImage { } - private getContainer(type: MPImageStorageType.UINT8_CLAMPED_ARRAY): - Uint8ClampedArray|undefined; - private getContainer(type: MPImageStorageType.FLOAT32_ARRAY): Float32Array - |undefined; - private getContainer(type: MPImageStorageType.IMAGE_DATA): ImageData - |undefined; - private getContainer(type: MPImageStorageType.IMAGE_BITMAP): ImageBitmap - |undefined; - private getContainer(type: MPImageStorageType.WEBGL_TEXTURE): WebGLTexture - |undefined; - private getContainer(type: MPImageStorageType): MPImageNativeContainer + private getContainer(type: MPImageType.UINT8_CLAMPED_ARRAY): Uint8ClampedArray |undefined; + private getContainer(type: MPImageType.FLOAT32_ARRAY): Float32Array|undefined; + private getContainer(type: MPImageType.IMAGE_DATA): ImageData|undefined; + private getContainer(type: MPImageType.IMAGE_BITMAP): ImageBitmap|undefined; + private getContainer(type: MPImageType.WEBGL_TEXTURE): WebGLTexture|undefined; + private getContainer(type: MPImageType): MPImageContainer|undefined; /** Returns the container for the requested storage type iff it exists. */ - private getContainer(type: MPImageStorageType): MPImageNativeContainer - |undefined { + private getContainer(type: MPImageType): MPImageContainer|undefined { switch (type) { - case MPImageStorageType.UINT8_CLAMPED_ARRAY: + case MPImageType.UINT8_CLAMPED_ARRAY: return this.containers.find(img => img instanceof Uint8ClampedArray); - case MPImageStorageType.FLOAT32_ARRAY: + case MPImageType.FLOAT32_ARRAY: return this.containers.find(img => img instanceof Float32Array); - case MPImageStorageType.IMAGE_DATA: + case MPImageType.IMAGE_DATA: return this.containers.find(img => img instanceof ImageData); - case MPImageStorageType.IMAGE_BITMAP: + case MPImageType.IMAGE_BITMAP: return this.containers.find(img => img instanceof ImageBitmap); - case MPImageStorageType.WEBGL_TEXTURE: + case MPImageType.WEBGL_TEXTURE: return this.containers.find(img => img instanceof WebGLTexture); default: throw new Error(`Type is not supported: ${type}`); @@ -547,12 +539,12 @@ export class MPImage { * avoided. */ clone(): MPImage { - const destinationContainers: MPImageNativeContainer[] = []; + const destinationContainers: MPImageContainer[] = []; // TODO: We might only want to clone one backing datastructure // even if multiple are defined; for (const container of this.containers) { - let destinationContainer: MPImageNativeContainer; + let destinationContainer: MPImageContainer; if (container instanceof Uint8ClampedArray) { destinationContainer = new Uint8ClampedArray(container); @@ -599,9 +591,9 @@ export class MPImage { } return new MPImage( - destinationContainers, this.hasType(MPImageStorageType.IMAGE_BITMAP), - this.hasType(MPImageStorageType.WEBGL_TEXTURE), this.canvas, - this.shaderContext, this.width, this.height); + destinationContainers, this.has(MPImageType.IMAGE_BITMAP), + this.has(MPImageType.WEBGL_TEXTURE), this.canvas, this.shaderContext, + this.width, this.height); } private getOffscreenCanvas(): OffscreenCanvas { @@ -637,7 +629,7 @@ export class MPImage { private convertToImageBitmap(converter: Required): ImageBitmap { - let imageBitmap = this.getContainer(MPImageStorageType.IMAGE_BITMAP); + let imageBitmap = this.getContainer(MPImageType.IMAGE_BITMAP); if (!imageBitmap) { this.convertToWebGLTexture(converter); imageBitmap = this.convertWebGLTextureToImageBitmap(); @@ -650,11 +642,10 @@ export class MPImage { private convertToImageData(converter: Required): ImageData { - let imageData = this.getContainer(MPImageStorageType.IMAGE_DATA); + let imageData = this.getContainer(MPImageType.IMAGE_DATA); if (!imageData) { - if (this.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)) { - const source = - this.getContainer(MPImageStorageType.UINT8_CLAMPED_ARRAY)!; + if (this.has(MPImageType.UINT8_CLAMPED_ARRAY)) { + const source = this.getContainer(MPImageType.UINT8_CLAMPED_ARRAY)!; const destination = new Uint8ClampedArray(this.width * this.height * 4); for (let i = 0; i < this.width * this.height; i++) { const rgba = converter.uint8ToRGBAConverter(source[i]); @@ -665,8 +656,8 @@ export class MPImage { } imageData = new ImageData(destination, this.width, this.height); this.containers.push(imageData); - } else if (this.hasType(MPImageStorageType.FLOAT32_ARRAY)) { - const source = this.getContainer(MPImageStorageType.FLOAT32_ARRAY)!; + } else if (this.has(MPImageType.FLOAT32_ARRAY)) { + const source = this.getContainer(MPImageType.FLOAT32_ARRAY)!; const destination = new Uint8ClampedArray(this.width * this.height * 4); for (let i = 0; i < this.width * this.height; i++) { const rgba = converter.floatToRGBAConverter(source[i]); @@ -678,8 +669,8 @@ export class MPImage { imageData = new ImageData(destination, this.width, this.height); this.containers.push(imageData); } else if ( - this.hasType(MPImageStorageType.IMAGE_BITMAP) || - this.hasType(MPImageStorageType.WEBGL_TEXTURE)) { + this.has(MPImageType.IMAGE_BITMAP) || + this.has(MPImageType.WEBGL_TEXTURE)) { const gl = this.getGL(); const shaderContext = this.getShaderContext(); const pixels = new Uint8Array(this.width * this.height * 4); @@ -706,11 +697,10 @@ export class MPImage { private convertToUint8ClampedArray( converter: Required): Uint8ClampedArray { - let uint8ClampedArray = - this.getContainer(MPImageStorageType.UINT8_CLAMPED_ARRAY); + let uint8ClampedArray = this.getContainer(MPImageType.UINT8_CLAMPED_ARRAY); if (!uint8ClampedArray) { - if (this.hasType(MPImageStorageType.FLOAT32_ARRAY)) { - const source = this.getContainer(MPImageStorageType.FLOAT32_ARRAY)!; + if (this.has(MPImageType.FLOAT32_ARRAY)) { + const source = this.getContainer(MPImageType.FLOAT32_ARRAY)!; uint8ClampedArray = new Uint8ClampedArray( source.map(v => converter.floatToUint8Converter(v))); } else { @@ -730,11 +720,10 @@ export class MPImage { private convertToFloat32Array(converter: Required): Float32Array { - let float32Array = this.getContainer(MPImageStorageType.FLOAT32_ARRAY); + let float32Array = this.getContainer(MPImageType.FLOAT32_ARRAY); if (!float32Array) { - if (this.hasType(MPImageStorageType.UINT8_CLAMPED_ARRAY)) { - const source = - this.getContainer(MPImageStorageType.UINT8_CLAMPED_ARRAY)!; + if (this.has(MPImageType.UINT8_CLAMPED_ARRAY)) { + const source = this.getContainer(MPImageType.UINT8_CLAMPED_ARRAY)!; float32Array = new Float32Array(source).map( v => converter.uint8ToFloatConverter(v)); } else { @@ -754,11 +743,11 @@ export class MPImage { private convertToWebGLTexture(converter: Required): WebGLTexture { - let webGLTexture = this.getContainer(MPImageStorageType.WEBGL_TEXTURE); + let webGLTexture = this.getContainer(MPImageType.WEBGL_TEXTURE); if (!webGLTexture) { const gl = this.getGL(); webGLTexture = this.bindTexture(); - const source = this.getContainer(MPImageStorageType.IMAGE_BITMAP) || + const source = this.getContainer(MPImageType.IMAGE_BITMAP) || this.convertToImageData(converter); gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source); @@ -778,7 +767,7 @@ export class MPImage { gl.viewport(0, 0, this.width, this.height); gl.activeTexture(gl.TEXTURE0); - let webGLTexture = this.getContainer(MPImageStorageType.WEBGL_TEXTURE); + let webGLTexture = this.getContainer(MPImageType.WEBGL_TEXTURE); if (!webGLTexture) { webGLTexture = assertNotNull(gl.createTexture(), 'Failed to create texture'); @@ -868,12 +857,12 @@ export class MPImage { */ close(): void { if (this.ownsImageBitmap) { - this.getContainer(MPImageStorageType.IMAGE_BITMAP)!.close(); + this.getContainer(MPImageType.IMAGE_BITMAP)!.close(); } if (this.ownsWebGLTexture) { const gl = this.getGL(); - gl.deleteTexture(this.getContainer(MPImageStorageType.WEBGL_TEXTURE)!); + gl.deleteTexture(this.getContainer(MPImageType.WEBGL_TEXTURE)!); } } } diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts index 7d30ef2a9..17764c9e5 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts @@ -19,7 +19,7 @@ import 'jasmine'; // Placeholder for internal dependency on encodeByteArray import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; import {addJasmineCustomFloatEqualityTester, createSpyWasmModule, MediapipeTasksFake, SpyWasmModule, verifyGraph, verifyListenersRegistered} from '../../../../tasks/web/core/task_runner_test_utils'; -import {MPImageStorageType} from '../../../../tasks/web/vision/core/image'; +import {MPImage} from '../../../../tasks/web/vision/core/image'; import {WasmImage} from '../../../../web/graph_runner/graph_runner_image_lib'; import {FaceStylizer} from './face_stylizer'; @@ -118,7 +118,7 @@ describe('FaceStylizer', () => { faceStylizer.stylize({} as HTMLImageElement, image => { expect(faceStylizer.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); expect(image).not.toBeNull(); - expect(image!.hasType(MPImageStorageType.IMAGE_DATA)).toBeTrue(); + expect(image!.has(MPImage.TYPE.IMAGE_DATA)).toBeTrue(); expect(image!.width).toEqual(1); expect(image!.height).toEqual(1); done(); diff --git a/mediapipe/tasks/web/vision/index.ts b/mediapipe/tasks/web/vision/index.ts index 632a294d6..34c1206cc 100644 --- a/mediapipe/tasks/web/vision/index.ts +++ b/mediapipe/tasks/web/vision/index.ts @@ -16,7 +16,7 @@ import {FilesetResolver as FilesetResolverImpl} from '../../../tasks/web/core/fileset_resolver'; import {DrawingUtils as DrawingUtilsImpl} from '../../../tasks/web/vision/core/drawing_utils'; -import {MPImage as MPImageImpl, MPImageStorageType as MPImageStorageTypeImpl} from '../../../tasks/web/vision/core/image'; +import {MPImage as MPImageImpl, MPImageType as MPImageTypeImpl} from '../../../tasks/web/vision/core/image'; import {FaceDetector as FaceDetectorImpl} from '../../../tasks/web/vision/face_detector/face_detector'; import {FaceLandmarker as FaceLandmarkerImpl, FaceLandmarksConnections as FaceLandmarksConnectionsImpl} from '../../../tasks/web/vision/face_landmarker/face_landmarker'; import {FaceStylizer as FaceStylizerImpl} from '../../../tasks/web/vision/face_stylizer/face_stylizer'; @@ -34,7 +34,7 @@ import {PoseLandmarker as PoseLandmarkerImpl} from '../../../tasks/web/vision/po const DrawingUtils = DrawingUtilsImpl; const FilesetResolver = FilesetResolverImpl; const MPImage = MPImageImpl; -const MPImageStorageType = MPImageStorageTypeImpl; +const MPImageType = MPImageTypeImpl; const FaceDetector = FaceDetectorImpl; const FaceLandmarker = FaceLandmarkerImpl; const FaceLandmarksConnections = FaceLandmarksConnectionsImpl; @@ -52,7 +52,7 @@ export { DrawingUtils, FilesetResolver, MPImage, - MPImageStorageType, + MPImageType, FaceDetector, FaceLandmarker, FaceLandmarksConnections, diff --git a/mediapipe/tasks/web/vision/types.ts b/mediapipe/tasks/web/vision/types.ts index 381052881..164276bab 100644 --- a/mediapipe/tasks/web/vision/types.ts +++ b/mediapipe/tasks/web/vision/types.ts @@ -16,7 +16,7 @@ export * from '../../../tasks/web/core/fileset_resolver'; export * from '../../../tasks/web/vision/core/drawing_utils'; -export {MPImage, MPImageChannelConverter, MPImageStorageType} from '../../../tasks/web/vision/core/image'; +export {MPImage, MPImageChannelConverter, MPImageType} from '../../../tasks/web/vision/core/image'; export * from '../../../tasks/web/vision/face_detector/face_detector'; export * from '../../../tasks/web/vision/face_landmarker/face_landmarker'; export * from '../../../tasks/web/vision/face_stylizer/face_stylizer'; From a9721ae2fbef20809854143ec0a8b84973c6ff6b Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 28 Apr 2023 19:59:03 -0700 Subject: [PATCH 147/753] Invoke callback for ImageSegmenter while C++ Packets are active PiperOrigin-RevId: 528047220 --- .../vision/image_segmenter/image_segmenter.ts | 28 +++++++++++++---- .../image_segmenter/image_segmenter_test.ts | 30 +++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts index 924628158..60b965345 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts @@ -60,6 +60,7 @@ export type ImageSegmenterCallback = (result: ImageSegmenterResult) => void; export class ImageSegmenter extends VisionTaskRunner { private result: ImageSegmenterResult = {}; private labels: string[] = []; + private userCallback: ImageSegmenterCallback = () => {}; private outputCategoryMask = DEFAULT_OUTPUT_CATEGORY_MASK; private outputConfidenceMasks = DEFAULT_OUTPUT_CONFIDENCE_MASKS; private readonly options: ImageSegmenterGraphOptionsProto; @@ -232,14 +233,13 @@ export class ImageSegmenter extends VisionTaskRunner { typeof imageProcessingOptionsOrCallback !== 'function' ? imageProcessingOptionsOrCallback : {}; - const userCallback = - typeof imageProcessingOptionsOrCallback === 'function' ? + this.userCallback = typeof imageProcessingOptionsOrCallback === 'function' ? imageProcessingOptionsOrCallback : callback!; this.reset(); this.processImageData(image, imageProcessingOptions); - userCallback(this.result); + this.userCallback = () => {}; } /** @@ -286,13 +286,13 @@ export class ImageSegmenter extends VisionTaskRunner { const timestamp = typeof timestampOrImageProcessingOptions === 'number' ? timestampOrImageProcessingOptions : timestampOrCallback as number; - const userCallback = typeof timestampOrCallback === 'function' ? + this.userCallback = typeof timestampOrCallback === 'function' ? timestampOrCallback : callback!; this.reset(); this.processVideoData(videoFrame, imageProcessingOptions, timestamp); - userCallback(this.result); + this.userCallback = () => {}; } /** @@ -314,6 +314,18 @@ export class ImageSegmenter extends VisionTaskRunner { this.result = {}; } + /** Invokes the user callback once all data has been received. */ + private maybeInvokeCallback(): void { + if (this.outputConfidenceMasks && !('confidenceMasks' in this.result)) { + return; + } + if (this.outputCategoryMask && !('categoryMask' in this.result)) { + return; + } + + this.userCallback(this.result); + } + /** Updates the MediaPipe graph configuration. */ protected override refreshGraph(): void { const graphConfig = new CalculatorGraphConfig(); @@ -342,10 +354,13 @@ export class ImageSegmenter extends VisionTaskRunner { this.result.confidenceMasks = masks.map(wasmImage => this.convertToMPImage(wasmImage)); this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( CONFIDENCE_MASKS_STREAM, timestamp => { + this.result.confidenceMasks = undefined; this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); } @@ -357,10 +372,13 @@ export class ImageSegmenter extends VisionTaskRunner { CATEGORY_MASK_STREAM, (mask, timestamp) => { this.result.categoryMask = this.convertToMPImage(mask); this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( CATEGORY_MASK_STREAM, timestamp => { + this.result.categoryMask = undefined; this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); } diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts index 7f7f19069..c1ccd7997 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts @@ -262,4 +262,34 @@ describe('ImageSegmenter', () => { }); }); }); + + it('invokes listener once masks are avaiblae', async () => { + const categoryMask = new Uint8ClampedArray([1]); + const confidenceMask = new Float32Array([0.0]); + let listenerCalled = false; + + await imageSegmenter.setOptions( + {outputCategoryMask: true, outputConfidenceMasks: true}); + + // Pass the test data to our listener + imageSegmenter.fakeWasmModule._waitUntilIdle.and.callFake(() => { + expect(listenerCalled).toBeFalse(); + imageSegmenter.categoryMaskListener! + ({data: categoryMask, width: 1, height: 1}, 1337); + expect(listenerCalled).toBeFalse(); + imageSegmenter.confidenceMasksListener!( + [ + {data: confidenceMask, width: 1, height: 1}, + ], + 1337); + expect(listenerCalled).toBeTrue(); + }); + + return new Promise(resolve => { + imageSegmenter.segment({} as HTMLImageElement, () => { + listenerCalled = true; + resolve(); + }); + }); + }); }); From d5c5457d25f52902064480efaaedba180df2c824 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 28 Apr 2023 20:22:08 -0700 Subject: [PATCH 148/753] Only log warnings once if color conversion is not specified PiperOrigin-RevId: 528052009 --- mediapipe/tasks/web/vision/core/image.ts | 88 +++++++++++++++++------- 1 file changed, 64 insertions(+), 24 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index 3927b910f..7d6997d37 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -263,6 +263,9 @@ export class MPImageShaderContext { } } +/** A four channel color with a red, green, blue and alpha values. */ +export type RGBAColor = [number, number, number, number]; + /** * An interface that can be used to provide custom conversion functions. These * functions are invoked to convert pixel values between different channel @@ -278,7 +281,7 @@ export interface MPImageChannelConverter { * The default conversion function is `[v * 255, v * 255, v * 255, 255]` * and will log a warning if invoked. */ - floatToRGBAConverter?: (value: number) => [number, number, number, number]; + floatToRGBAConverter?: (value: number) => RGBAColor; /* * A conversion function to convert a number in the [0, 255] range to RGBA. @@ -288,7 +291,7 @@ export interface MPImageChannelConverter { * The default conversion function is `[v, v , v , 255]` and will log a * warning if invoked. */ - uint8ToRGBAConverter?: (value: number) => [number, number, number, number]; + uint8ToRGBAConverter?: (value: number) => RGBAColor; /** * A conversion function to convert an RGBA value in the range of 0 to 255 to @@ -326,33 +329,70 @@ export interface MPImageChannelConverter { */ uint8ToFloatConverter?: (value: number) => number; } +/** + * Color converter that falls back to a default implementation if the + * user-provided converter does not specify a conversion. + */ +class DefaultColorConverter implements Required { + private static readonly WARNINGS_LOGGED = new Set(); -const DEFAULT_CONVERTER: Required = { - floatToRGBAConverter: v => { - console.log('Using default floatToRGBAConverter'); + constructor(private readonly customConverter: MPImageChannelConverter) {} + + floatToRGBAConverter(v: number): RGBAColor { + if (this.customConverter.floatToRGBAConverter) { + return this.customConverter.floatToRGBAConverter(v); + } + this.logWarningOnce('floatToRGBAConverter'); return [v * 255, v * 255, v * 255, 255]; - }, - uint8ToRGBAConverter: v => { - console.log('Using default uint8ToRGBAConverter'); + } + + uint8ToRGBAConverter(v: number): RGBAColor { + if (this.customConverter.uint8ToRGBAConverter) { + return this.customConverter.uint8ToRGBAConverter(v); + } + this.logWarningOnce('uint8ToRGBAConverter'); return [v, v, v, 255]; - }, - rgbaToFloatConverter: (r, g, b) => { - console.log('Using default floatToRGBAConverter'); + } + + rgbaToFloatConverter(r: number, g: number, b: number, a: number): number { + if (this.customConverter.rgbaToFloatConverter) { + return this.customConverter.rgbaToFloatConverter(r, g, b, a); + } + this.logWarningOnce('rgbaToFloatConverter'); return (r / 3 + g / 3 + b / 3) / 255; - }, - rgbaToUint8Converter: (r, g, b) => { - console.log('Using default rgbaToUint8Converter'); + } + + rgbaToUint8Converter(r: number, g: number, b: number, a: number): number { + if (this.customConverter.rgbaToUint8Converter) { + return this.customConverter.rgbaToUint8Converter(r, g, b, a); + } + this.logWarningOnce('rgbaToUint8Converter'); return r / 3 + g / 3 + b / 3; - }, - floatToUint8Converter: v => { - console.log('Using default floatToUint8Converter'); + } + + floatToUint8Converter(v: number): number { + if (this.customConverter.floatToUint8Converter) { + return this.customConverter.floatToUint8Converter(v); + } + this.logWarningOnce('floatToUint8Converter'); return v * 255; - }, - uint8ToFloatConverter: v => { - console.log('Using default uint8ToFloatConverter'); + } + + uint8ToFloatConverter(v: number): number { + if (this.customConverter.uint8ToFloatConverter) { + return this.customConverter.uint8ToFloatConverter(v); + } + this.logWarningOnce('uint8ToFloatConverter'); return v / 255; - }, -}; + } + + private logWarningOnce(methodName: string): void { + if (!DefaultColorConverter.WARNINGS_LOGGED.has(methodName)) { + console.log(`Using default ${methodName}`); + DefaultColorConverter.WARNINGS_LOGGED.add(methodName); + } + } +} /** * The wrapper class for MediaPipe Image objects. @@ -488,7 +528,7 @@ export class MPImage { converter?: MPImageChannelConverter): WebGLTexture; get(type?: MPImageType, converter?: MPImageChannelConverter): MPImageContainer { - const internalConverter = {...DEFAULT_CONVERTER, ...converter}; + const internalConverter = new DefaultColorConverter(converter ?? {}); switch (type) { case MPImageType.UINT8_CLAMPED_ARRAY: return this.convertToUint8ClampedArray(internalConverter); @@ -579,7 +619,7 @@ export class MPImage { this.unbindTexture(); } else if (container instanceof ImageBitmap) { - this.convertToWebGLTexture(DEFAULT_CONVERTER); + this.convertToWebGLTexture(new DefaultColorConverter({})); this.bindTexture(); destinationContainer = this.copyTextureToBitmap(); this.unbindTexture(); From 253f13ad622139ca41b134fc1611f6d2907ca0a9 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 28 Apr 2023 20:31:57 -0700 Subject: [PATCH 149/753] Invoke callback for InteractiveSegmenter while C++ Packets are active PiperOrigin-RevId: 528053621 --- .../interactive_segmenter.ts | 24 +++++++++++++-- .../interactive_segmenter_test.ts | 30 +++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts index f127792ce..67d6ec3f6 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts @@ -86,6 +86,7 @@ export class InteractiveSegmenter extends VisionTaskRunner { private result: InteractiveSegmenterResult = {}; private outputCategoryMask = DEFAULT_OUTPUT_CATEGORY_MASK; private outputConfidenceMasks = DEFAULT_OUTPUT_CONFIDENCE_MASKS; + private userCallback: InteractiveSegmenterCallback = () => {}; private readonly options: ImageSegmenterGraphOptionsProto; private readonly segmenterOptions: SegmenterOptionsProto; @@ -241,21 +242,32 @@ export class InteractiveSegmenter extends VisionTaskRunner { typeof imageProcessingOptionsOrCallback !== 'function' ? imageProcessingOptionsOrCallback : {}; - const userCallback = - typeof imageProcessingOptionsOrCallback === 'function' ? + this.userCallback = typeof imageProcessingOptionsOrCallback === 'function' ? imageProcessingOptionsOrCallback : callback!; this.reset(); this.processRenderData(roi, this.getSynctheticTimestamp()); this.processImageData(image, imageProcessingOptions); - userCallback(this.result); + this.userCallback = () => {}; } private reset(): void { this.result = {}; } + /** Invokes the user callback once all data has been received. */ + private maybeInvokeCallback(): void { + if (this.outputConfidenceMasks && !('confidenceMasks' in this.result)) { + return; + } + if (this.outputCategoryMask && !('categoryMask' in this.result)) { + return; + } + + this.userCallback(this.result); + } + /** Updates the MediaPipe graph configuration. */ protected override refreshGraph(): void { const graphConfig = new CalculatorGraphConfig(); @@ -286,10 +298,13 @@ export class InteractiveSegmenter extends VisionTaskRunner { this.result.confidenceMasks = masks.map(wasmImage => this.convertToMPImage(wasmImage)); this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( CONFIDENCE_MASKS_STREAM, timestamp => { + this.result.confidenceMasks = undefined; this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); } @@ -301,10 +316,13 @@ export class InteractiveSegmenter extends VisionTaskRunner { CATEGORY_MASK_STREAM, (mask, timestamp) => { this.result.categoryMask = this.convertToMPImage(mask); this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( CATEGORY_MASK_STREAM, timestamp => { + this.result.categoryMask = undefined; this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); } diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts index cbaf76630..84ecde00b 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts @@ -252,4 +252,34 @@ describe('InteractiveSegmenter', () => { }); }); }); + + it('invokes listener once masks are avaiblae', async () => { + const categoryMask = new Uint8ClampedArray([1]); + const confidenceMask = new Float32Array([0.0]); + let listenerCalled = false; + + await interactiveSegmenter.setOptions( + {outputCategoryMask: true, outputConfidenceMasks: true}); + + // Pass the test data to our listener + interactiveSegmenter.fakeWasmModule._waitUntilIdle.and.callFake(() => { + expect(listenerCalled).toBeFalse(); + interactiveSegmenter.categoryMaskListener! + ({data: categoryMask, width: 1, height: 1}, 1337); + expect(listenerCalled).toBeFalse(); + interactiveSegmenter.confidenceMasksListener!( + [ + {data: confidenceMask, width: 1, height: 1}, + ], + 1337); + expect(listenerCalled).toBeTrue(); + }); + + return new Promise(resolve => { + interactiveSegmenter.segment({} as HTMLImageElement, ROI, () => { + listenerCalled = true; + resolve(); + }); + }); + }); }); From 8e510a3255719971abbfb777ff4f76157b6b2ca0 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 28 Apr 2023 21:19:46 -0700 Subject: [PATCH 150/753] Invoke PoseListener callback while C++ Packet is still active PiperOrigin-RevId: 528061429 --- .../vision/pose_landmarker/pose_landmarker.ts | 48 ++++++++++++++----- .../pose_landmarker/pose_landmarker_test.ts | 34 +++++++++++++ 2 files changed, 69 insertions(+), 13 deletions(-) diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts index 44effa879..2d72bf1dc 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts @@ -62,12 +62,9 @@ export type PoseLandmarkerCallback = (result: PoseLandmarkerResult) => void; /** Performs pose landmarks detection on images. */ export class PoseLandmarker extends VisionTaskRunner { - private result: PoseLandmarkerResult = { - landmarks: [], - worldLandmarks: [], - auxilaryLandmarks: [] - }; + private result: Partial = {}; private outputSegmentationMasks = false; + private userCallback: PoseLandmarkerCallback = () => {}; private readonly options: PoseLandmarkerGraphOptions; private readonly poseLandmarksDetectorGraphOptions: PoseLandmarksDetectorGraphOptions; @@ -239,14 +236,13 @@ export class PoseLandmarker extends VisionTaskRunner { typeof imageProcessingOptionsOrCallback !== 'function' ? imageProcessingOptionsOrCallback : {}; - const userCallback = - typeof imageProcessingOptionsOrCallback === 'function' ? + this.userCallback = typeof imageProcessingOptionsOrCallback === 'function' ? imageProcessingOptionsOrCallback : callback!; this.resetResults(); this.processImageData(image, imageProcessingOptions); - userCallback(this.result); + this.userCallback = () => {}; } /** @@ -293,19 +289,33 @@ export class PoseLandmarker extends VisionTaskRunner { const timestamp = typeof timestampOrImageProcessingOptions === 'number' ? timestampOrImageProcessingOptions : timestampOrCallback as number; - const userCallback = typeof timestampOrCallback === 'function' ? + this.userCallback = typeof timestampOrCallback === 'function' ? timestampOrCallback : callback!; this.resetResults(); this.processVideoData(videoFrame, imageProcessingOptions, timestamp); - userCallback(this.result); + this.userCallback = () => {}; } private resetResults(): void { - this.result = {landmarks: [], worldLandmarks: [], auxilaryLandmarks: []}; - if (this.outputSegmentationMasks) { - this.result.segmentationMasks = []; + this.result = {}; + } + + /** Invokes the user callback once all data has been received. */ + private maybeInvokeCallback(): void { + if (!('landmarks' in this.result)) { + return; } + if (!('worldLandmarks' in this.result)) { + return; + } + if (!('landmarks' in this.result)) { + return; + } + if (this.outputSegmentationMasks && !('segmentationMasks' in this.result)) { + return; + } + this.userCallback(this.result as Required); } /** Sets the default values for the graph. */ @@ -385,30 +395,39 @@ export class PoseLandmarker extends VisionTaskRunner { NORM_LANDMARKS_STREAM, (binaryProto, timestamp) => { this.addJsLandmarks(binaryProto); this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( NORM_LANDMARKS_STREAM, timestamp => { + this.result.landmarks = []; this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); this.graphRunner.attachProtoVectorListener( WORLD_LANDMARKS_STREAM, (binaryProto, timestamp) => { this.adddJsWorldLandmarks(binaryProto); this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( WORLD_LANDMARKS_STREAM, timestamp => { + this.result.worldLandmarks = []; this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); this.graphRunner.attachProtoVectorListener( AUXILIARY_LANDMARKS_STREAM, (binaryProto, timestamp) => { this.addJsAuxiliaryLandmarks(binaryProto); this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( AUXILIARY_LANDMARKS_STREAM, timestamp => { + this.result.auxilaryLandmarks = []; this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); if (this.outputSegmentationMasks) { @@ -419,10 +438,13 @@ export class PoseLandmarker extends VisionTaskRunner { this.result.segmentationMasks = masks.map(wasmImage => this.convertToMPImage(wasmImage)); this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( SEGMENTATION_MASK_STREAM, timestamp => { + this.result.segmentationMasks = []; this.setLatestOutputTimestamp(timestamp); + this.maybeInvokeCallback(); }); } diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts index 2d76f656f..794df68b8 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts @@ -260,4 +260,38 @@ describe('PoseLandmarker', () => { expect(landmarks1).toBeDefined(); expect(landmarks1).toEqual(landmarks2); }); + + it('invokes listener once masks are avaiblae', (done) => { + const landmarksProto = [createLandmarks().serializeBinary()]; + const worldLandmarksProto = [createWorldLandmarks().serializeBinary()]; + const masks = [ + {data: new Float32Array([0, 1, 2, 3]), width: 2, height: 2}, + ]; + let listenerCalled = false; + + + poseLandmarker.setOptions({outputSegmentationMasks: true}); + + // Pass the test data to our listener + poseLandmarker.fakeWasmModule._waitUntilIdle.and.callFake(() => { + expect(listenerCalled).toBeFalse(); + poseLandmarker.listeners.get('normalized_landmarks')! + (landmarksProto, 1337); + expect(listenerCalled).toBeFalse(); + poseLandmarker.listeners.get('world_landmarks')! + (worldLandmarksProto, 1337); + expect(listenerCalled).toBeFalse(); + poseLandmarker.listeners.get('auxiliary_landmarks')! + (landmarksProto, 1337); + expect(listenerCalled).toBeFalse(); + poseLandmarker.listeners.get('segmentation_masks')!(masks, 1337); + expect(listenerCalled).toBeTrue(); + done(); + }); + + // Invoke the pose landmarker + poseLandmarker.detect({} as HTMLImageElement, () => { + listenerCalled = true; + }); + }); }); From c4502837156a6f9b58cfcdd4dc8899c316a45d38 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Sun, 30 Apr 2023 01:16:48 -0700 Subject: [PATCH 151/753] Add a filegroup for referencing model. PiperOrigin-RevId: 528251316 --- mediapipe/model_maker/python/vision/core/BUILD | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mediapipe/model_maker/python/vision/core/BUILD b/mediapipe/model_maker/python/vision/core/BUILD index ba67b61e9..a5d4b08f8 100644 --- a/mediapipe/model_maker/python/vision/core/BUILD +++ b/mediapipe/model_maker/python/vision/core/BUILD @@ -17,7 +17,9 @@ licenses(["notice"]) -package(default_visibility = ["//mediapipe:__subpackages__"]) +package(default_visibility = [ + "//mediapipe:__subpackages__", +]) py_library( name = "image_preprocessing", From c29e43dda063d218374cc372263606c4ad9fdf94 Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Sun, 30 Apr 2023 16:57:32 -0700 Subject: [PATCH 152/753] Add the "FACE_ALIGNMENT" output stream to the face stylizer graph. PiperOrigin-RevId: 528345204 --- mediapipe/tasks/cc/vision/face_stylizer/BUILD | 1 + .../face_stylizer/face_stylizer_graph.cc | 99 ++++++++++++++++--- 2 files changed, 87 insertions(+), 13 deletions(-) diff --git a/mediapipe/tasks/cc/vision/face_stylizer/BUILD b/mediapipe/tasks/cc/vision/face_stylizer/BUILD index e7e6724cc..afc348174 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/BUILD +++ b/mediapipe/tasks/cc/vision/face_stylizer/BUILD @@ -50,6 +50,7 @@ cc_library( "//mediapipe/tasks/cc/vision/face_stylizer/calculators:tensors_to_image_calculator", "//mediapipe/tasks/cc/vision/face_stylizer/calculators:tensors_to_image_calculator_cc_proto", "//mediapipe/tasks/cc/vision/face_stylizer/proto:face_stylizer_graph_options_cc_proto", + "//mediapipe/util:graph_builder_utils", "@com_google_absl//absl/memory", "@com_google_absl//absl/status:statusor", ], diff --git a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc index 89394c53a..6f2777fc7 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc +++ b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc @@ -41,6 +41,7 @@ limitations under the License. #include "mediapipe/tasks/cc/vision/face_landmarker/proto/face_landmarks_detector_graph_options.pb.h" #include "mediapipe/tasks/cc/vision/face_stylizer/calculators/tensors_to_image_calculator.pb.h" #include "mediapipe/tasks/cc/vision/face_stylizer/proto/face_stylizer_graph_options.pb.h" +#include "mediapipe/util/graph_builder_utils.h" namespace mediapipe { namespace tasks { @@ -64,6 +65,7 @@ using ::mediapipe::tasks::vision::face_stylizer::proto:: FaceStylizerGraphOptions; constexpr char kDetectionTag[] = "DETECTION"; +constexpr char kFaceAlignmentTag[] = "FACE_ALIGNMENT"; constexpr char kFaceDetectorTFLiteName[] = "face_detector.tflite"; constexpr char kFaceLandmarksDetectorTFLiteName[] = "face_landmarks_detector.tflite"; @@ -83,7 +85,8 @@ constexpr char kTensorsTag[] = "TENSORS"; // Struct holding the different output streams produced by the face stylizer // graph. struct FaceStylizerOutputStreams { - Source stylized_image; + std::optional> stylized_image; + std::optional> face_alignment_image; Source original_image; }; @@ -190,8 +193,13 @@ void ConfigureTensorsToImageCalculator( // @Optional: rect covering the whole image is used if not specified. // // Outputs: -// IMAGE - mediapipe::Image +// STYLIZED_IMAGE - mediapipe::Image // The face stylization output image. +// FACE_ALIGNMENT - mediapipe::Image +// The face alignment output image. +// IMAGE - mediapipe::Image +// The input image that the face landmarker runs on and has the pixel data +// stored on the target storage (CPU vs GPU). // // Example: // node { @@ -215,6 +223,8 @@ class FaceStylizerGraph : public core::ModelTaskGraph { public: absl::StatusOr GetConfig( SubgraphContext* sc) override { + bool output_stylized = !HasInput(sc->OriginalNode(), kStylizedImageTag); + bool output_alignment = !HasInput(sc->OriginalNode(), kFaceAlignmentTag); ASSIGN_OR_RETURN( const auto* model_asset_bundle_resources, CreateModelAssetBundleResources(sc)); @@ -235,15 +245,27 @@ class FaceStylizerGraph : public core::ModelTaskGraph { ->mutable_face_landmarker_graph_options(), graph[Input(kImageTag)], graph[Input::Optional(kNormRectTag)], graph)); - ASSIGN_OR_RETURN( - const auto* model_resources, - CreateModelResources(sc, std::move(face_stylizer_external_file))); + const ModelResources* face_stylizer_model_resources; + if (output_stylized) { + ASSIGN_OR_RETURN( + const auto* model_resources, + CreateModelResources(sc, std::move(face_stylizer_external_file))); + face_stylizer_model_resources = model_resources; + } ASSIGN_OR_RETURN( auto output_streams, BuildFaceStylizerGraph(sc->Options(), - *model_resources, graph[Input(kImageTag)], + face_stylizer_model_resources, output_alignment, + graph[Input(kImageTag)], face_landmark_lists, graph)); - output_streams.stylized_image >> graph[Output(kStylizedImageTag)]; + if (output_stylized) { + output_streams.stylized_image.value() >> + graph[Output(kStylizedImageTag)]; + } + if (output_alignment) { + output_streams.stylized_image.value() >> + graph[Output(kFaceAlignmentTag)]; + } output_streams.original_image >> graph[Output(kImageTag)]; return graph.GetConfig(); } @@ -277,9 +299,11 @@ class FaceStylizerGraph : public core::ModelTaskGraph { absl::StatusOr BuildFaceStylizerGraph( const FaceStylizerGraphOptions& task_options, - const ModelResources& model_resources, Source image_in, + const ModelResources* model_resources, bool output_alignment, + Source image_in, Source> face_landmark_lists, Graph& graph) { + bool output_stylized = model_resources != nullptr; auto& split_face_landmark_list = graph.AddNode("SplitNormalizedLandmarkListVectorCalculator"); ConfigureSplitNormalizedLandmarkListVectorCalculator( @@ -303,15 +327,52 @@ class FaceStylizerGraph : public core::ModelTaskGraph { face_detection >> face_to_rect.In(kDetectionTag); image_size >> face_to_rect.In(kImageSizeTag); auto face_rect = face_to_rect.Out(kNormRectTag); - // Adds preprocessing calculators and connects them to the graph input image - // stream. + + std::optional> face_alignment; + // Output face alignment only. + // In this case, the face stylization model inference is not required. + // However, to keep consistent with the inference preprocessing steps, the + // ImageToTensorCalculator is still used to perform image rotation, + // cropping, and resizing. + if (!output_stylized) { + auto& pass_through = graph.AddNode("PassThroughCalculator"); + image_in >> pass_through.In(""); + + auto& image_to_tensor = graph.AddNode("ImageToTensorCalculator"); + auto& image_to_tensor_options = + image_to_tensor.GetOptions(); + image_to_tensor_options.mutable_output_tensor_float_range()->set_min(-1); + image_to_tensor_options.mutable_output_tensor_float_range()->set_max(1); + image_to_tensor_options.set_keep_aspect_ratio(true); + image_to_tensor_options.set_border_mode( + mediapipe::ImageToTensorCalculatorOptions::BORDER_ZERO); + image_in >> image_to_tensor.In(kImageTag); + face_rect >> image_to_tensor.In(kNormRectTag); + auto face_alignment_image = image_to_tensor.Out(kTensorsTag); + + auto& tensors_to_image = + graph.AddNode("mediapipe.tasks.TensorsToImageCalculator"); + ConfigureTensorsToImageCalculator( + image_to_tensor_options, + &tensors_to_image.GetOptions()); + face_alignment_image >> tensors_to_image.In(kTensorsTag); + face_alignment = tensors_to_image.Out(kImageTag).Cast(); + + return {{/*stylized_image=*/std::nullopt, + /*alignment_image=*/face_alignment, + /*original_image=*/pass_through.Out("").Cast()}}; + } + + std::optional> stylized; + // Adds preprocessing calculators and connects them to the graph input + // image stream. auto& preprocessing = graph.AddNode( "mediapipe.tasks.components.processors.ImagePreprocessingGraph"); bool use_gpu = components::processors::DetermineImagePreprocessingGpuBackend( task_options.base_options().acceleration()); MP_RETURN_IF_ERROR(components::processors::ConfigureImagePreprocessingGraph( - model_resources, use_gpu, + *model_resources, use_gpu, &preprocessing.GetOptions())); auto& image_to_tensor_options = @@ -329,7 +390,7 @@ class FaceStylizerGraph : public core::ModelTaskGraph { // Adds inference subgraph and connects its input stream to the output // tensors produced by the ImageToTensorCalculator. auto& inference = AddInference( - model_resources, task_options.base_options().acceleration(), graph); + *model_resources, task_options.base_options().acceleration(), graph); preprocessed_tensors >> inference.In(kTensorsTag); auto model_output_tensors = inference.Out(kTensorsTag).Cast>(); @@ -346,8 +407,20 @@ class FaceStylizerGraph : public core::ModelTaskGraph { image_converter.GetOptions() .set_output_on_gpu(false); tensor_image >> image_converter.In(""); + stylized = image_converter.Out("").Cast(); - return {{/*stylized_image=*/image_converter.Out("").Cast(), + if (output_alignment) { + auto& tensors_to_image = + graph.AddNode("mediapipe.tasks.TensorsToImageCalculator"); + ConfigureTensorsToImageCalculator( + image_to_tensor_options, + &tensors_to_image.GetOptions()); + preprocessed_tensors >> tensors_to_image.In(kTensorsTag); + face_alignment = tensors_to_image.Out(kImageTag).Cast(); + } + + return {{/*stylized_image=*/stylized, + /*alignment_image=*/face_alignment, /*original_image=*/preprocessing.Out(kImageTag).Cast()}}; } }; From 80b19fff4b15ae4911d738665d33fa5c68b3b631 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Sun, 30 Apr 2023 23:08:15 -0700 Subject: [PATCH 153/753] Internal Change PiperOrigin-RevId: 528399911 --- mediapipe/framework/api2/builder.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mediapipe/framework/api2/builder.h b/mediapipe/framework/api2/builder.h index adc2c9ffa..51e59973c 100644 --- a/mediapipe/framework/api2/builder.h +++ b/mediapipe/framework/api2/builder.h @@ -223,6 +223,16 @@ class SourceImpl { return !(*this == other); } + Src& SetName(const char* name) { + base_->name_ = std::string(name); + return *this; + } + + Src& SetName(absl::string_view name) { + base_->name_ = std::string(name); + return *this; + } + Src& SetName(std::string name) { base_->name_ = std::move(name); return *this; From ad4ae6559b5eb7fd8a08c7ac1b088ccd8eb4b261 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Sun, 30 Apr 2023 23:11:14 -0700 Subject: [PATCH 154/753] 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 --- .../python/core/utils/test_util.py | 14 ++++++++++- .../vision/face_stylizer/face_stylizer.py | 5 +++- .../face_stylizer/face_stylizer_test.py | 23 ++++++++++++++++--- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/mediapipe/model_maker/python/core/utils/test_util.py b/mediapipe/model_maker/python/core/utils/test_util.py index eda8facc2..72fb229c7 100644 --- a/mediapipe/model_maker/python/core/utils/test_util.py +++ b/mediapipe/model_maker/python/core/utils/test_util.py @@ -16,7 +16,8 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function -from typing import List, Union +from typing import Sequence +from typing import Dict, List, Union # Dependency imports @@ -94,6 +95,17 @@ def is_same_output(tflite_model: bytearray, return np.allclose(lite_output, keras_output, atol=atol) +def run_tflite( + tflite_filename: str, + input_tensors: Union[List[tf.Tensor], Dict[str, tf.Tensor]], +) -> Union[Sequence[tf.Tensor], tf.Tensor]: + """Runs TFLite model inference.""" + with tf.io.gfile.GFile(tflite_filename, "rb") as f: + tflite_model = f.read() + lite_runner = model_util.get_lite_runner(tflite_model) + return lite_runner.run(input_tensors) + + def test_tflite(keras_model: tf.keras.Model, tflite_model: bytearray, size: Union[int, List[int]], diff --git a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py index 2c0c1057c..85b567ca3 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py @@ -221,7 +221,10 @@ class FaceStylizer(object): inputs = tf.keras.Input(shape=(256, 256, 3)) x = self._encoder(inputs) x = self._decoder({'inputs': x + self.w_avg}) - outputs = x['image'][-1] + x = x['image'][-1] + # Scale the data range from [-1, 1] to [0, 1] to support running inference + # on both CPU and GPU. + outputs = (x + 1.0) / 2.0 model = tf.keras.Model(inputs=inputs, outputs=outputs) tflite_model = model_util.convert_to_tflite( diff --git a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_test.py b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_test.py index 8a3023269..16b314c8e 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_test.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer_test.py @@ -12,8 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os + import tensorflow as tf +from mediapipe.model_maker.python.core.utils import test_util as mm_test_util from mediapipe.model_maker.python.vision import face_stylizer from mediapipe.tasks.python.test import test_utils @@ -52,14 +55,28 @@ class FaceStylizerTest(tf.test.TestCase): def test_export_face_stylizer_tflite_model(self): with self.test_session(use_gpu=True): + model_enum = face_stylizer.SupportedModels.BLAZE_FACE_STYLIZER_256 face_stylizer_options = face_stylizer.FaceStylizerOptions( - model=face_stylizer.SupportedModels.BLAZE_FACE_STYLIZER_256, - hparams=face_stylizer.HParams(epochs=0), + model=model_enum, + hparams=face_stylizer.HParams( + epochs=0, export_dir=self.get_temp_dir() + ), ) model = face_stylizer.FaceStylizer.create( train_data=self._train_data, options=face_stylizer_options ) - model.export_model() + tflite_model_name = 'custom_face_stylizer.tflite' + model.export_model(model_name=tflite_model_name) + face_stylizer_tflite_file = os.path.join( + self.get_temp_dir(), tflite_model_name + ) + spec = face_stylizer.SupportedModels.get(model_enum) + input_image_shape = spec.input_image_shape + input_tensor_shape = [1] + list(input_image_shape) + [3] + input_tensor = mm_test_util.create_random_sample(size=input_tensor_shape) + output = mm_test_util.run_tflite(face_stylizer_tflite_file, input_tensor) + self.assertTrue((output >= 0.0).all()) + self.assertTrue((output <= 1.0).all()) if __name__ == '__main__': From 209d78f36cac23e0de035d2f01976a620c04d01f Mon Sep 17 00:00:00 2001 From: kinaryml Date: Mon, 1 May 2023 05:55:46 -0700 Subject: [PATCH 155/753] Added the Face Aligner Python API --- .../python/test/vision/face_aligner_test.py | 208 ++++++++++++++++++ mediapipe/tasks/python/vision/face_aligner.py | 201 +++++++++++++++++ 2 files changed, 409 insertions(+) create mode 100644 mediapipe/tasks/python/test/vision/face_aligner_test.py create mode 100644 mediapipe/tasks/python/vision/face_aligner.py diff --git a/mediapipe/tasks/python/test/vision/face_aligner_test.py b/mediapipe/tasks/python/test/vision/face_aligner_test.py new file mode 100644 index 000000000..7f2f8dd7e --- /dev/null +++ b/mediapipe/tasks/python/test/vision/face_aligner_test.py @@ -0,0 +1,208 @@ +# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for face aligner.""" + +import enum +import os +from unittest import mock + +from absl.testing import absltest +from absl.testing import parameterized + +from mediapipe.python._framework_bindings import image as image_module +from mediapipe.tasks.python.core import base_options as base_options_module +from mediapipe.tasks.python.components.containers import rect +from mediapipe.tasks.python.test import test_utils +from mediapipe.tasks.python.vision import face_aligner +from mediapipe.tasks.python.vision.core import vision_task_running_mode as running_mode_module +from mediapipe.tasks.python.vision.core import image_processing_options as image_processing_options_module + + +_BaseOptions = base_options_module.BaseOptions +_Rect = rect.Rect +_Image = image_module.Image +_FaceAligner = face_aligner.FaceAligner +_FaceAlignerOptions = face_aligner.FaceAlignerOptions +_RUNNING_MODE = running_mode_module.VisionTaskRunningMode +_ImageProcessingOptions = image_processing_options_module.ImageProcessingOptions + +_MODEL = 'face_stylizer.task' +_LARGE_FACE_IMAGE = "portrait.jpg" +_MODEL_IMAGE_SIZE = 256 +_TEST_DATA_DIR = 'mediapipe/tasks/testdata/vision' + + +class ModelFileType(enum.Enum): + FILE_CONTENT = 1 + FILE_NAME = 2 + + +class FaceAlignerTest(parameterized.TestCase): + + def setUp(self): + super().setUp() + self.test_image = _Image.create_from_file( + test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, _LARGE_FACE_IMAGE))) + self.model_path = test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, _MODEL)) + + def test_create_from_file_succeeds_with_valid_model_path(self): + # Creates with default option and valid model file successfully. + with _FaceAligner.create_from_model_path(self.model_path) as aligner: + self.assertIsInstance(aligner, _FaceAligner) + + def test_create_from_options_succeeds_with_valid_model_path(self): + # Creates with options containing model file successfully. + base_options = _BaseOptions(model_asset_path=self.model_path) + options = _FaceAlignerOptions(base_options=base_options) + with _FaceAligner.create_from_options(options) as aligner: + self.assertIsInstance(aligner, _FaceAligner) + + def test_create_from_options_fails_with_invalid_model_path(self): + with self.assertRaisesRegex( + RuntimeError, 'Unable to open file at /path/to/invalid/model.tflite'): + base_options = _BaseOptions( + model_asset_path='/path/to/invalid/model.tflite') + options = _FaceAlignerOptions(base_options=base_options) + _FaceAligner.create_from_options(options) + + def test_create_from_options_succeeds_with_valid_model_content(self): + # Creates with options containing model content successfully. + with open(self.model_path, 'rb') as f: + base_options = _BaseOptions(model_asset_buffer=f.read()) + options = _FaceAlignerOptions(base_options=base_options) + aligner = _FaceAligner.create_from_options(options) + self.assertIsInstance(aligner, _FaceAligner) + + @parameterized.parameters( + (ModelFileType.FILE_NAME, _LARGE_FACE_IMAGE), + (ModelFileType.FILE_CONTENT, _LARGE_FACE_IMAGE) + ) + def test_align(self, model_file_type, image_file_name): + # Load the test image. + self.test_image = _Image.create_from_file( + test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, image_file_name))) + # Creates aligner. + if model_file_type is ModelFileType.FILE_NAME: + base_options = _BaseOptions(model_asset_path=self.model_path) + elif model_file_type is ModelFileType.FILE_CONTENT: + with open(self.model_path, 'rb') as f: + model_content = f.read() + base_options = _BaseOptions(model_asset_buffer=model_content) + else: + # Should never happen + raise ValueError('model_file_type is invalid.') + + options = _FaceAlignerOptions(base_options=base_options) + aligner = _FaceAligner.create_from_options(options) + + # Performs face alignment on the input. + alignd_image = aligner.align(self.test_image) + self.assertIsInstance(alignd_image, _Image) + # Closes the aligner explicitly when the aligner is not used in + # a context. + aligner.close() + + @parameterized.parameters( + (ModelFileType.FILE_NAME, _LARGE_FACE_IMAGE), + (ModelFileType.FILE_CONTENT, _LARGE_FACE_IMAGE) + ) + def test_align_in_context(self, model_file_type, image_file_name): + # Load the test image. + self.test_image = _Image.create_from_file( + test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, image_file_name))) + # Creates aligner. + if model_file_type is ModelFileType.FILE_NAME: + base_options = _BaseOptions(model_asset_path=self.model_path) + elif model_file_type is ModelFileType.FILE_CONTENT: + with open(self.model_path, 'rb') as f: + model_content = f.read() + base_options = _BaseOptions(model_asset_buffer=model_content) + else: + # Should never happen + raise ValueError('model_file_type is invalid.') + + options = _FaceAlignerOptions(base_options=base_options) + with _FaceAligner.create_from_options(options) as aligner: + # Performs face alignment on the input. + alignd_image = aligner.align(self.test_image) + self.assertIsInstance(alignd_image, _Image) + self.assertEqual(alignd_image.width, _MODEL_IMAGE_SIZE) + self.assertEqual(alignd_image.height, _MODEL_IMAGE_SIZE) + + def test_align_succeeds_with_region_of_interest(self): + base_options = _BaseOptions(model_asset_path=self.model_path) + options = _FaceAlignerOptions(base_options=base_options) + with _FaceAligner.create_from_options(options) as aligner: + # Load the test image. + test_image = _Image.create_from_file( + test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, _LARGE_FACE_IMAGE) + ) + ) + # Region-of-interest around the face. + roi = _Rect(left=0.32, top=0.02, right=0.67, bottom=0.32) + image_processing_options = _ImageProcessingOptions(roi) + # Performs face alignment on the input. + alignd_image = aligner.align(test_image, image_processing_options) + self.assertIsInstance(alignd_image, _Image) + self.assertEqual(alignd_image.width, _MODEL_IMAGE_SIZE) + self.assertEqual(alignd_image.height, _MODEL_IMAGE_SIZE) + + def test_align_succeeds_with_no_face_detected(self): + base_options = _BaseOptions(model_asset_path=self.model_path) + options = _FaceAlignerOptions(base_options=base_options) + with _FaceAligner.create_from_options(options) as aligner: + # Load the test image. + test_image = _Image.create_from_file( + test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, _LARGE_FACE_IMAGE) + ) + ) + # Region-of-interest that doesn't contain a human face. + roi = _Rect(left=0.1, top=0.1, right=0.2, bottom=0.2) + image_processing_options = _ImageProcessingOptions(roi) + # Performs face alignment on the input. + alignd_image = aligner.align(test_image, image_processing_options) + self.assertIsNone(alignd_image) + + def test_missing_result_callback(self): + options = _FaceAlignerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.LIVE_STREAM, + ) + with self.assertRaisesRegex( + ValueError, r'result callback must be provided' + ): + with _FaceAligner.create_from_options(options) as unused_aligner: + pass + + def test_illegal_result_callback(self): + options = _FaceAlignerOptions( + base_options=_BaseOptions(model_asset_path=self.model_path), + running_mode=_RUNNING_MODE.IMAGE, + result_callback=mock.MagicMock(), + ) + with self.assertRaisesRegex( + ValueError, r'result callback should not be provided' + ): + with _FaceAligner.create_from_options(options) as unused_aligner: + pass + + +if __name__ == '__main__': + absltest.main() diff --git a/mediapipe/tasks/python/vision/face_aligner.py b/mediapipe/tasks/python/vision/face_aligner.py new file mode 100644 index 000000000..615232f05 --- /dev/null +++ b/mediapipe/tasks/python/vision/face_aligner.py @@ -0,0 +1,201 @@ +# 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. +"""MediaPipe face aligner task.""" + +import dataclasses +from typing import Callable, Mapping, Optional + +from mediapipe.python import packet_creator +from mediapipe.python import packet_getter +from mediapipe.python._framework_bindings import image as image_module +from mediapipe.python._framework_bindings import packet as packet_module +from mediapipe.tasks.cc.vision.face_stylizer.proto import face_stylizer_graph_options_pb2 +from mediapipe.tasks.python.core import base_options as base_options_module +from mediapipe.tasks.python.core import task_info as task_info_module +from mediapipe.tasks.python.core.optional_dependencies import doc_controls +from mediapipe.tasks.python.vision.core import base_vision_task_api +from mediapipe.tasks.python.vision.core import image_processing_options as image_processing_options_module +from mediapipe.tasks.python.vision.core import vision_task_running_mode as running_mode_module + +_BaseOptions = base_options_module.BaseOptions +_FaceStylizerGraphOptionsProto = ( + face_stylizer_graph_options_pb2.FaceStylizerGraphOptions +) +_RunningMode = running_mode_module.VisionTaskRunningMode +_ImageProcessingOptions = image_processing_options_module.ImageProcessingOptions +_TaskInfo = task_info_module.TaskInfo + +_FACE_ALIGNMENT_IMAGE_NAME = 'stylized_image' +_FACE_ALIGNMENT_IMAGE_TAG = 'FACE_ALIGNMENT' +_NORM_RECT_STREAM_NAME = 'norm_rect_in' +_NORM_RECT_TAG = 'NORM_RECT' +_IMAGE_IN_STREAM_NAME = 'image_in' +_IMAGE_OUT_STREAM_NAME = 'image_out' +_IMAGE_TAG = 'IMAGE' +_TASK_GRAPH_NAME = 'mediapipe.tasks.vision.face_stylizer.FaceStylizerGraph' +_MICRO_SECONDS_PER_MILLISECOND = 1000 + + +@dataclasses.dataclass +class FaceAlignerOptions: + """Options for the face aligner task. + + Attributes: + base_options: Base options for the face aligner task. + running_mode: The running mode of the task. Default to the image mode. Face + aligner task has three running modes: 1) The image mode for aligning one + face on a single image input. 2) The video mode for aligning one face per + frame on the decoded frames of a video. 3) The live stream mode for + aligning one face on a live stream of input data, such as from camera. + result_callback: The user-defined result callback for processing live stream + data. The result callback should only be specified when the running mode + is set to the live stream mode. + """ + + base_options: _BaseOptions + running_mode: _RunningMode = _RunningMode.IMAGE + result_callback: Optional[ + Callable[[image_module.Image, image_module.Image, int], None] + ] = None + + @doc_controls.do_not_generate_docs + def to_pb2(self) -> _FaceStylizerGraphOptionsProto: + """Generates an FaceStylizerOptions protobuf object.""" + base_options_proto = self.base_options.to_pb2() + base_options_proto.use_stream_mode = ( + False if self.running_mode == _RunningMode.IMAGE else True + ) + return _FaceStylizerGraphOptionsProto(base_options=base_options_proto) + + +class FaceAligner(base_vision_task_api.BaseVisionTaskApi): + """Class that performs face alignment on images.""" + + @classmethod + def create_from_model_path(cls, model_path: str) -> 'FaceAligner': + """Creates an `FaceAligner` object from a TensorFlow Lite model and the default `FaceAlignerOptions`. + + Note that the created `FaceAligner` instance is in image mode, for + aligning one face on a single image input. + + Args: + model_path: Path to the model. + + Returns: + `FaceAligner` object that's created from the model file and the default + `FaceAlignerOptions`. + + Raises: + ValueError: If failed to create `FaceAligner` object from the provided + file such as invalid file path. + RuntimeError: If other types of error occurred. + """ + base_options = _BaseOptions(model_asset_path=model_path) + options = FaceAlignerOptions( + base_options=base_options, running_mode=_RunningMode.IMAGE + ) + return cls.create_from_options(options) + + @classmethod + def create_from_options(cls, options: FaceAlignerOptions) -> 'FaceAligner': + """Creates the `FaceAligner` object from face aligner options. + + Args: + options: Options for the face aligner task. + + Returns: + `FaceAligner` object that's created from `options`. + + Raises: + ValueError: If failed to create `FaceAligner` object from + `FaceAlignerOptions` such as missing the model. + RuntimeError: If other types of error occurred. + """ + + def packets_callback(output_packets: Mapping[str, packet_module.Packet]): + if output_packets[_IMAGE_OUT_STREAM_NAME].is_empty(): + return + image = packet_getter.get_image(output_packets[_IMAGE_OUT_STREAM_NAME]) + aligned_image_packet = output_packets[_FACE_ALIGNMENT_IMAGE_NAME] + if aligned_image_packet.is_empty(): + options.result_callback( + None, + image, + aligned_image_packet.timestamp.value + // _MICRO_SECONDS_PER_MILLISECOND, + ) + + aligned_image = packet_getter.get_image(aligned_image_packet) + + options.result_callback( + aligned_image, + image, + aligned_image_packet.timestamp.value + // _MICRO_SECONDS_PER_MILLISECOND, + ) + + task_info = _TaskInfo( + task_graph=_TASK_GRAPH_NAME, + input_streams=[ + ':'.join([_IMAGE_TAG, _IMAGE_IN_STREAM_NAME]), + ':'.join([_NORM_RECT_TAG, _NORM_RECT_STREAM_NAME]), + ], + output_streams=[ + ':'.join([_FACE_ALIGNMENT_IMAGE_TAG, _FACE_ALIGNMENT_IMAGE_NAME]), + ':'.join([_IMAGE_TAG, _IMAGE_OUT_STREAM_NAME]), + ], + task_options=options, + ) + return cls( + task_info.generate_graph_config( + enable_flow_limiting=options.running_mode + == _RunningMode.LIVE_STREAM + ), + options.running_mode, + packets_callback if options.result_callback else None, + ) + + def align( + self, + image: image_module.Image, + image_processing_options: Optional[_ImageProcessingOptions] = None, + ) -> image_module.Image: + """Performs face alignment on the provided MediaPipe Image. + + Only use this method when the FaceAligner is created with the image + running mode. + + Args: + image: MediaPipe Image. + image_processing_options: Options for image processing. + + Returns: + The aligned face image. The aligned output image size is the same as the + model output size. None if no face is detected on the input image. + + Raises: + ValueError: If any of the input arguments is invalid. + RuntimeError: If face alignment failed to run. + """ + normalized_rect = self.convert_to_normalized_rect( + image_processing_options, image) + output_packets = self._process_image_data({ + _IMAGE_IN_STREAM_NAME: packet_creator.create_image(image), + _NORM_RECT_STREAM_NAME: packet_creator.create_proto( + normalized_rect.to_pb2() + ), + }) + if output_packets[_FACE_ALIGNMENT_IMAGE_NAME].is_empty(): + return None + return packet_getter.get_image(output_packets[_FACE_ALIGNMENT_IMAGE_NAME]) From bd039f8b65d2b6bf623c909832c8b5ada0e81a6e Mon Sep 17 00:00:00 2001 From: kinaryml Date: Mon, 1 May 2023 05:56:52 -0700 Subject: [PATCH 156/753] Updated necessary BUILD files --- mediapipe/tasks/python/test/vision/BUILD | 18 ++++++++++++++++++ mediapipe/tasks/python/vision/BUILD | 19 +++++++++++++++++++ mediapipe/tasks/testdata/vision/BUILD | 2 ++ 3 files changed, 39 insertions(+) diff --git a/mediapipe/tasks/python/test/vision/BUILD b/mediapipe/tasks/python/test/vision/BUILD index e55e1b572..8488a3b1f 100644 --- a/mediapipe/tasks/python/test/vision/BUILD +++ b/mediapipe/tasks/python/test/vision/BUILD @@ -140,6 +140,24 @@ py_test( ], ) +py_test( + name = "face_aligner_test", + srcs = ["face_aligner_test.py"], + data = [ + "//mediapipe/tasks/testdata/vision:test_images", + "//mediapipe/tasks/testdata/vision:test_models", + ], + deps = [ + "//mediapipe/python:_framework_bindings", + "//mediapipe/tasks/python/components/containers:rect", + "//mediapipe/tasks/python/core:base_options", + "//mediapipe/tasks/python/test:test_utils", + "//mediapipe/tasks/python/vision:face_aligner", + "//mediapipe/tasks/python/vision/core:image_processing_options", + "//mediapipe/tasks/python/vision/core:vision_task_running_mode", + ], +) + py_test( name = "hand_landmarker_test", srcs = ["hand_landmarker_test.py"], diff --git a/mediapipe/tasks/python/vision/BUILD b/mediapipe/tasks/python/vision/BUILD index d0c97434f..dcd28dcf5 100644 --- a/mediapipe/tasks/python/vision/BUILD +++ b/mediapipe/tasks/python/vision/BUILD @@ -264,3 +264,22 @@ py_library( "//mediapipe/tasks/python/vision/core:vision_task_running_mode", ], ) + +py_library( + name = "face_aligner", + srcs = [ + "face_aligner.py", + ], + deps = [ + "//mediapipe/python:_framework_bindings", + "//mediapipe/python:packet_creator", + "//mediapipe/python:packet_getter", + "//mediapipe/tasks/cc/vision/face_stylizer/proto:face_stylizer_graph_options_py_pb2", + "//mediapipe/tasks/python/core:base_options", + "//mediapipe/tasks/python/core:optional_dependencies", + "//mediapipe/tasks/python/core:task_info", + "//mediapipe/tasks/python/vision/core:base_vision_task_api", + "//mediapipe/tasks/python/vision/core:image_processing_options", + "//mediapipe/tasks/python/vision/core:vision_task_running_mode", + ], +) diff --git a/mediapipe/tasks/testdata/vision/BUILD b/mediapipe/tasks/testdata/vision/BUILD index 632e8aa4e..a8e06cad5 100644 --- a/mediapipe/tasks/testdata/vision/BUILD +++ b/mediapipe/tasks/testdata/vision/BUILD @@ -48,6 +48,7 @@ mediapipe_files(srcs = [ "face_landmark.tflite", "face_landmarker.task", "face_landmarker_v2.task", + "face_stylizer.task", "fist.jpg", "fist.png", "hair_segmentation.tflite", @@ -176,6 +177,7 @@ filegroup( "face_detection_short_range.tflite", "face_landmarker.task", "face_landmarker_v2.task", + "face_stylizer.task", "hair_segmentation.tflite", "hand_landmark_full.tflite", "hand_landmark_lite.tflite", From b9a9da5de54e34c3dff2a3232a5674ab4fbf9a78 Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Mon, 1 May 2023 10:16:20 -0700 Subject: [PATCH 157/753] Ignore fetching face stylizer model when the graph doesn't output stylized face images. PiperOrigin-RevId: 528504312 --- .../cc/vision/face_stylizer/face_stylizer_graph.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc index 6f2777fc7..7bb2e9c8d 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc +++ b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc @@ -130,9 +130,11 @@ absl::Status SetSubTaskBaseOptions(const ModelAssetBundleResources& resources, face_landmarks_detector_graph_options->mutable_base_options() ->set_use_stream_mode(options->base_options().use_stream_mode()); - ASSIGN_OR_RETURN(const auto face_stylizer_file, - resources.GetFile(kFaceStylizerTFLiteName)); - SetExternalFile(face_stylizer_file, face_stylizer_external_file, is_copy); + if (face_stylizer_external_file) { + ASSIGN_OR_RETURN(const auto face_stylizer_file, + resources.GetFile(kFaceStylizerTFLiteName)); + SetExternalFile(face_stylizer_file, face_stylizer_external_file, is_copy); + } return absl::OkStatus(); } @@ -234,7 +236,7 @@ class FaceStylizerGraph : public core::ModelTaskGraph { MP_RETURN_IF_ERROR(SetSubTaskBaseOptions( *model_asset_bundle_resources, sc->MutableOptions(), - face_stylizer_external_file.get(), + output_stylized ? face_stylizer_external_file.get() : nullptr, !sc->Service(::mediapipe::tasks::core::kModelResourcesCacheService) .IsAvailable())); Graph graph; From cab619f8da145b2759fc130288d8c9125d074de4 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Mon, 1 May 2023 10:22:38 -0700 Subject: [PATCH 158/753] Fix typo in README PiperOrigin-RevId: 528506206 --- mediapipe/framework/api2/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/framework/api2/README.md b/mediapipe/framework/api2/README.md index eb53dd67e..849a5f4c4 100644 --- a/mediapipe/framework/api2/README.md +++ b/mediapipe/framework/api2/README.md @@ -52,7 +52,7 @@ int select = cc->Inputs().Tag(kSelectTag).Get(); write ``` -int select = kSelectTag(cc).Get(); // alternative: *kSelectTag(cc) +int select = kSelect(cc).Get(); // alternative: *kSelect(cc) ``` Sets of multiple ports can be declared with `::Multiple`. Note, also, that a tag From 085f8265fb389e8e060a9502bbfcd6952b529aa5 Mon Sep 17 00:00:00 2001 From: Yuqi Li Date: Mon, 1 May 2023 10:59:22 -0700 Subject: [PATCH 159/753] Internal change PiperOrigin-RevId: 528517562 --- .../python/metadata/metadata_writers/BUILD | 9 ++ .../metadata_writers/face_stylizer.py | 138 ++++++++++++++++++ .../test/metadata/metadata_writers/BUILD | 13 ++ .../metadata_writers/face_stylizer_test.py | 80 ++++++++++ mediapipe/tasks/testdata/metadata/BUILD | 4 + .../testdata/metadata/face_stylizer.json | 47 ++++++ third_party/external_files.bzl | 12 ++ 7 files changed, 303 insertions(+) create mode 100644 mediapipe/tasks/python/metadata/metadata_writers/face_stylizer.py create mode 100644 mediapipe/tasks/python/test/metadata/metadata_writers/face_stylizer_test.py create mode 100644 mediapipe/tasks/testdata/metadata/face_stylizer.json diff --git a/mediapipe/tasks/python/metadata/metadata_writers/BUILD b/mediapipe/tasks/python/metadata/metadata_writers/BUILD index f7db16682..268dec494 100644 --- a/mediapipe/tasks/python/metadata/metadata_writers/BUILD +++ b/mediapipe/tasks/python/metadata/metadata_writers/BUILD @@ -78,6 +78,15 @@ py_library( ], ) +py_library( + name = "face_stylizer", + srcs = ["face_stylizer.py"], + deps = [ + ":metadata_writer", + ":model_asset_bundle_utils", + ], +) + py_library( name = "model_asset_bundle_utils", srcs = ["model_asset_bundle_utils.py"], diff --git a/mediapipe/tasks/python/metadata/metadata_writers/face_stylizer.py b/mediapipe/tasks/python/metadata/metadata_writers/face_stylizer.py new file mode 100644 index 000000000..01d0d7027 --- /dev/null +++ b/mediapipe/tasks/python/metadata/metadata_writers/face_stylizer.py @@ -0,0 +1,138 @@ +# 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. +# ============================================================================== +"""Writes metadata and creates model asset bundle for face stylizer.""" + +import os +import tempfile +from typing import List + +from mediapipe.tasks.python.metadata.metadata_writers import metadata_writer +from mediapipe.tasks.python.metadata.metadata_writers import model_asset_bundle_utils + +_MODEL_NAME = "FaceStylizer" +_MODEL_DESCRIPTION = "Performs face stylization on images." +_FACE_DETECTOR_MODEL = "face_detector.tflite" +_FACE_LANDMARKS_DETECTOR_MODEL = "face_landmarks_detector.tflite" +_FACE_STYLIZER_MODEL = "face_stylizer.tflite" +_FACE_STYLIZER_TASK = "face_stylizer.task" + + +class MetadataWriter: + """MetadataWriter to write the metadata for face stylizer.""" + + def __init__( + self, + face_detector_model_buffer: bytearray, + face_landmarks_detector_model_buffer: bytearray, + face_stylizer_metadata_writer: metadata_writer.MetadataWriter, + ) -> None: + """Initializes MetadataWriter to write the metadata and model asset bundle. + + Args: + face_detector_model_buffer: A valid flatbuffer loaded from the face + detector TFLite model file with metadata already packed inside. + face_landmarks_detector_model_buffer: A valid flatbuffer loaded from the + face landmarks detector TFLite model file with metadata already packed + inside. + face_stylizer_metadata_writer: Metadata writer to write face stylizer + metadata into the TFLite file. + """ + self._face_detector_model_buffer = face_detector_model_buffer + self._face_landmarks_detector_model_buffer = ( + face_landmarks_detector_model_buffer + ) + self._face_stylizer_metadata_writer = face_stylizer_metadata_writer + self._temp_folder = tempfile.TemporaryDirectory() + + def __del__(self): + if os.path.exists(self._temp_folder.name): + self._temp_folder.cleanup() + + @classmethod + def create( + cls, + face_stylizer_model_buffer: bytearray, + face_detector_model_buffer: bytearray, + face_landmarks_detector_model_buffer: bytearray, + input_norm_mean: List[float], + input_norm_std: List[float], + ) -> "MetadataWriter": + """Creates MetadataWriter to write the metadata for face stylizer. + + The parameters required in this method are mandatory when using MediaPipe + Tasks. + + Note that only the output TFLite is used for deployment. The output JSON + content is used to interpret the metadata content. + + Args: + face_stylizer_model_buffer: A valid flatbuffer loaded from the face + stylizer TFLite model file. + face_detector_model_buffer: A valid flatbuffer loaded from the face + detector TFLite model file with metadata already packed inside. + face_landmarks_detector_model_buffer: A valid flatbuffer loaded from the + face landmarks detector TFLite model file with metadata already packed + inside. + input_norm_mean: the mean value used in the input tensor normalization for + face stylizer model [1]. + input_norm_std: the std value used in the input tensor normalizarion for + face stylizer model [1]. + + [1]: + https://github.com/google/mediapipe/blob/f8af41b1eb49ff4bdad756ff19d1d36f486be614/mediapipe/tasks/metadata/metadata_schema.fbs#L389 + + Returns: + A MetadataWriter object. + """ + face_stylizer_writer = metadata_writer.MetadataWriter( + face_stylizer_model_buffer + ) + face_stylizer_writer.add_general_info(_MODEL_NAME, _MODEL_DESCRIPTION) + face_stylizer_writer.add_image_input(input_norm_mean, input_norm_std) + return cls( + face_detector_model_buffer, + face_landmarks_detector_model_buffer, + face_stylizer_writer, + ) + + def populate(self): + """Populates the metadata and creates model asset bundle. + + Note that only the output model asset bundle is used for deployment. + The output JSON content is used to interpret the face stylizer metadata + content. + + Returns: + A tuple of (model_asset_bundle_in_bytes, metadata_json_content) + """ + # Write metadata into the face stylizer TFLite model. + face_stylizer_model_buffer, face_stylizer_metadata_json = ( + self._face_stylizer_metadata_writer.populate() + ) + # Create the model asset bundle for the face stylizer task. + face_stylizer_models = { + _FACE_DETECTOR_MODEL: self._face_detector_model_buffer, + _FACE_LANDMARKS_DETECTOR_MODEL: ( + self._face_landmarks_detector_model_buffer + ), + _FACE_STYLIZER_MODEL: face_stylizer_model_buffer, + } + output_path = os.path.join(self._temp_folder.name, _FACE_STYLIZER_TASK) + model_asset_bundle_utils.create_model_asset_bundle( + face_stylizer_models, output_path + ) + with open(output_path, "rb") as f: + face_stylizer_model_bundle_buffer = f.read() + return face_stylizer_model_bundle_buffer, face_stylizer_metadata_json diff --git a/mediapipe/tasks/python/test/metadata/metadata_writers/BUILD b/mediapipe/tasks/python/test/metadata/metadata_writers/BUILD index 66ddf54b8..863cc1a64 100644 --- a/mediapipe/tasks/python/test/metadata/metadata_writers/BUILD +++ b/mediapipe/tasks/python/test/metadata/metadata_writers/BUILD @@ -107,3 +107,16 @@ py_test( "//mediapipe/tasks/python/test:test_utils", ], ) + +py_test( + name = "face_stylizer_test", + srcs = ["face_stylizer_test.py"], + data = [ + "//mediapipe/tasks/testdata/metadata:data_files", + "//mediapipe/tasks/testdata/metadata:model_files", + ], + deps = [ + "//mediapipe/tasks/python/metadata/metadata_writers:face_stylizer", + "//mediapipe/tasks/python/test:test_utils", + ], +) diff --git a/mediapipe/tasks/python/test/metadata/metadata_writers/face_stylizer_test.py b/mediapipe/tasks/python/test/metadata/metadata_writers/face_stylizer_test.py new file mode 100644 index 000000000..127a4a47d --- /dev/null +++ b/mediapipe/tasks/python/test/metadata/metadata_writers/face_stylizer_test.py @@ -0,0 +1,80 @@ +# 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. +# ============================================================================== +"""Tests for metadata_writer.face_stylizer.""" + +import os +import tempfile +import zipfile + +from absl.testing import absltest +from absl.testing import parameterized + +from mediapipe.tasks.python.metadata.metadata_writers import face_stylizer +from mediapipe.tasks.python.test import test_utils + +_TEST_DATA_DIR = "mediapipe/tasks/testdata/metadata" +_NORM_MEAN = 0 +_NORM_STD = 255 +_TFLITE = test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, "dummy_face_stylizer.tflite") +) +_EXPECTED_JSON = test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, "face_stylizer.json") +) + + +class FaceStylizerTest(parameterized.TestCase): + + def test_write_metadata_and_create_model_asset_bundle_successful(self): + # Use dummy model buffer for unit test only. + with open(_TFLITE, "rb") as f: + face_stylizer_model_buffer = f.read() + face_detector_model_buffer = b"\x33\x44" + face_landmarks_detector_model_buffer = b"\x55\x66" + writer = face_stylizer.MetadataWriter.create( + face_stylizer_model_buffer, + face_detector_model_buffer, + face_landmarks_detector_model_buffer, + input_norm_mean=[_NORM_MEAN], + input_norm_std=[_NORM_STD], + ) + model_bundle_content, metadata_json = writer.populate() + with open(_EXPECTED_JSON, "r") as f: + expected_json = f.read() + self.assertEqual(metadata_json, expected_json) + + temp_folder = tempfile.TemporaryDirectory() + + # Checks the model bundle can be extracted successfully. + model_bundle_filepath = os.path.join(temp_folder.name, "face_stylizer.task") + + with open(model_bundle_filepath, "wb") as f: + f.write(model_bundle_content) + + with zipfile.ZipFile(model_bundle_filepath) as zf: + self.assertEqual( + set(zf.namelist()), + set([ + "face_detector.tflite", + "face_landmarks_detector.tflite", + "face_stylizer.tflite", + ]), + ) + zf.extractall(temp_folder.name) + temp_folder.cleanup() + + +if __name__ == "__main__": + absltest.main() diff --git a/mediapipe/tasks/testdata/metadata/BUILD b/mediapipe/tasks/testdata/metadata/BUILD index 710e9d8cf..25cac9e15 100644 --- a/mediapipe/tasks/testdata/metadata/BUILD +++ b/mediapipe/tasks/testdata/metadata/BUILD @@ -32,8 +32,10 @@ mediapipe_files(srcs = [ "deeplabv3_with_activation.json", "deeplabv3_without_labels.json", "deeplabv3_without_metadata.tflite", + "dummy_face_stylizer.tflite", "efficientdet_lite0_fp16_no_nms.tflite", "efficientdet_lite0_v1.tflite", + "face_stylizer.json", "labelmap.txt", "mobile_ica_8bit-with-custom-metadata.tflite", "mobile_ica_8bit-with-large-min-parser-version.tflite", @@ -96,6 +98,7 @@ filegroup( "bert_text_classifier_no_metadata.tflite", "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29_no_metadata.tflite", "deeplabv3_without_metadata.tflite", + "dummy_face_stylizer.tflite", "efficientdet_lite0_fp16_no_nms.tflite", "efficientdet_lite0_v1.tflite", "mobile_ica_8bit-with-custom-metadata.tflite", @@ -132,6 +135,7 @@ filegroup( "efficientdet_lite0_fp16_no_nms_anchors.csv", "efficientdet_lite0_v1.json", "external_file", + "face_stylizer.json", "feature_tensor_meta.json", "general_meta.json", "golden_json.json", diff --git a/mediapipe/tasks/testdata/metadata/face_stylizer.json b/mediapipe/tasks/testdata/metadata/face_stylizer.json new file mode 100644 index 000000000..e987ad816 --- /dev/null +++ b/mediapipe/tasks/testdata/metadata/face_stylizer.json @@ -0,0 +1,47 @@ +{ + "name": "FaceStylizer", + "description": "Performs face stylization on images.", + "subgraph_metadata": [ + { + "input_tensor_metadata": [ + { + "name": "image", + "description": "Input image to be processed.", + "content": { + "content_properties_type": "ImageProperties", + "content_properties": { + "color_space": "RGB" + } + }, + "process_units": [ + { + "options_type": "NormalizationOptions", + "options": { + "mean": [ + 0.0 + ], + "std": [ + 255.0 + ] + } + } + ], + "stats": { + "max": [ + 1.0 + ], + "min": [ + 0.0 + ] + } + } + ], + "output_tensor_metadata": [ + { + "name": "PartitionedCall:0" + } + ] + } + ], + "min_parser_version": "1.0.0" +} diff --git a/third_party/external_files.bzl b/third_party/external_files.bzl index ff338bae2..af9361bb3 100644 --- a/third_party/external_files.bzl +++ b/third_party/external_files.bzl @@ -250,6 +250,12 @@ def external_files(): urls = ["https://storage.googleapis.com/mediapipe-assets/dense.tflite?generation=1678218351373709"], ) + http_file( + name = "com_google_mediapipe_dummy_face_stylizer_tflite", + sha256 = "c44a32a673790aac4aca63ca4b4192b9870c21045241e69d9fe09b7ad1a38d65", + urls = ["https://storage.googleapis.com/mediapipe-assets/dummy_face_stylizer.tflite?generation=1682960595073526"], + ) + http_file( name = "com_google_mediapipe_dummy_gesture_recognizer_task", sha256 = "18e54586bda33300d459ca140cd045f6daf43d897224ba215a16db3423eae18e", @@ -418,6 +424,12 @@ def external_files(): urls = ["https://storage.googleapis.com/mediapipe-assets/face_stylization_dummy.tflite?generation=1678323589048063"], ) + http_file( + name = "com_google_mediapipe_face_stylizer_json", + sha256 = "ad89860d5daba6a1c4163a576428713fc3ddab76d6bbaf06d675164423ae159f", + urls = ["https://storage.googleapis.com/mediapipe-assets/face_stylizer.json?generation=1682960598942694"], + ) + http_file( name = "com_google_mediapipe_face_stylizer_task", sha256 = "b34f3896cbe860468538cf5a562c0468964f182b8bb07cb527224312969d1625", From 5526e96b21667431ea4011a29dcc1960cf4a2785 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Mon, 1 May 2023 12:14:49 -0700 Subject: [PATCH 160/753] Internal change for proto library outputs. PiperOrigin-RevId: 528539840 --- mediapipe/framework/tool/mediapipe_proto.bzl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mediapipe/framework/tool/mediapipe_proto.bzl b/mediapipe/framework/tool/mediapipe_proto.bzl index 527774ff3..6e41d054e 100644 --- a/mediapipe/framework/tool/mediapipe_proto.bzl +++ b/mediapipe/framework/tool/mediapipe_proto.bzl @@ -54,6 +54,7 @@ def mediapipe_proto_library_impl( def_java_proto = True, def_jspb_proto = True, def_go_proto = True, + def_dart_proto = True, def_options_lib = True): """Defines the proto_library targets needed for all mediapipe platforms. @@ -75,6 +76,7 @@ def mediapipe_proto_library_impl( def_java_proto: define the java_proto_library target def_jspb_proto: define the jspb_proto_library target def_go_proto: define the go_proto_library target + def_dart_proto: define the dart_proto_library target def_options_lib: define the mediapipe_options_library target """ @@ -258,6 +260,7 @@ def mediapipe_proto_library( def_java_proto = True, def_jspb_proto = True, def_go_proto = True, + def_dart_proto = True, def_options_lib = True, def_rewrite = True, portable_deps = None): # @unused @@ -283,6 +286,7 @@ def mediapipe_proto_library( def_java_proto: define the java_proto_library target def_jspb_proto: define the jspb_proto_library target def_go_proto: define the go_proto_library target + def_dart_proto: define the dart_proto_library target def_options_lib: define the mediapipe_options_library target def_rewrite: define a sibling mediapipe_proto_library with package "mediapipe" """ @@ -304,6 +308,7 @@ def mediapipe_proto_library( def_java_proto = def_java_proto, def_jspb_proto = def_jspb_proto, def_go_proto = def_go_proto, + def_dart_proto = def_dart_proto, def_options_lib = def_options_lib, ) @@ -333,6 +338,7 @@ def mediapipe_proto_library( def_java_proto = def_java_proto, def_jspb_proto = def_jspb_proto, def_go_proto = def_go_proto, + def_dart_proto = def_dart_proto, # A clone of mediapipe_options_library() will redefine some classes. def_options_lib = False, ) From 162a99988750a2a9d84341172088f49f52d4d8fa Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Mon, 1 May 2023 13:12:09 -0700 Subject: [PATCH 161/753] Check the output stream tag rather than the input stream tag in face stylizer graph. PiperOrigin-RevId: 528555024 --- .../tasks/cc/vision/face_stylizer/face_stylizer_graph.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc index 7bb2e9c8d..029a5a86c 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc +++ b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc @@ -169,7 +169,7 @@ void ConfigureTensorsToImageCalculator( if (image_to_tensor_options.has_output_tensor_float_range()) { auto* mutable_range = tensors_to_image_options->mutable_input_tensor_float_range(); - // TODO: Make the float range flexiable. + // TODO: Make the float range flexible. mutable_range->set_min(0); mutable_range->set_max(1); } else if (image_to_tensor_options.has_output_tensor_uint_range()) { @@ -225,8 +225,8 @@ class FaceStylizerGraph : public core::ModelTaskGraph { public: absl::StatusOr GetConfig( SubgraphContext* sc) override { - bool output_stylized = !HasInput(sc->OriginalNode(), kStylizedImageTag); - bool output_alignment = !HasInput(sc->OriginalNode(), kFaceAlignmentTag); + bool output_stylized = HasOutput(sc->OriginalNode(), kStylizedImageTag); + bool output_alignment = HasOutput(sc->OriginalNode(), kFaceAlignmentTag); ASSIGN_OR_RETURN( const auto* model_asset_bundle_resources, CreateModelAssetBundleResources(sc)); @@ -265,7 +265,7 @@ class FaceStylizerGraph : public core::ModelTaskGraph { graph[Output(kStylizedImageTag)]; } if (output_alignment) { - output_streams.stylized_image.value() >> + output_streams.face_alignment_image.value() >> graph[Output(kFaceAlignmentTag)]; } output_streams.original_image >> graph[Output(kImageTag)]; From fca728d22612c008286926fcdba4974e7b37d614 Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Mon, 1 May 2023 14:57:56 -0700 Subject: [PATCH 162/753] Set face alignment image width and hight to 256. PiperOrigin-RevId: 528583074 --- .../tasks/cc/vision/face_stylizer/face_stylizer_graph.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc index 029a5a86c..7c4e6f138 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc +++ b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc @@ -81,6 +81,7 @@ constexpr char kOutputSizeTag[] = "OUTPUT_SIZE"; constexpr char kSizeTag[] = "SIZE"; constexpr char kStylizedImageTag[] = "STYLIZED_IMAGE"; constexpr char kTensorsTag[] = "TENSORS"; +constexpr int kFaceAlignmentOutputSize = 256; // Struct holding the different output streams produced by the face stylizer // graph. @@ -345,6 +346,9 @@ class FaceStylizerGraph : public core::ModelTaskGraph { image_to_tensor.GetOptions(); image_to_tensor_options.mutable_output_tensor_float_range()->set_min(-1); image_to_tensor_options.mutable_output_tensor_float_range()->set_max(1); + image_to_tensor_options.set_output_tensor_width(kFaceAlignmentOutputSize); + image_to_tensor_options.set_output_tensor_height( + kFaceAlignmentOutputSize); image_to_tensor_options.set_keep_aspect_ratio(true); image_to_tensor_options.set_border_mode( mediapipe::ImageToTensorCalculatorOptions::BORDER_ZERO); From 0a8be0d09dfda8f6a86e5f7a97ecb0814f12095f Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Mon, 1 May 2023 18:38:20 -0700 Subject: [PATCH 163/753] Internal change PiperOrigin-RevId: 528632873 --- .../framework/jni/graph_texture_frame_jni.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mediapipe/java/com/google/mediapipe/framework/jni/graph_texture_frame_jni.cc b/mediapipe/java/com/google/mediapipe/framework/jni/graph_texture_frame_jni.cc index dd99cccd4..b3bcd14dd 100644 --- a/mediapipe/java/com/google/mediapipe/framework/jni/graph_texture_frame_jni.cc +++ b/mediapipe/java/com/google/mediapipe/framework/jni/graph_texture_frame_jni.cc @@ -14,6 +14,7 @@ #include "mediapipe/java/com/google/mediapipe/framework/jni/graph_texture_frame_jni.h" +#include "absl/strings/str_format.h" #include "mediapipe/gpu/gl_calculator_helper.h" #include "mediapipe/gpu/gl_context.h" #include "mediapipe/gpu/gl_texture_buffer.h" @@ -89,9 +90,20 @@ JNIEXPORT jlong JNICALL GRAPH_TEXTURE_FRAME_METHOD( JNIEXPORT void JNICALL GRAPH_TEXTURE_FRAME_METHOD(nativeDidRead)( JNIEnv* env, jobject thiz, jlong nativeHandle, jlong consumerSyncToken) { + if (!consumerSyncToken) return; + GlTextureBufferSharedPtr* buffer = reinterpret_cast(nativeHandle); mediapipe::GlSyncToken& token = *reinterpret_cast(consumerSyncToken); + // The below check attempts to detect when an invalid or already deleted + // `consumerSyncToken` is passed. (That results in undefined behavior. + // However, `DidRead` may succeed resulting in a later crash and masking the + // actual problem.) + if (token.use_count() == 0) { + LOG_FIRST_N(ERROR, 5) << absl::StrFormat("invalid sync token ref: %d", + consumerSyncToken); + return; + } (*buffer)->DidRead(token); } From 3719aaef7e8aab9a62985d5e1d947a8fe09b2540 Mon Sep 17 00:00:00 2001 From: Chuo-Ling Chang Date: Mon, 1 May 2023 23:50:27 -0700 Subject: [PATCH 164/753] Fix typo. PiperOrigin-RevId: 528693117 --- mediapipe/tasks/python/vision/face_landmarker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/python/vision/face_landmarker.py b/mediapipe/tasks/python/vision/face_landmarker.py index 870e7e43e..44ddba87e 100644 --- a/mediapipe/tasks/python/vision/face_landmarker.py +++ b/mediapipe/tasks/python/vision/face_landmarker.py @@ -2939,7 +2939,7 @@ class FaceLandmarkerOptions: Attributes: base_options: Base options for the face landmarker task. running_mode: The running mode of the task. Default to the image mode. - HandLandmarker has three running modes: 1) The image mode for detecting + FaceLandmarker has three running modes: 1) The image mode for detecting face landmarks on single image inputs. 2) The video mode for detecting face landmarks on the decoded frames of a video. 3) The live stream mode for detecting face landmarks on the live stream of input data, such as From 5b93477589412c3aa0e4a75d350380a797c1496e Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 2 May 2023 02:15:03 -0700 Subject: [PATCH 165/753] internal change PiperOrigin-RevId: 528719459 --- mediapipe/calculators/util/BUILD | 2 + .../util/flat_color_image_calculator.cc | 51 +++++++++--- .../util/flat_color_image_calculator_test.cc | 80 +++++++++++++++++++ 3 files changed, 123 insertions(+), 10 deletions(-) diff --git a/mediapipe/calculators/util/BUILD b/mediapipe/calculators/util/BUILD index 22e6b0738..b6f50b840 100644 --- a/mediapipe/calculators/util/BUILD +++ b/mediapipe/calculators/util/BUILD @@ -1285,12 +1285,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", diff --git a/mediapipe/calculators/util/flat_color_image_calculator.cc b/mediapipe/calculators/util/flat_color_image_calculator.cc index 71d3582c5..f3b9c184c 100644 --- a/mediapipe/calculators/util/flat_color_image_calculator.cc +++ b/mediapipe/calculators/util/flat_color_image_calculator.cc @@ -15,14 +15,13 @@ #include #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::Optional kInImage{"IMAGE"}; static constexpr Input::Optional kInColor{"COLOR"}; - static constexpr Output kOutImage{"IMAGE"}; + static constexpr Output::Optional kOutImage{"IMAGE"}; + static constexpr SideOutput::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(); @@ -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> 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> 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> output_frame = + CreateOutputFrame(cc); + if (output_frame.has_value()) { + kOutImage(cc).Send(Image(output_frame.value())); + } + } + + return absl::OkStatus(); +} + +std::optional> +FlatColorImageCalculator::CreateOutputFrame(CalculatorContext* cc) { const auto& options = cc->Options(); 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(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 diff --git a/mediapipe/calculators/util/flat_color_image_calculator_test.cc b/mediapipe/calculators/util/flat_color_image_calculator_test.cc index 53c6de1b1..c09064bf2 100644 --- a/mediapipe/calculators/util/flat_color_image_calculator_test.cc +++ b/mediapipe/calculators/util/flat_color_image_calculator_test.cc @@ -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(); + 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(ImageFormat::SRGB, + kImageWidth, kImageHeight); + + for (int ts = 0; ts < 3; ++ts) { + runner.MutableInputs()->Tag(kImageTag).packets.push_back( + MakePacket(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 From 7fdbbee5be85c06758c01211ea0c81bbcf223ccc Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 2 May 2023 09:04:56 -0700 Subject: [PATCH 166/753] Internal change PiperOrigin-RevId: 528799585 --- mediapipe/framework/tool/BUILD | 1 + mediapipe/framework/tool/test_util.cc | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/mediapipe/framework/tool/BUILD b/mediapipe/framework/tool/BUILD index fbdcf8c9e..4ae0bb607 100644 --- a/mediapipe/framework/tool/BUILD +++ b/mediapipe/framework/tool/BUILD @@ -791,6 +791,7 @@ cc_library( "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:str_format", "@stblib//:stb_image", "@stblib//:stb_image_write", ], diff --git a/mediapipe/framework/tool/test_util.cc b/mediapipe/framework/tool/test_util.cc index 5642941e9..64b5072c5 100644 --- a/mediapipe/framework/tool/test_util.cc +++ b/mediapipe/framework/tool/test_util.cc @@ -26,6 +26,7 @@ #include "absl/status/status.h" #include "absl/strings/match.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" #include "absl/strings/str_join.h" #include "absl/strings/substitute.h" #include "mediapipe/framework/calculator.pb.h" @@ -311,6 +312,13 @@ std::unique_ptr LoadTestPng(absl::string_view path, // Returns the path to the output if successful. absl::StatusOr SavePngTestOutput( const mediapipe::ImageFrame& image, absl::string_view prefix) { + absl::flat_hash_set supported_formats = { + ImageFormat::GRAY8, ImageFormat::SRGB, ImageFormat::SRGBA, + ImageFormat::LAB8, ImageFormat::SBGRA}; + if (!supported_formats.contains(image.Format())) { + return absl::CancelledError( + absl::StrFormat("Format %d can not be saved to PNG.", image.Format())); + } std::string now_string = absl::FormatTime(absl::Now()); std::string output_relative_path = absl::StrCat(prefix, "_", now_string, ".png"); From 60055f6feecdf9e7117622aabb68aedc77943629 Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Tue, 2 May 2023 10:28:28 -0700 Subject: [PATCH 167/753] Add more comments and usage example of the face stylizer graph. PiperOrigin-RevId: 528823127 --- .../tasks/cc/vision/face_stylizer/face_stylizer_graph.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc index 7c4e6f138..cb49ef59d 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc +++ b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc @@ -199,7 +199,9 @@ void ConfigureTensorsToImageCalculator( // STYLIZED_IMAGE - mediapipe::Image // The face stylization output image. // FACE_ALIGNMENT - mediapipe::Image -// The face alignment output image. +// The aligned face image that is fed to the face stylization model to +// perform stylization. Also useful for preparing face stylization training +// data. // IMAGE - mediapipe::Image // The input image that the face landmarker runs on and has the pixel data // stored on the target storage (CPU vs GPU). @@ -211,6 +213,7 @@ void ConfigureTensorsToImageCalculator( // input_stream: "NORM_RECT:norm_rect" // output_stream: "IMAGE:image_out" // output_stream: "STYLIZED_IMAGE:stylized_image" +// output_stream: "FACE_ALIGNMENT:face_alignment_image" // options { // [mediapipe.tasks.vision.face_stylizer.proto.FaceStylizerGraphOptions.ext] // { @@ -248,7 +251,7 @@ class FaceStylizerGraph : public core::ModelTaskGraph { ->mutable_face_landmarker_graph_options(), graph[Input(kImageTag)], graph[Input::Optional(kNormRectTag)], graph)); - const ModelResources* face_stylizer_model_resources; + const ModelResources* face_stylizer_model_resources = nullptr; if (output_stylized) { ASSIGN_OR_RETURN( const auto* model_resources, @@ -332,7 +335,7 @@ class FaceStylizerGraph : public core::ModelTaskGraph { auto face_rect = face_to_rect.Out(kNormRectTag); std::optional> face_alignment; - // Output face alignment only. + // Output aligned face only. // In this case, the face stylization model inference is not required. // However, to keep consistent with the inference preprocessing steps, the // ImageToTensorCalculator is still used to perform image rotation, From 4d112c132fed14fa61059b2fe20399a51639c98d Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 2 May 2023 10:35:16 -0700 Subject: [PATCH 168/753] Fix msan errors. PiperOrigin-RevId: 528825081 --- .../autoflip/quality/padding_effect_generator_test.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mediapipe/examples/desktop/autoflip/quality/padding_effect_generator_test.cc b/mediapipe/examples/desktop/autoflip/quality/padding_effect_generator_test.cc index 84b229d80..4c9e96b88 100644 --- a/mediapipe/examples/desktop/autoflip/quality/padding_effect_generator_test.cc +++ b/mediapipe/examples/desktop/autoflip/quality/padding_effect_generator_test.cc @@ -190,14 +190,16 @@ TEST(PaddingEffectGeneratorTest, ScaleToMultipleOfTwo) { double target_aspect_ratio = 0.5; int expect_width = 14; int expect_height = input_height; - auto test_frame = absl::make_unique(/*format=*/ImageFormat::SRGB, - input_width, input_height); + ImageFrame test_frame(/*format=*/ImageFormat::SRGB, input_width, + input_height); + cv::Mat mat = formats::MatView(&test_frame); + mat = cv::Scalar(0, 0, 0); - PaddingEffectGenerator generator(test_frame->Width(), test_frame->Height(), + PaddingEffectGenerator generator(test_frame.Width(), test_frame.Height(), target_aspect_ratio, /*scale_to_multiple_of_two=*/true); ImageFrame result_frame; - MP_ASSERT_OK(generator.Process(*test_frame, 0.3, 40, 0.0, &result_frame)); + MP_ASSERT_OK(generator.Process(test_frame, 0.3, 40, 0.0, &result_frame)); EXPECT_EQ(result_frame.Width(), expect_width); EXPECT_EQ(result_frame.Height(), expect_height); } From 421c9e8e97d8b33332b7564504c4f5090128474d Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 2 May 2023 10:49:40 -0700 Subject: [PATCH 169/753] Fix typo PiperOrigin-RevId: 528829423 --- mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc b/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc index 8d83ac2c8..2e5f7e416 100644 --- a/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc +++ b/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc @@ -242,7 +242,7 @@ class FaceDetectorGraph : public core::ModelTaskGraph { auto matrix = preprocessing.Out(kMatrixTag); auto image_size = preprocessing.Out(kImageSizeTag); - // Face detection model inferece. + // Face detection model inference. auto& inference = AddInference( model_resources, subgraph_options.base_options().acceleration(), graph); preprocessed_tensors >> inference.In(kTensorsTag); From 9ce16fddebcf0c7152ef9ecee670a6d352f4cfd6 Mon Sep 17 00:00:00 2001 From: Yuqi Li Date: Tue, 2 May 2023 11:54:23 -0700 Subject: [PATCH 170/753] nit: format the documentation of LandmarksDetectionResult. PiperOrigin-RevId: 528848566 --- .../components/containers/landmark_detection_result.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/python/components/containers/landmark_detection_result.py b/mediapipe/tasks/python/components/containers/landmark_detection_result.py index c60ad850c..fdb719b92 100644 --- a/mediapipe/tasks/python/components/containers/landmark_detection_result.py +++ b/mediapipe/tasks/python/components/containers/landmark_detection_result.py @@ -39,9 +39,11 @@ _Landmark = landmark_module.Landmark class LandmarksDetectionResult: """Represents the landmarks detection result. - Attributes: landmarks : A list of `NormalizedLandmark` objects. categories : A - list of `Category` objects. world_landmarks : A list of `Landmark` objects. - rect : A `NormalizedRect` object. + Attributes: + landmarks: A list of `NormalizedLandmark` objects. + categories: A list of `Category` objects. + world_landmarks: A list of `Landmark` objects. + rect: A `NormalizedRect` object. """ landmarks: Optional[List[_NormalizedLandmark]] From 4d9812af4396bc8fe72fe7618919bdd189a84afb Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Tue, 2 May 2023 13:49:24 -0700 Subject: [PATCH 171/753] Pose detector uses `advanced_gpu_api` for gpu inference to resolve unsupported gpu op issue. PiperOrigin-RevId: 528879218 --- .../pose_landmarker/pose_landmarker_graph.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph.cc index 826de5ec4..7889212e8 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_graph.cc @@ -108,9 +108,18 @@ absl::Status SetSubTaskBaseOptions(const ModelAssetBundleResources& resources, ->mutable_model_asset(), is_copy); } - pose_detector_graph_options->mutable_base_options() - ->mutable_acceleration() - ->CopyFrom(options->base_options().acceleration()); + if (options->base_options().acceleration().has_gpu()) { + core::proto::Acceleration gpu_accel; + gpu_accel.mutable_gpu()->set_use_advanced_gpu_api(true); + pose_detector_graph_options->mutable_base_options() + ->mutable_acceleration() + ->CopyFrom(gpu_accel); + + } else { + pose_detector_graph_options->mutable_base_options() + ->mutable_acceleration() + ->CopyFrom(options->base_options().acceleration()); + } pose_detector_graph_options->mutable_base_options()->set_use_stream_mode( options->base_options().use_stream_mode()); auto* pose_landmarks_detector_graph_options = From bf11fb313e34766a6f4e856f502178ebdaf0808d Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Tue, 2 May 2023 14:01:21 -0700 Subject: [PATCH 172/753] Expose PoseLandmarker as a public MediaPipe Tasks Python API. PiperOrigin-RevId: 528882303 --- mediapipe/tasks/python/vision/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mediapipe/tasks/python/vision/__init__.py b/mediapipe/tasks/python/vision/__init__.py index 75a8bd323..9dee86401 100644 --- a/mediapipe/tasks/python/vision/__init__.py +++ b/mediapipe/tasks/python/vision/__init__.py @@ -25,6 +25,7 @@ import mediapipe.tasks.python.vision.image_embedder import mediapipe.tasks.python.vision.image_segmenter import mediapipe.tasks.python.vision.interactive_segmenter import mediapipe.tasks.python.vision.object_detector +import mediapipe.tasks.python.vision.pose_landmarker FaceDetector = face_detector.FaceDetector FaceDetectorOptions = face_detector.FaceDetectorOptions @@ -54,6 +55,10 @@ InteractiveSegmenterOptions = interactive_segmenter.InteractiveSegmenterOptions InteractiveSegmenterRegionOfInterest = interactive_segmenter.RegionOfInterest ObjectDetector = object_detector.ObjectDetector ObjectDetectorOptions = object_detector.ObjectDetectorOptions +ObjectDetectorResult = object_detector.ObjectDetectorResult +PoseLandmarker = pose_landmarker.PoseLandmarker +PoseLandmarkerOptions = pose_landmarker.PoseLandmarkerOptions +PoseLandmarkerResult = pose_landmarker.PoseLandmarkerResult RunningMode = core.vision_task_running_mode.VisionTaskRunningMode # Remove unnecessary modules to avoid duplication in API docs. @@ -68,4 +73,5 @@ del image_embedder del image_segmenter del interactive_segmenter del object_detector +del pose_landmarker del mediapipe From c698381e48ad70b30fb752b71c2e702ef2ceed8f Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 2 May 2023 18:01:12 -0700 Subject: [PATCH 173/753] Internal change PiperOrigin-RevId: 528939095 --- .../com/google/mediapipe/tasks/vision/BUILD | 1 + .../PoseLandmarksConnections.java | 80 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarksConnections.java diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD index 5be0e233f..c27da79c7 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD @@ -180,6 +180,7 @@ android_library( srcs = [ "poselandmarker/PoseLandmarker.java", "poselandmarker/PoseLandmarkerResult.java", + "poselandmarker/PoseLandmarksConnections.java", ], javacopts = [ "-Xep:AndroidJdkLibsChecker:OFF", diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarksConnections.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarksConnections.java new file mode 100644 index 000000000..9be6a9aeb --- /dev/null +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarksConnections.java @@ -0,0 +1,80 @@ +// 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. + +package com.google.mediapipe.tasks.vision.poselandmarker; + +import com.google.auto.value.AutoValue; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** Pose landmarks connection constants. */ +public final class PoseLandmarksConnections { + + /** Value class representing pose landmarks connection. */ + @AutoValue + public abstract static class Connection { + static Connection create(int start, int end) { + return new AutoValue_PoseLandmarksConnections_Connection(start, end); + } + + public abstract int start(); + + public abstract int end(); + } + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set POSE_LANDMARKS = + Collections.unmodifiableSet( + new HashSet<>( + Arrays.asList( + Connection.create(0, 1), + Connection.create(1, 2), + Connection.create(2, 3), + Connection.create(3, 7), + Connection.create(0, 4), + Connection.create(4, 5), + Connection.create(5, 6), + Connection.create(6, 8), + Connection.create(9, 10), + Connection.create(11, 12), + Connection.create(11, 13), + Connection.create(13, 15), + Connection.create(15, 17), + Connection.create(15, 19), + Connection.create(15, 21), + Connection.create(17, 19), + Connection.create(12, 14), + Connection.create(14, 16), + Connection.create(16, 18), + Connection.create(16, 20), + Connection.create(16, 22), + Connection.create(18, 20), + Connection.create(11, 23), + Connection.create(12, 24), + Connection.create(23, 24), + Connection.create(23, 25), + Connection.create(24, 26), + Connection.create(25, 27), + Connection.create(26, 28), + Connection.create(27, 29), + Connection.create(28, 30), + Connection.create(29, 31), + Connection.create(30, 32), + Connection.create(27, 31), + Connection.create(28, 32)))); + + private PoseLandmarksConnections() {} +} From 1dea01aecc3ae30acf7698ac9eb5acf120712eb2 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 2 May 2023 22:55:12 -0700 Subject: [PATCH 174/753] Internal change PiperOrigin-RevId: 528996603 --- .../com/google/mediapipe/tasks/vision/BUILD | 1 + .../HandLandmarksConnections.java | 105 ++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarksConnections.java diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD index c27da79c7..a2dbe351a 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD @@ -213,6 +213,7 @@ android_library( "handlandmarker/HandLandmark.java", "handlandmarker/HandLandmarker.java", "handlandmarker/HandLandmarkerResult.java", + "handlandmarker/HandLandmarksConnections.java", ], javacopts = [ "-Xep:AndroidJdkLibsChecker:OFF", diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarksConnections.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarksConnections.java new file mode 100644 index 000000000..c60923840 --- /dev/null +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarksConnections.java @@ -0,0 +1,105 @@ +// 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. + +package com.google.mediapipe.tasks.vision.handlandmarker; + +import com.google.auto.value.AutoValue; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** Hand landmarks connection constants. */ +public final class HandLandmarksConnections { + + /** Value class representing hand landmarks connection. */ + @AutoValue + public abstract static class Connection { + static Connection create(int start, int end) { + return new AutoValue_HandLandmarksConnections_Connection(start, end); + } + + public abstract int start(); + + public abstract int end(); + } + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_PALM_CONNECTIONS = + Collections.unmodifiableSet( + new HashSet<>( + Arrays.asList( + Connection.create(0, 1), + Connection.create(0, 5), + Connection.create(9, 13), + Connection.create(13, 17), + Connection.create(5, 9), + Connection.create(0, 17)))); + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_THUMB_CONNECTIONS = + Collections.unmodifiableSet( + new HashSet<>( + Arrays.asList( + Connection.create(1, 2), Connection.create(2, 3), Connection.create(3, 4)))); + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_INDEX_FINGER_CONNECTIONS = + Collections.unmodifiableSet( + new HashSet<>( + Arrays.asList( + Connection.create(5, 6), Connection.create(6, 7), Connection.create(7, 8)))); + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_MIDDLE_FINGER_CONNECTIONS = + Collections.unmodifiableSet( + new HashSet<>( + Arrays.asList( + Connection.create(9, 10), Connection.create(10, 11), Connection.create(11, 12)))); + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_RING_FINGER_CONNECTIONS = + Collections.unmodifiableSet( + new HashSet<>( + Arrays.asList( + Connection.create(13, 14), + Connection.create(14, 15), + Connection.create(15, 16)))); + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_PINKY_FINGER_CONNECTIONS = + Collections.unmodifiableSet( + new HashSet<>( + Arrays.asList( + Connection.create(17, 18), + Connection.create(18, 19), + Connection.create(19, 20)))); + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_CONNECTIONS = + Collections.unmodifiableSet( + Stream.of( + HAND_PALM_CONNECTIONS.stream(), + HAND_THUMB_CONNECTIONS.stream(), + HAND_INDEX_FINGER_CONNECTIONS.stream(), + HAND_MIDDLE_FINGER_CONNECTIONS.stream(), + HAND_RING_FINGER_CONNECTIONS.stream(), + HAND_PINKY_FINGER_CONNECTIONS.stream()) + .flatMap(i -> i) + .collect(Collectors.toSet())); + + private HandLandmarksConnections() {} +} From 3789156a41cc4952a4a89f333d092d23b3eaa18d Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 3 May 2023 00:26:40 -0700 Subject: [PATCH 175/753] Internal change PiperOrigin-RevId: 529011480 --- .../port/drishti_proto_alias_rules.bzl | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 mediapipe/framework/port/drishti_proto_alias_rules.bzl diff --git a/mediapipe/framework/port/drishti_proto_alias_rules.bzl b/mediapipe/framework/port/drishti_proto_alias_rules.bzl new file mode 100644 index 000000000..7df141cbe --- /dev/null +++ b/mediapipe/framework/port/drishti_proto_alias_rules.bzl @@ -0,0 +1,31 @@ +"""Rules implementation for mediapipe_proto_alias.bzl, do not load directly.""" + +def _copy_header_impl(ctx): + source = ctx.attr.source.replace("//", "").replace(":", "/") + files = [] + for dep in ctx.attr.deps: + for header in dep[CcInfo].compilation_context.direct_headers: + if (header.short_path == source): + files.append(header) + if len(files) != 1: + fail("Expected exactly 1 source, got ", str(files)) + dest_file = ctx.actions.declare_file(ctx.attr.filename) + + # Use expand_template() with no substitutions as a simple copier. + ctx.actions.expand_template( + template = files[0], + output = dest_file, + substitutions = {}, + ) + return [DefaultInfo(files = depset([dest_file]))] + +copy_header = rule( + implementation = _copy_header_impl, + attrs = { + "filename": attr.string(), + "source": attr.string(), + "deps": attr.label_list(providers = [CcInfo]), + }, + output_to_genfiles = True, + outputs = {"out": "%{filename}"}, +) From baa8fc68a1b3b3280968fa526413b486ffd5229b Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 3 May 2023 05:55:25 -0700 Subject: [PATCH 176/753] Make uploading to GPU optional in Image.GetGpuBuffer(). PiperOrigin-RevId: 529066617 --- .../tensor/image_to_tensor_converter_frame_buffer.cc | 3 ++- mediapipe/framework/formats/image.h | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/mediapipe/calculators/tensor/image_to_tensor_converter_frame_buffer.cc b/mediapipe/calculators/tensor/image_to_tensor_converter_frame_buffer.cc index 093f50d76..6f6f6f11c 100644 --- a/mediapipe/calculators/tensor/image_to_tensor_converter_frame_buffer.cc +++ b/mediapipe/calculators/tensor/image_to_tensor_converter_frame_buffer.cc @@ -95,7 +95,8 @@ absl::Status FrameBufferProcessor::Convert(const mediapipe::Image& input, static_cast(range_max) == 255); } - auto input_frame = input.GetGpuBuffer().GetReadView(); + auto input_frame = + input.GetGpuBuffer(/*upload_to_gpu=*/false).GetReadView(); const auto& output_shape = output_tensor.shape(); MP_RETURN_IF_ERROR(ValidateTensorShape(output_shape)); FrameBuffer::Dimension output_dimension{/*width=*/output_shape.dims[2], diff --git a/mediapipe/framework/formats/image.h b/mediapipe/framework/formats/image.h index ffb6362f3..936a3554e 100644 --- a/mediapipe/framework/formats/image.h +++ b/mediapipe/framework/formats/image.h @@ -113,11 +113,11 @@ class Image { #endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER #endif // !MEDIAPIPE_DISABLE_GPU - // Get a GPU view. Automatically uploads from CPU if needed. - const mediapipe::GpuBuffer GetGpuBuffer() const { -#if !MEDIAPIPE_DISABLE_GPU - if (use_gpu_ == false) ConvertToGpu(); -#endif // !MEDIAPIPE_DISABLE_GPU + // Provides access to the underlying GpuBuffer storage. + // Automatically uploads from CPU to GPU if needed and requested through the + // `upload_to_gpu` argument. + const mediapipe::GpuBuffer GetGpuBuffer(bool upload_to_gpu = true) const { + if (!use_gpu_ && upload_to_gpu) ConvertToGpu(); return gpu_buffer_; } From 09662749ea433f1d5b8b4b9a9b86c341a1574658 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 3 May 2023 11:58:26 -0700 Subject: [PATCH 177/753] Support scribble input for Interactive Segmenter PiperOrigin-RevId: 529156049 --- .../interactive_segmenter.cc | 18 +++++- .../interactive_segmenter.h | 8 ++- .../interactive_segmenter_test.cc | 63 +++++++++++++++---- mediapipe/util/annotation_renderer.cc | 15 ++++- mediapipe/util/annotation_renderer.h | 5 ++ mediapipe/util/render_data.proto | 5 ++ 6 files changed, 99 insertions(+), 15 deletions(-) diff --git a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc index af2a3f50c..c0d89c87d 100644 --- a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc +++ b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc @@ -28,6 +28,7 @@ limitations under the License. #include "mediapipe/framework/formats/image.h" #include "mediapipe/framework/formats/rect.pb.h" #include "mediapipe/tasks/cc/common.h" +#include "mediapipe/tasks/cc/components/containers/keypoint.h" #include "mediapipe/tasks/cc/core/base_options.h" #include "mediapipe/tasks/cc/vision/core/image_processing_options.h" #include "mediapipe/tasks/cc/vision/core/running_mode.h" @@ -60,6 +61,8 @@ constexpr absl::string_view kNormRectTag{"NORM_RECT"}; constexpr absl::string_view kSubgraphTypeName{ "mediapipe.tasks.vision.interactive_segmenter.InteractiveSegmenterGraph"}; +using components::containers::NormalizedKeypoint; + using ::mediapipe::CalculatorGraphConfig; using ::mediapipe::Image; using ::mediapipe::NormalizedRect; @@ -115,7 +118,7 @@ absl::StatusOr ConvertRoiToRenderData(const RegionOfInterest& roi) { case RegionOfInterest::Format::kUnspecified: return absl::InvalidArgumentError( "RegionOfInterest format not specified"); - case RegionOfInterest::Format::kKeyPoint: + case RegionOfInterest::Format::kKeyPoint: { RET_CHECK(roi.keypoint.has_value()); auto* annotation = result.add_render_annotations(); annotation->mutable_color()->set_r(255); @@ -124,6 +127,19 @@ absl::StatusOr ConvertRoiToRenderData(const RegionOfInterest& roi) { point->set_x(roi.keypoint->x); point->set_y(roi.keypoint->y); return result; + } + case RegionOfInterest::Format::kScribble: { + RET_CHECK(roi.scribble.has_value()); + auto* annotation = result.add_render_annotations(); + annotation->mutable_color()->set_r(255); + for (const NormalizedKeypoint& keypoint : *(roi.scribble)) { + auto* point = annotation->mutable_scribble()->add_point(); + point->set_normalized(true); + point->set_x(keypoint.x); + point->set_y(keypoint.y); + } + return result; + } } return absl::UnimplementedError("Unrecognized format"); } diff --git a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.h b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.h index ad4a238df..ad8a558df 100644 --- a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.h +++ b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.h @@ -53,6 +53,7 @@ struct RegionOfInterest { enum class Format { kUnspecified = 0, // Format not specified. kKeyPoint = 1, // Using keypoint to represent ROI. + kScribble = 2, // Using scribble to represent ROI. }; // Specifies the format used to specify the region-of-interest. Note that @@ -61,8 +62,13 @@ struct RegionOfInterest { Format format = Format::kUnspecified; // Represents the ROI in keypoint format, this should be non-nullopt if - // `format` is `KEYPOINT`. + // `format` is `kKeyPoint`. std::optional keypoint; + + // Represents the ROI in scribble format, this should be non-nullopt if + // `format` is `kScribble`. + std::optional> + scribble; }; // Performs interactive segmentation on images. diff --git a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_test.cc b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_test.cc index 443247aea..16d065f61 100644 --- a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_test.cc +++ b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_test.cc @@ -18,9 +18,12 @@ limitations under the License. #include #include #include +#include +#include #include "absl/flags/flag.h" #include "absl/status/status.h" +#include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "mediapipe/framework/deps/file_path.h" #include "mediapipe/framework/formats/image.h" @@ -179,22 +182,46 @@ TEST_F(CreateFromOptionsTest, FailsWithNeitherOutputSet) { struct InteractiveSegmenterTestParams { std::string test_name; RegionOfInterest::Format format; - NormalizedKeypoint roi; + std::variant> roi; absl::string_view golden_mask_file; float similarity_threshold; }; -using SucceedSegmentationWithRoi = - ::testing::TestWithParam; +class SucceedSegmentationWithRoi + : public ::testing::TestWithParam { + public: + absl::StatusOr TestParamsToTaskOptions() { + const InteractiveSegmenterTestParams& params = GetParam(); + + RegionOfInterest interaction_roi; + interaction_roi.format = params.format; + switch (params.format) { + case (RegionOfInterest::Format::kKeyPoint): { + interaction_roi.keypoint = std::get(params.roi); + break; + } + case (RegionOfInterest::Format::kScribble): { + interaction_roi.scribble = + std::get>(params.roi); + break; + } + default: { + return absl::InvalidArgumentError("Unknown ROI format"); + } + } + + return interaction_roi; + } +}; TEST_P(SucceedSegmentationWithRoi, SucceedsWithCategoryMask) { + MP_ASSERT_OK_AND_ASSIGN(RegionOfInterest interaction_roi, + TestParamsToTaskOptions()); const InteractiveSegmenterTestParams& params = GetParam(); + MP_ASSERT_OK_AND_ASSIGN( Image image, DecodeImageFromFile(JoinPath("./", kTestDataDirectory, kCatsAndDogsJpg))); - RegionOfInterest interaction_roi; - interaction_roi.format = params.format; - interaction_roi.keypoint = params.roi; auto options = std::make_unique(); options->base_options.model_asset_path = JoinPath("./", kTestDataDirectory, kPtmModel); @@ -220,13 +247,13 @@ TEST_P(SucceedSegmentationWithRoi, SucceedsWithCategoryMask) { } TEST_P(SucceedSegmentationWithRoi, SucceedsWithConfidenceMask) { - const auto& params = GetParam(); + MP_ASSERT_OK_AND_ASSIGN(RegionOfInterest interaction_roi, + TestParamsToTaskOptions()); + const InteractiveSegmenterTestParams& params = GetParam(); + MP_ASSERT_OK_AND_ASSIGN( Image image, DecodeImageFromFile(JoinPath("./", kTestDataDirectory, kCatsAndDogsJpg))); - RegionOfInterest interaction_roi; - interaction_roi.format = params.format; - interaction_roi.keypoint = params.roi; auto options = std::make_unique(); options->base_options.model_asset_path = JoinPath("./", kTestDataDirectory, kPtmModel); @@ -253,11 +280,23 @@ TEST_P(SucceedSegmentationWithRoi, SucceedsWithConfidenceMask) { INSTANTIATE_TEST_SUITE_P( SucceedSegmentationWithRoiTest, SucceedSegmentationWithRoi, ::testing::ValuesIn( - {{"PointToDog1", RegionOfInterest::Format::kKeyPoint, + {// Keypoint input. + {"PointToDog1", RegionOfInterest::Format::kKeyPoint, NormalizedKeypoint{0.44, 0.70}, kCatsAndDogsMaskDog1, 0.84f}, {"PointToDog2", RegionOfInterest::Format::kKeyPoint, NormalizedKeypoint{0.66, 0.66}, kCatsAndDogsMaskDog2, - kGoldenMaskSimilarity}}), + kGoldenMaskSimilarity}, + // Scribble input. + {"ScribbleToDog1", RegionOfInterest::Format::kScribble, + std::vector{NormalizedKeypoint{0.44, 0.70}, + NormalizedKeypoint{0.44, 0.71}, + NormalizedKeypoint{0.44, 0.72}}, + kCatsAndDogsMaskDog1, 0.84f}, + {"ScribbleToDog2", RegionOfInterest::Format::kScribble, + std::vector{NormalizedKeypoint{0.66, 0.66}, + NormalizedKeypoint{0.66, 0.67}, + NormalizedKeypoint{0.66, 0.68}}, + kCatsAndDogsMaskDog2, kGoldenMaskSimilarity}}), [](const ::testing::TestParamInfo& info) { return info.param.test_name; }); diff --git a/mediapipe/util/annotation_renderer.cc b/mediapipe/util/annotation_renderer.cc index 5188da896..d8516f9bc 100644 --- a/mediapipe/util/annotation_renderer.cc +++ b/mediapipe/util/annotation_renderer.cc @@ -22,6 +22,7 @@ #include "mediapipe/framework/port/logging.h" #include "mediapipe/framework/port/vector.h" #include "mediapipe/util/color.pb.h" +#include "mediapipe/util/render_data.pb.h" namespace mediapipe { namespace { @@ -112,6 +113,8 @@ void AnnotationRenderer::RenderDataOnImage(const RenderData& render_data) { DrawGradientLine(annotation); } else if (annotation.data_case() == RenderAnnotation::kArrow) { DrawArrow(annotation); + } else if (annotation.data_case() == RenderAnnotation::kScribble) { + DrawScribble(annotation); } else { LOG(FATAL) << "Unknown annotation type: " << annotation.data_case(); } @@ -442,7 +445,11 @@ void AnnotationRenderer::DrawArrow(const RenderAnnotation& annotation) { } void AnnotationRenderer::DrawPoint(const RenderAnnotation& annotation) { - const auto& point = annotation.point(); + DrawPoint(annotation.point(), annotation); +} + +void AnnotationRenderer::DrawPoint(const RenderAnnotation::Point& point, + const RenderAnnotation& annotation) { int x = -1; int y = -1; if (point.normalized()) { @@ -460,6 +467,12 @@ void AnnotationRenderer::DrawPoint(const RenderAnnotation& annotation) { cv::circle(mat_image_, point_to_draw, thickness, color, -1); } +void AnnotationRenderer::DrawScribble(const RenderAnnotation& annotation) { + for (const RenderAnnotation::Point& point : annotation.scribble().point()) { + DrawPoint(point, annotation); + } +} + void AnnotationRenderer::DrawLine(const RenderAnnotation& annotation) { int x_start = -1; int y_start = -1; diff --git a/mediapipe/util/annotation_renderer.h b/mediapipe/util/annotation_renderer.h index 380bc3614..ae0cf976e 100644 --- a/mediapipe/util/annotation_renderer.h +++ b/mediapipe/util/annotation_renderer.h @@ -96,6 +96,11 @@ class AnnotationRenderer { // Draws a point on the image as described in the annotation. void DrawPoint(const RenderAnnotation& annotation); + void DrawPoint(const RenderAnnotation::Point& point, + const RenderAnnotation& annotation); + + // Draws scribbles on the image as described in the annotation. + void DrawScribble(const RenderAnnotation& annotation); // Draws a line segment on the image as described in the annotation. void DrawLine(const RenderAnnotation& annotation); diff --git a/mediapipe/util/render_data.proto b/mediapipe/util/render_data.proto index fee02fff3..897d5fa37 100644 --- a/mediapipe/util/render_data.proto +++ b/mediapipe/util/render_data.proto @@ -131,6 +131,10 @@ message RenderAnnotation { optional Color color2 = 7; } + message Scribble { + repeated Point point = 1; + } + message Arrow { // The arrow head will be drawn at (x_end, y_end). optional double x_start = 1; @@ -192,6 +196,7 @@ message RenderAnnotation { RoundedRectangle rounded_rectangle = 9; FilledRoundedRectangle filled_rounded_rectangle = 10; GradientLine gradient_line = 14; + Scribble scribble = 15; } // Thickness for drawing the annotation. From c78055921492d567d89e36b3d75d069f6e376927 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 3 May 2023 12:18:16 -0700 Subject: [PATCH 178/753] Internal change PiperOrigin-RevId: 529161249 --- mediapipe/tasks/python/vision/__init__.py | 1 + .../tasks/python/vision/pose_landmarker.py | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/mediapipe/tasks/python/vision/__init__.py b/mediapipe/tasks/python/vision/__init__.py index 9dee86401..cea950ea7 100644 --- a/mediapipe/tasks/python/vision/__init__.py +++ b/mediapipe/tasks/python/vision/__init__.py @@ -59,6 +59,7 @@ ObjectDetectorResult = object_detector.ObjectDetectorResult PoseLandmarker = pose_landmarker.PoseLandmarker PoseLandmarkerOptions = pose_landmarker.PoseLandmarkerOptions PoseLandmarkerResult = pose_landmarker.PoseLandmarkerResult +PoseLandmarksConnections = pose_landmarker.PoseLandmarksConnections RunningMode = core.vision_task_running_mode.VisionTaskRunningMode # Remove unnecessary modules to avoid duplication in API docs. diff --git a/mediapipe/tasks/python/vision/pose_landmarker.py b/mediapipe/tasks/python/vision/pose_landmarker.py index b91eb0326..3ff7edb0a 100644 --- a/mediapipe/tasks/python/vision/pose_landmarker.py +++ b/mediapipe/tasks/python/vision/pose_landmarker.py @@ -132,6 +132,55 @@ def _build_landmarker_result( return pose_landmarker_result +class PoseLandmarksConnections: + """The connections between pose landmarks.""" + + @dataclasses.dataclass + class Connection: + """The connection class for pose landmarks.""" + + start: int + end: int + + POSE_LANDMARKS: List[Connection] = [ + Connection(0, 1), + Connection(1, 2), + Connection(2, 3), + Connection(3, 7), + Connection(0, 4), + Connection(4, 5), + Connection(5, 6), + Connection(6, 8), + Connection(9, 10), + Connection(11, 12), + Connection(11, 13), + Connection(13, 15), + Connection(15, 17), + Connection(15, 19), + Connection(15, 21), + Connection(17, 19), + Connection(12, 14), + Connection(14, 16), + Connection(16, 18), + Connection(16, 20), + Connection(16, 22), + Connection(18, 20), + Connection(11, 23), + Connection(12, 24), + Connection(23, 24), + Connection(23, 25), + Connection(24, 26), + Connection(25, 27), + Connection(26, 28), + Connection(27, 29), + Connection(28, 30), + Connection(29, 31), + Connection(30, 32), + Connection(27, 31), + Connection(28, 32) + ] + + @dataclasses.dataclass class PoseLandmarkerOptions: """Options for the pose landmarker task. From 7c955246aaf8f9a4d0200317c0500591d877f8a7 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 3 May 2023 13:19:51 -0700 Subject: [PATCH 179/753] Support scribble input for Interactive Segmenter Java API PiperOrigin-RevId: 529177660 --- .../InteractiveSegmenter.java | 23 ++++++++ .../InteractiveSegmenterTest.java | 57 ++++++++++++++++++- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java index 52a5f2a67..e9ff1f2b5 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java @@ -502,6 +502,7 @@ public final class InteractiveSegmenter extends BaseVisionTaskApi { /** The Region-Of-Interest (ROI) to interact with. */ public static class RegionOfInterest { private NormalizedKeypoint keypoint; + private List scribble; private RegionOfInterest() {} @@ -514,6 +515,16 @@ public final class InteractiveSegmenter extends BaseVisionTaskApi { roi.keypoint = keypoint; return roi; } + + /** + * Creates a {@link RegionOfInterest} instance representing scribbles over the object that the + * user wants to segment. + */ + public static RegionOfInterest create(List scribble) { + RegionOfInterest roi = new RegionOfInterest(); + roi.scribble = scribble; + return roi; + } } /** @@ -535,6 +546,18 @@ public final class InteractiveSegmenter extends BaseVisionTaskApi { .setX(roi.keypoint.x()) .setY(roi.keypoint.y()))) .build(); + } else if (roi.scribble != null) { + RenderAnnotation.Scribble.Builder scribbleBuilder = RenderAnnotation.Scribble.newBuilder(); + for (NormalizedKeypoint p : roi.scribble) { + scribbleBuilder.addPoint(RenderAnnotation.Point.newBuilder().setX(p.x()).setY(p.y())); + } + + return builder + .addRenderAnnotations( + RenderAnnotation.newBuilder() + .setColor(Color.newBuilder().setR(255)) + .setScribble(scribbleBuilder)) + .build(); } throw new IllegalArgumentException( diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenterTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenterTest.java index 506036ba2..a534970f7 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenterTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenterTest.java @@ -27,6 +27,7 @@ import com.google.mediapipe.tasks.core.BaseOptions; import com.google.mediapipe.tasks.vision.imagesegmenter.ImageSegmenterResult; import com.google.mediapipe.tasks.vision.interactivesegmenter.InteractiveSegmenter.InteractiveSegmenterOptions; import java.io.InputStream; +import java.util.ArrayList; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,7 +37,8 @@ import org.junit.runners.Suite.SuiteClasses; /** Test for {@link InteractiveSegmenter}. */ @RunWith(Suite.class) @SuiteClasses({ - InteractiveSegmenterTest.General.class, + InteractiveSegmenterTest.KeypointRoi.class, + InteractiveSegmenterTest.ScribbleRoi.class, }) public class InteractiveSegmenterTest { private static final String DEEPLAB_MODEL_FILE = "ptm_512_hdt_ptm_woid.tflite"; @@ -44,7 +46,7 @@ public class InteractiveSegmenterTest { private static final int MAGNIFICATION_FACTOR = 10; @RunWith(AndroidJUnit4.class) - public static final class General extends InteractiveSegmenterTest { + public static final class KeypointRoi extends InteractiveSegmenterTest { @Test public void segment_successWithCategoryMask() throws Exception { final String inputImageName = CATS_AND_DOGS_IMAGE; @@ -86,6 +88,57 @@ public class InteractiveSegmenterTest { } } + @RunWith(AndroidJUnit4.class) + public static final class ScribbleRoi extends InteractiveSegmenterTest { + @Test + public void segment_successWithCategoryMask() throws Exception { + final String inputImageName = CATS_AND_DOGS_IMAGE; + ArrayList scribble = new ArrayList<>(); + scribble.add(NormalizedKeypoint.create(0.25f, 0.9f)); + scribble.add(NormalizedKeypoint.create(0.25f, 0.91f)); + scribble.add(NormalizedKeypoint.create(0.25f, 0.92f)); + final InteractiveSegmenter.RegionOfInterest roi = + InteractiveSegmenter.RegionOfInterest.create(scribble); + InteractiveSegmenterOptions options = + InteractiveSegmenterOptions.builder() + .setBaseOptions(BaseOptions.builder().setModelAssetPath(DEEPLAB_MODEL_FILE).build()) + .setOutputConfidenceMasks(false) + .setOutputCategoryMask(true) + .build(); + InteractiveSegmenter imageSegmenter = + InteractiveSegmenter.createFromOptions( + ApplicationProvider.getApplicationContext(), options); + MPImage image = getImageFromAsset(inputImageName); + ImageSegmenterResult actualResult = imageSegmenter.segment(image, roi); + assertThat(actualResult.categoryMask().isPresent()).isTrue(); + } + + @Test + public void segment_successWithConfidenceMask() throws Exception { + final String inputImageName = CATS_AND_DOGS_IMAGE; + ArrayList scribble = new ArrayList<>(); + scribble.add(NormalizedKeypoint.create(0.25f, 0.9f)); + scribble.add(NormalizedKeypoint.create(0.25f, 0.91f)); + scribble.add(NormalizedKeypoint.create(0.25f, 0.92f)); + final InteractiveSegmenter.RegionOfInterest roi = + InteractiveSegmenter.RegionOfInterest.create(scribble); + InteractiveSegmenterOptions options = + InteractiveSegmenterOptions.builder() + .setBaseOptions(BaseOptions.builder().setModelAssetPath(DEEPLAB_MODEL_FILE).build()) + .setOutputConfidenceMasks(true) + .setOutputCategoryMask(false) + .build(); + InteractiveSegmenter imageSegmenter = + InteractiveSegmenter.createFromOptions( + ApplicationProvider.getApplicationContext(), options); + ImageSegmenterResult actualResult = + imageSegmenter.segment(getImageFromAsset(inputImageName), roi); + assertThat(actualResult.confidenceMasks().isPresent()).isTrue(); + List confidenceMasks = actualResult.confidenceMasks().get(); + assertThat(confidenceMasks.size()).isEqualTo(2); + } + } + private static MPImage getImageFromAsset(String filePath) throws Exception { AssetManager assetManager = ApplicationProvider.getApplicationContext().getAssets(); InputStream istr = assetManager.open(filePath); From 606b83ac65911c384537044831f15ad7a90d9573 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 3 May 2023 13:30:08 -0700 Subject: [PATCH 180/753] Internal change PiperOrigin-RevId: 529180655 --- mediapipe/tasks/python/vision/__init__.py | 1 + .../tasks/python/vision/hand_landmarker.py | 59 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/mediapipe/tasks/python/vision/__init__.py b/mediapipe/tasks/python/vision/__init__.py index cea950ea7..3c3f34db0 100644 --- a/mediapipe/tasks/python/vision/__init__.py +++ b/mediapipe/tasks/python/vision/__init__.py @@ -42,6 +42,7 @@ GestureRecognizerResult = gesture_recognizer.GestureRecognizerResult HandLandmarker = hand_landmarker.HandLandmarker HandLandmarkerOptions = hand_landmarker.HandLandmarkerOptions HandLandmarkerResult = hand_landmarker.HandLandmarkerResult +HandLandmarksConnections = hand_landmarker.HandLandmarksConnections ImageClassifier = image_classifier.ImageClassifier ImageClassifierOptions = image_classifier.ImageClassifierOptions ImageClassifierResult = image_classifier.ImageClassifierResult diff --git a/mediapipe/tasks/python/vision/hand_landmarker.py b/mediapipe/tasks/python/vision/hand_landmarker.py index 1f2c629d2..e781c8882 100644 --- a/mediapipe/tasks/python/vision/hand_landmarker.py +++ b/mediapipe/tasks/python/vision/hand_landmarker.py @@ -82,6 +82,65 @@ class HandLandmark(enum.IntEnum): PINKY_TIP = 20 +class HandLandmarksConnections: + """The connections between hand landmarks.""" + + @dataclasses.dataclass + class Connection: + """The connection class for hand landmarks.""" + + start: int + end: int + + HAND_PALM_CONNECTIONS: List[Connection] = [ + Connection(0, 1), + Connection(1, 5), + Connection(9, 13), + Connection(13, 17), + Connection(5, 9), + Connection(0, 17), + ] + + HAND_THUMB_CONNECTIONS: List[Connection] = [ + Connection(1, 2), + Connection(2, 3), + Connection(3, 4), + ] + + HAND_INDEX_FINGER_CONNECTIONS: List[Connection] = [ + Connection(5, 6), + Connection(6, 7), + Connection(7, 8), + ] + + HAND_MIDDLE_FINGER_CONNECTIONS: List[Connection] = [ + Connection(9, 10), + Connection(10, 11), + Connection(11, 12), + ] + + HAND_RING_FINGER_CONNECTIONS: List[Connection] = [ + Connection(13, 14), + Connection(14, 15), + Connection(15, 16), + ] + + HAND_PINKY_FINGER_CONNECTIONS: List[Connection] = [ + Connection(17, 18), + Connection(18, 19), + Connection(19, 20), + ] + + HAND_CONNECTIONS: List[Connection] = ( + HAND_PALM_CONNECTIONS + + HAND_THUMB_CONNECTIONS + + HAND_INDEX_FINGER_CONNECTIONS + + HAND_MIDDLE_FINGER_CONNECTIONS + + HAND_RING_FINGER_CONNECTIONS + + HAND_PINKY_FINGER_CONNECTIONS + ) + + @dataclasses.dataclass class HandLandmarkerResult: """The hand landmarks result from HandLandmarker, where each vector element represents a single hand detected in the image. From e428bdb7e89aa101e442d05cc75157915f0ee5c3 Mon Sep 17 00:00:00 2001 From: Yuqi Li Date: Wed, 3 May 2023 13:32:20 -0700 Subject: [PATCH 181/753] internal change. PiperOrigin-RevId: 529181374 --- .../tasks/vision/core/BaseVisionTaskApi.java | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java index 070806522..5964cef2c 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java @@ -77,11 +77,13 @@ public class BaseVisionTaskApi implements AutoCloseable { } Map inputPackets = new HashMap<>(); inputPackets.put(imageStreamName, runner.getPacketCreator().createImage(image)); - inputPackets.put( - normRectStreamName, - runner - .getPacketCreator() - .createProto(convertToNormalizedRect(imageProcessingOptions, image))); + if (!normRectStreamName.isEmpty()) { + inputPackets.put( + normRectStreamName, + runner + .getPacketCreator() + .createProto(convertToNormalizedRect(imageProcessingOptions, image))); + } return runner.process(inputPackets); } @@ -105,11 +107,13 @@ public class BaseVisionTaskApi implements AutoCloseable { } Map inputPackets = new HashMap<>(); inputPackets.put(imageStreamName, runner.getPacketCreator().createImage(image)); - inputPackets.put( - normRectStreamName, - runner - .getPacketCreator() - .createProto(convertToNormalizedRect(imageProcessingOptions, image))); + if (!normRectStreamName.isEmpty()) { + inputPackets.put( + normRectStreamName, + runner + .getPacketCreator() + .createProto(convertToNormalizedRect(imageProcessingOptions, image))); + } return runner.process(inputPackets, timestampMs * MICROSECONDS_PER_MILLISECOND); } @@ -133,11 +137,13 @@ public class BaseVisionTaskApi implements AutoCloseable { } Map inputPackets = new HashMap<>(); inputPackets.put(imageStreamName, runner.getPacketCreator().createImage(image)); - inputPackets.put( - normRectStreamName, - runner - .getPacketCreator() - .createProto(convertToNormalizedRect(imageProcessingOptions, image))); + if (!normRectStreamName.isEmpty()) { + inputPackets.put( + normRectStreamName, + runner + .getPacketCreator() + .createProto(convertToNormalizedRect(imageProcessingOptions, image))); + } runner.send(inputPackets, timestampMs * MICROSECONDS_PER_MILLISECOND); } From a09e39d431ca216f35bc45c52985449c4b23a189 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 3 May 2023 15:44:42 -0700 Subject: [PATCH 182/753] Add TransformerParameters proto PiperOrigin-RevId: 529213840 --- .../cc/components/processors/proto/BUILD | 5 ++ .../processors/proto/transformer_params.proto | 46 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 mediapipe/tasks/cc/components/processors/proto/transformer_params.proto diff --git a/mediapipe/tasks/cc/components/processors/proto/BUILD b/mediapipe/tasks/cc/components/processors/proto/BUILD index 82d4ea21b..a45c91633 100644 --- a/mediapipe/tasks/cc/components/processors/proto/BUILD +++ b/mediapipe/tasks/cc/components/processors/proto/BUILD @@ -93,3 +93,8 @@ mediapipe_proto_library( "//mediapipe/framework:calculator_proto", ], ) + +mediapipe_proto_library( + name = "transformer_params_proto", + srcs = ["transformer_params.proto"], +) diff --git a/mediapipe/tasks/cc/components/processors/proto/transformer_params.proto b/mediapipe/tasks/cc/components/processors/proto/transformer_params.proto new file mode 100644 index 000000000..8c1daf277 --- /dev/null +++ b/mediapipe/tasks/cc/components/processors/proto/transformer_params.proto @@ -0,0 +1,46 @@ +/* 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. +==============================================================================*/ + +syntax = "proto3"; + +package mediapipe.tasks.components.processors.proto; + +option java_package = "com.google.mediapipe.tasks.components.processors.proto"; +option java_outer_classname = "TransformerParametersProto"; + +// The parameters of transformer (https://arxiv.org/pdf/1706.03762.pdf) +message TransformerParameters { + // Batch size of tensors. + int32 batch_size = 1; + + // Maximum sequence length of the input/output tensor. + int32 max_seq_length = 2; + + // Embedding dimension (or model dimension), `d_model` in the paper. + // `d_k` == `d_v` == `d_model`/`h`. + int32 embedding_dim = 3; + + // Hidden dimension used in the feedforward layer, `d_ff` in the paper. + int32 hidden_dimension = 4; + + // Head dimension, `d_k` or `d_v` in the paper. + int32 head_dimension = 5; + + // Number of heads, `h` in the paper. + int32 num_heads = 6; + + // Number of stacked transformers, `N` in the paper. + int32 num_stacks = 7; +} From b350f7239482b542db325f5fa52d5a3e9193778a Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 3 May 2023 16:10:51 -0700 Subject: [PATCH 183/753] Support MultiHW AVG Architecture for object detector PiperOrigin-RevId: 529221127 --- .../python/vision/object_detector/model.py | 9 +++++++-- .../vision/object_detector/model_spec.py | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/mediapipe/model_maker/python/vision/object_detector/model.py b/mediapipe/model_maker/python/vision/object_detector/model.py index eac669786..e3eb3a651 100644 --- a/mediapipe/model_maker/python/vision/object_detector/model.py +++ b/mediapipe/model_maker/python/vision/object_detector/model.py @@ -59,7 +59,9 @@ class ObjectDetectorModel(tf.keras.Model): self._num_classes = num_classes self._model = self._build_model() checkpoint_folder = self._model_spec.downloaded_files.get_path() - checkpoint_file = os.path.join(checkpoint_folder, 'ckpt-277200') + checkpoint_file = os.path.join( + checkpoint_folder, self._model_spec.checkpoint_name + ) self.load_checkpoint(checkpoint_file) self._model.summary() self.loss_trackers = [ @@ -80,7 +82,10 @@ class ObjectDetectorModel(tf.keras.Model): num_scales=3, aspect_ratios=[0.5, 1.0, 2.0], anchor_size=3 ), backbone=configs.backbones.Backbone( - type='mobilenet', mobilenet=configs.backbones.MobileNet() + type='mobilenet', + mobilenet=configs.backbones.MobileNet( + model_id=self._model_spec.model_id + ), ), decoder=configs.decoders.Decoder( type='fpn', diff --git a/mediapipe/model_maker/python/vision/object_detector/model_spec.py b/mediapipe/model_maker/python/vision/object_detector/model_spec.py index 2ce838c71..9c89c4ed0 100644 --- a/mediapipe/model_maker/python/vision/object_detector/model_spec.py +++ b/mediapipe/model_maker/python/vision/object_detector/model_spec.py @@ -26,6 +26,12 @@ MOBILENET_V2_FILES = file_util.DownloadedFiles( is_folder=True, ) +MOBILENET_MULTI_AVG_FILES = file_util.DownloadedFiles( + 'object_detector/mobilenetmultiavg', + 'https://storage.googleapis.com/tf_model_garden/vision/qat/mobilenetv3.5_ssd_coco/mobilenetv3.5_ssd_i256_ckpt.tar.gz', + is_folder=True, +) + @dataclasses.dataclass class ModelSpec(object): @@ -38,13 +44,25 @@ class ModelSpec(object): stddev_rgb = (127.5,) downloaded_files: file_util.DownloadedFiles + checkpoint_name: str input_image_shape: List[int] + model_id: str mobilenet_v2_spec = functools.partial( ModelSpec, downloaded_files=MOBILENET_V2_FILES, + checkpoint_name='ckpt-277200', input_image_shape=[256, 256, 3], + model_id='MobileNetV2', +) + +mobilenet_multi_avg_spec = functools.partial( + ModelSpec, + downloaded_files=MOBILENET_MULTI_AVG_FILES, + checkpoint_name='ckpt-277200', + input_image_shape=[256, 256, 3], + model_id='MobileNetMultiAVG', ) @@ -53,6 +71,7 @@ class SupportedModels(enum.Enum): """Predefined object detector model specs supported by Model Maker.""" MOBILENET_V2 = mobilenet_v2_spec + MOBILENET_MULTI_AVG = mobilenet_multi_avg_spec @classmethod def get(cls, spec: 'SupportedModels') -> 'ModelSpec': From c6e3f0828248c50ff62fe51113b18bb1b7850698 Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Wed, 3 May 2023 16:36:45 -0700 Subject: [PATCH 184/753] Expose FaceAligner and LanguageDetector to be public MediaPipe Tasks Python API. PiperOrigin-RevId: 529227382 --- mediapipe/tasks/python/text/__init__.py | 5 +++++ mediapipe/tasks/python/vision/__init__.py | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/mediapipe/tasks/python/text/__init__.py b/mediapipe/tasks/python/text/__init__.py index 5aa221c33..66c62cafc 100644 --- a/mediapipe/tasks/python/text/__init__.py +++ b/mediapipe/tasks/python/text/__init__.py @@ -14,9 +14,13 @@ """MediaPipe Tasks Text API.""" +import mediapipe.tasks.python.text.language_detector import mediapipe.tasks.python.text.text_classifier import mediapipe.tasks.python.text.text_embedder +LanguageDetector = language_detector.LanguageDetector +LanguageDetectorOptions = language_detector.LanguageDetectorOptions +LanguageDetectorResult = language_detector.LanguageDetectorResult TextClassifier = text_classifier.TextClassifier TextClassifierOptions = text_classifier.TextClassifierOptions TextClassifierResult = text_classifier.TextClassifierResult @@ -26,5 +30,6 @@ TextEmbedderResult = text_embedder.TextEmbedderResult # Remove unnecessary modules to avoid duplication in API docs. del mediapipe +del language_detector del text_classifier del text_embedder diff --git a/mediapipe/tasks/python/vision/__init__.py b/mediapipe/tasks/python/vision/__init__.py index 3c3f34db0..c88dbb9ad 100644 --- a/mediapipe/tasks/python/vision/__init__.py +++ b/mediapipe/tasks/python/vision/__init__.py @@ -15,6 +15,7 @@ """MediaPipe Tasks Vision API.""" import mediapipe.tasks.python.vision.core +import mediapipe.tasks.python.vision.face_aligner import mediapipe.tasks.python.vision.face_detector import mediapipe.tasks.python.vision.face_landmarker import mediapipe.tasks.python.vision.face_stylizer @@ -27,6 +28,8 @@ import mediapipe.tasks.python.vision.interactive_segmenter import mediapipe.tasks.python.vision.object_detector import mediapipe.tasks.python.vision.pose_landmarker +FaceAligner = face_aligner.FaceAligner +FaceAlignerOptions = face_aligner.FaceAlignerOptions FaceDetector = face_detector.FaceDetector FaceDetectorOptions = face_detector.FaceDetectorOptions FaceDetectorResult = face_detector.FaceDetectorResult @@ -65,6 +68,7 @@ RunningMode = core.vision_task_running_mode.VisionTaskRunningMode # Remove unnecessary modules to avoid duplication in API docs. del core +del face_aligner del face_detector del face_landmarker del face_stylizer From 1323a5271c70e05b76833949faea67279a8bcb93 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 16:39:43 +0530 Subject: [PATCH 185/753] Added method to create unique dispatch queue names in MPPVisionTaskRunner --- .../common/utils/sources/NSString+Helpers.h | 1 + .../common/utils/sources/NSString+Helpers.mm | 4 ++++ mediapipe/tasks/ios/vision/core/BUILD | 1 + .../vision/core/sources/MPPVisionTaskRunner.h | 14 +++++++++++ .../core/sources/MPPVisionTaskRunner.mm | 23 ++++++++++++++----- 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h b/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h index 8433baaaf..1697a28e4 100644 --- a/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h +++ b/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h @@ -24,6 +24,7 @@ NS_ASSUME_NONNULL_BEGIN + (NSString *)stringWithCppString:(std::string)text; ++ (NSString *)uuidString; @end NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm b/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm index b7d486e80..dfc7749be 100644 --- a/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm +++ b/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm @@ -24,4 +24,8 @@ return [NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]; } ++ (NSString *)uuidString{ + return [[NSUUID UUID] UUIDString]; +} + @end diff --git a/mediapipe/tasks/ios/vision/core/BUILD b/mediapipe/tasks/ios/vision/core/BUILD index 4b72fc91d..328d9e892 100644 --- a/mediapipe/tasks/ios/vision/core/BUILD +++ b/mediapipe/tasks/ios/vision/core/BUILD @@ -58,6 +58,7 @@ objc_library( "//mediapipe/framework/formats:rect_cc_proto", "//mediapipe/tasks/ios/common:MPPCommon", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", + "//mediapipe/tasks/ios/common/utils:NSStringHelpers", "//mediapipe/tasks/ios/core:MPPTaskRunner", "//third_party/apple_frameworks:UIKit", "@com_google_absl//absl/status:statusor", diff --git a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h index 92b5563ef..318b24051 100644 --- a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h +++ b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h @@ -141,6 +141,20 @@ NS_ASSUME_NONNULL_BEGIN (mediapipe::tasks::core::PacketsCallback)packetsCallback error:(NSError **)error NS_UNAVAILABLE; +/** + * This method returns a unique dispatch queue name by adding the given suffix and a `UUID` to the + * pre-defined queue name prefix for vision tasks. The vision tasks can use this method to get + * unique dispatch queue names which are consistent with other vision tasks. + * Dispatch queue names need not be unique, but for easy debugging we ensure that the queue names + * are unique. + * + * @param suffix A suffix that identifies a dispatch queue's functionality. + * + * @return A unique dispatch queue name by adding the given suffix and a `UUID` to the pre-defined + * queue name prefix for vision tasks. + */ ++ (const char *)uniqueDispatchQueueNameWithSuffix:(NSString *)suffix; + - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; diff --git a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm index 40b68a211..0089e516f 100644 --- a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm +++ b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm @@ -16,6 +16,7 @@ #import "mediapipe/tasks/ios/common/sources/MPPCommon.h" #import "mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h" +#import "mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h" #include "absl/status/statusor.h" @@ -37,6 +38,8 @@ static const NSInteger kMPPOrientationDegreesDown = -180; /** Rotation degrees for a 90 degree rotation to the left. */ static const NSInteger kMPPOrientationDegreesLeft = -270; +static NSString *const kTaskPrefix = @"com.mediapipe.tasks.vision"; + @interface MPPVisionTaskRunner () { MPPRunningMode _runningMode; } @@ -54,18 +57,21 @@ static const NSInteger kMPPOrientationDegreesLeft = -270; if (packetsCallback) { [MPPCommonUtils createCustomError:error withCode:MPPTasksErrorCodeInvalidArgumentError - description:@"The vision task is in image or video mode, a " - @"user-defined result callback should not be provided."]; + description:@"The vision task is in image or video mode. The " + @"delegate must not be set in the task's options."]; return nil; } break; } case MPPRunningModeLiveStream: { if (!packetsCallback) { - [MPPCommonUtils createCustomError:error - withCode:MPPTasksErrorCodeInvalidArgumentError - description:@"The vision task is in live stream mode, a user-defined " - @"result callback must be provided."]; + [MPPCommonUtils + createCustomError:error + withCode:MPPTasksErrorCodeInvalidArgumentError + description: + @"The vision task is in live stream mode. An object must be set as the " + @"delegate of the task in its options to ensure asynchronous delivery of " + @"results."]; return nil; } break; @@ -197,4 +203,9 @@ static const NSInteger kMPPOrientationDegreesLeft = -270; return [self sendPacketMap:packetMap error:error]; } ++ (const char *)uniqueDispatchQueueNameWithSuffix:(NSString *)suffix { + return [NSString stringWithFormat:@"%@.%@_%@", kTaskPrefix, suffix, [NSString uuidString]] + .UTF8String; +} + @end From ab4b07646c994b62b9b3f341defffe9786cc6191 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 16:43:18 +0530 Subject: [PATCH 186/753] Updated MPPImageClassifier to use delegates instead of completion blocks for callback. --- .../MPPImageClassifierTests.m | 126 ++++++++++++------ .../sources/MPPImageClassifier.h | 16 ++- .../sources/MPPImageClassifier.mm | 63 +++++++-- .../sources/MPPImageClassifierOptions.h | 56 +++++++- .../sources/MPPImageClassifierOptions.m | 2 +- 5 files changed, 205 insertions(+), 58 deletions(-) diff --git a/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m b/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m index 58abb5c70..a2fd68482 100644 --- a/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m +++ b/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m @@ -27,6 +27,8 @@ static NSDictionary *const kMultiObjectsRotatedImage = @{@"name" : @"multi_objects_rotated", @"type" : @"jpg"}; static const int kMobileNetCategoriesCount = 1001; static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; +static NSString *const kLiveStreamTestsDictImageClassifierKey = @"image_classifier"; +static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; #define AssertEqualErrors(error, expectedError) \ XCTAssertNotNil(error); \ @@ -54,11 +56,14 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; XCTAssertEqual(imageClassifierResult.classificationResult.classifications.count, 1); \ XCTAssertEqual(imageClassifierResult.classificationResult.classifications[0].headIndex, 0); -@interface MPPImageClassifierTests : XCTestCase +@interface MPPImageClassifierTests : XCTestCase { + NSDictionary *liveStreamSucceedsTestDict; + NSDictionary *outOfOrderTimestampTestDict; +} + @end @implementation MPPImageClassifierTests - #pragma mark Results + (NSArray *)expectedResultCategoriesForClassifyBurgerImageWithFloatModel { @@ -436,43 +441,43 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; #pragma mark Running Mode Tests -- (void)testCreateImageClassifierFailsWithResultListenerInNonLiveStreamMode { +- (void)testCreateImageClassifierFailsWithDelegateInNonLiveStreamMode { MPPRunningMode runningModesToTest[] = {MPPRunningModeImage, MPPRunningModeVideo}; for (int i = 0; i < sizeof(runningModesToTest) / sizeof(runningModesToTest[0]); i++) { MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName]; options.runningMode = runningModesToTest[i]; - options.completion = ^(MPPImageClassifierResult *result, NSError *error) { - }; + options.imageClassifierLiveStreamDelegate = self; [self assertCreateImageClassifierWithOptions:options failsWithExpectedError: - [NSError - errorWithDomain:kExpectedErrorDomain - code:MPPTasksErrorCodeInvalidArgumentError - userInfo:@{ - NSLocalizedDescriptionKey : - @"The vision task is in image or video mode, a " - @"user-defined result callback should not be provided." - }]]; + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : + @"The vision task is in image or video mode. The " + @"delegate must not be set in the task's options." + }]]; } } -- (void)testCreateImageClassifierFailsWithMissingResultListenerInLiveStreamMode { +- (void)testCreateImageClassifierFailsWithMissingDelegateInLiveStreamMode { MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName]; options.runningMode = MPPRunningModeLiveStream; [self assertCreateImageClassifierWithOptions:options failsWithExpectedError: - [NSError errorWithDomain:kExpectedErrorDomain - code:MPPTasksErrorCodeInvalidArgumentError - userInfo:@{ - NSLocalizedDescriptionKey : - @"The vision task is in live stream mode, a " - @"user-defined result callback must be provided." - }]]; + [NSError + errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : + @"The vision task is in live stream mode. An object " + @"must be set as the delegate of the task in its " + @"options to ensure asynchronous delivery of results." + }]]; } - (void)testClassifyFailsWithCallingWrongApiInImageMode { @@ -553,9 +558,7 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; MPPImageClassifierOptions *options = [self imageClassifierOptionsWithModelName:kFloatModelName]; options.runningMode = MPPRunningModeLiveStream; - options.completion = ^(MPPImageClassifierResult *result, NSError *error) { - - }; + options.imageClassifierLiveStreamDelegate = self; MPPImageClassifier *imageClassifier = [self imageClassifierWithOptionsSucceeds:options]; @@ -619,16 +622,20 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; options.maxResults = maxResults; options.runningMode = MPPRunningModeLiveStream; - options.completion = ^(MPPImageClassifierResult *result, NSError *error) { - [self assertImageClassifierResult:result - hasExpectedCategoriesCount:maxResults - expectedCategories: - [MPPImageClassifierTests - expectedResultCategoriesForClassifyBurgerImageWithFloatModel]]; - }; + options.imageClassifierLiveStreamDelegate = self; + + XCTestExpectation *expectation = [[XCTestExpectation alloc] + initWithDescription:@"classifyWithOutOfOrderTimestampsAndLiveStream"]; + + expectation.expectedFulfillmentCount = 1; MPPImageClassifier *imageClassifier = [self imageClassifierWithOptionsSucceeds:options]; + outOfOrderTimestampTestDict = @{ + kLiveStreamTestsDictImageClassifierKey : imageClassifier, + kLiveStreamTestsDictExpectationKey : expectation + }; + MPPImage *image = [self imageWithFileInfo:kBurgerImage]; XCTAssertTrue([imageClassifier classifyAsyncImage:image timestampInMilliseconds:1 error:nil]); @@ -644,6 +651,8 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; @"INVALID_ARGUMENT: Input timestamp must be monotonically increasing." }]; AssertEqualErrors(error, expectedError); + + [self waitForExpectations:@[ expectation ] timeout:1e-2f]; } - (void)testClassifyWithLiveStreamModeSucceeds { @@ -653,24 +662,63 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; options.maxResults = maxResults; options.runningMode = MPPRunningModeLiveStream; - options.completion = ^(MPPImageClassifierResult *result, NSError *error) { - [self assertImageClassifierResult:result - hasExpectedCategoriesCount:maxResults - expectedCategories: - [MPPImageClassifierTests - expectedResultCategoriesForClassifyBurgerImageWithFloatModel]]; - }; + options.imageClassifierLiveStreamDelegate = self; + + NSInteger iterationCount = 100; + + // Because of flow limiting, we cannot ensure that the callback will be + // invoked `iterationCount` times. + // An normal expectation will fail if expectation.fullfill() is not called + // `expectation.expectedFulfillmentCount` times. + // If `expectation.isInverted = true`, the test will only succeed if + // expectation is not fullfilled for the specified `expectedFulfillmentCount`. + // Since in our case we cannot predict how many times the expectation is + // supposed to be fullfilled setting, + // `expectation.expectedFulfillmentCount` = `iterationCount` + 1 and + // `expectation.isInverted = true` ensures that test succeeds if + // expectation is fullfilled <= `iterationCount` times. + XCTestExpectation *expectation = + [[XCTestExpectation alloc] initWithDescription:@"classifyWithLiveStream"]; + + expectation.expectedFulfillmentCount = iterationCount + 1; + expectation.inverted = YES; MPPImageClassifier *imageClassifier = [self imageClassifierWithOptionsSucceeds:options]; + liveStreamSucceedsTestDict = @{ + kLiveStreamTestsDictImageClassifierKey : imageClassifier, + kLiveStreamTestsDictExpectationKey : expectation + }; + // TODO: Mimic initialization from CMSampleBuffer as live stream mode is most likely to be used // with the iOS camera. AVCaptureVideoDataOutput sample buffer delegates provide frames of type // `CMSampleBuffer`. MPPImage *image = [self imageWithFileInfo:kBurgerImage]; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < iterationCount; i++) { XCTAssertTrue([imageClassifier classifyAsyncImage:image timestampInMilliseconds:i error:nil]); } + + [self waitForExpectations:@[ expectation ] timeout:1e-2f]; +} + +- (void)imageClassifier:(MPPImageClassifier *)imageClassifier + didFinishClassificationWithResult:(MPPImageClassifierResult *)imageClassifierResult + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(NSError *)error { + NSInteger maxResults = 3; + [self assertImageClassifierResult:imageClassifierResult + hasExpectedCategoriesCount:maxResults + expectedCategories: + [MPPImageClassifierTests + expectedResultCategoriesForClassifyBurgerImageWithFloatModel]]; + + if (imageClassifier == outOfOrderTimestampTestDict[kLiveStreamTestsDictImageClassifierKey]) { + [outOfOrderTimestampTestDict[kLiveStreamTestsDictExpectationKey] fulfill]; + } else if (imageClassifier == + liveStreamSucceedsTestDict[kLiveStreamTestsDictImageClassifierKey]) { + [liveStreamSucceedsTestDict[kLiveStreamTestsDictExpectationKey] fulfill]; + } } @end diff --git a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.h b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.h index 345687877..024eee0aa 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.h +++ b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.h @@ -164,8 +164,11 @@ NS_SWIFT_NAME(ImageClassifier) * Sends live stream image data of type `MPPImage` to perform image classification using the whole * image as region of interest. Rotation will be applied according to the `orientation` property of * the provided `MPPImage`. Only use this method when the `MPPImageClassifier` is created with - * `MPPRunningModeLiveStream`. Results are provided asynchronously via the `completion` callback - * provided in the `MPPImageClassifierOptions`. + * `MPPRunningModeLiveStream`. + * The object which needs to be continuously notified of the available results of image + * classification must confirm to `MPPImageClassifierLiveStreamDelegate` protocol and implement the + * `imageClassifier:didFinishClassificationWithResult:timestampInMilliseconds:error:` + * delegate method. * * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent * to the image classifier. The input timestamps must be monotonically increasing. @@ -185,11 +188,14 @@ NS_SWIFT_NAME(ImageClassifier) NS_SWIFT_NAME(classifyAsync(image:timestampInMilliseconds:)); /** - * Sends live stream image data of type `MPPImage` to perform image classification, cropped to the + * Sends live stream image data of type ``MPPImage`` to perform image classification, cropped to the * specified region of interest.. Rotation will be applied according to the `orientation` property * of the provided `MPPImage`. Only use this method when the `MPPImageClassifier` is created with - * `MPPRunningModeLiveStream`. Results are provided asynchronously via the `completion` callback - * provided in the `MPPImageClassifierOptions`. + * `MPPRunningModeLiveStream`. + * The object which needs to be continuously notified of the available results of image + * classification must confirm to `MPPImageClassifierLiveStreamDelegate` protocol and implement the + * `imageClassifier:didFinishClassificationWithResult:timestampInMilliseconds:error:` delegate + * method. * * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent * to the image classifier. The input timestamps must be monotonically increasing. diff --git a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.mm b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.mm index 3e345a5d0..408153c01 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.mm +++ b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.mm @@ -27,6 +27,7 @@ namespace { using ::mediapipe::NormalizedRect; using ::mediapipe::Packet; +using ::mediapipe::Timestamp; using ::mediapipe::tasks::core::PacketMap; using ::mediapipe::tasks::core::PacketsCallback; } // namespace @@ -38,9 +39,9 @@ static NSString *const kImageOutStreamName = @"image_out"; static NSString *const kImageTag = @"IMAGE"; static NSString *const kNormRectStreamName = @"norm_rect_in"; static NSString *const kNormRectTag = @"NORM_RECT"; - static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.image_classifier.ImageClassifierGraph"; +static NSString *const kTaskName = @"imageClassifier"; #define InputPacketMap(imagePacket, normalizedRectPacket) \ { \ @@ -53,6 +54,8 @@ static NSString *const kTaskGraphName = /** iOS Vision Task Runner */ MPPVisionTaskRunner *_visionTaskRunner; } +@property(nonatomic, weak) id + imageClassifierLiveStreamDelegate; @end @implementation MPPImageClassifier @@ -81,16 +84,58 @@ static NSString *const kTaskGraphName = PacketsCallback packetsCallback = nullptr; - if (options.completion) { + if (options.imageClassifierLiveStreamDelegate) { + _imageClassifierLiveStreamDelegate = options.imageClassifierLiveStreamDelegate; + // Capturing `self` as weak in order to avoid `self` being kept in memory + // and cause a retain cycle, after self is set to `nil`. + MPPImageClassifier *__weak weakSelf = self; + + // Create a private serial dispatch queue in which the deleagte method will be called + // asynchronously. This is to ensure that if the client performs a long running operation in + // the delegate method, the queue on which the C++ callbacks is invoked is not blocked and is + // freed up to continue with its operations. + const char *queueName = [MPPVisionTaskRunner uniqueDispatchQueueNameWithSuffix:kTaskName]; + dispatch_queue_t callbackQueue = dispatch_queue_create(queueName, NULL); packetsCallback = [=](absl::StatusOr status_or_packets) { - NSError *callbackError = nil; - MPPImageClassifierResult *result; - if ([MPPCommonUtils checkCppError:status_or_packets.status() toError:&callbackError]) { - result = [MPPImageClassifierResult - imageClassifierResultWithClassificationsPacket: - status_or_packets.value()[kClassificationsStreamName.cppString]]; + if (!weakSelf) { + return; } - options.completion(result, callbackError); + if (![weakSelf.imageClassifierLiveStreamDelegate + respondsToSelector:@selector + (imageClassifier: + didFinishClassificationWithResult:timestampInMilliseconds:error:)]) { + return; + } + + NSError *callbackError = nil; + if (![MPPCommonUtils checkCppError:status_or_packets.status() toError:&callbackError]) { + dispatch_async(callbackQueue, ^{ + [weakSelf.imageClassifierLiveStreamDelegate imageClassifier:weakSelf + didFinishClassificationWithResult:nil + timestampInMilliseconds:Timestamp::Unset().Value() + error:callbackError]; + }); + return; + } + + PacketMap &outputPacketMap = status_or_packets.value(); + if (outputPacketMap[kImageOutStreamName.cppString].IsEmpty()) { + return; + } + + MPPImageClassifierResult *result = + [MPPImageClassifierResult imageClassifierResultWithClassificationsPacket: + outputPacketMap[kClassificationsStreamName.cppString]]; + + NSInteger timeStampInMilliseconds = + outputPacketMap[kImageOutStreamName.cppString].Timestamp().Value() / + kMicroSecondsPerMilliSecond; + dispatch_async(callbackQueue, ^{ + [weakSelf.imageClassifierLiveStreamDelegate imageClassifier:weakSelf + didFinishClassificationWithResult:result + timestampInMilliseconds:timeStampInMilliseconds + error:callbackError]; + }); }; } diff --git a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifierOptions.h b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifierOptions.h index 2e6022041..fc76560c2 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifierOptions.h +++ b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifierOptions.h @@ -20,20 +20,68 @@ NS_ASSUME_NONNULL_BEGIN +@class MPPImageClassifier; + +/** + * This protocol defines an interface for the delegates of `MPPImageClassifier` object to receive + * results of asynchronous classification of images + * (i.e, when `runningMode = MPPRunningModeLiveStream`). + * + * The delegate of `MPPImageClassifier` must adopt `MPPImageClassifierLiveStreamDelegate` protocol. + * The methods in this protocol are optional. + */ +NS_SWIFT_NAME(ImageClassifierLiveStreamDelegate) +@protocol MPPImageClassifierLiveStreamDelegate + +@optional +/** + * This method notifies a delegate that the results of asynchronous classification of + * an image submitted to the `MPPImageClassifier` is available. + * + * This method is called on a private serial queue created by the `MPPImageClassifier` + * for performing the asynchronous delegates calls. + * + * @param imageClassifier The image classifier which performed the classification. + * This is useful to test equality when there are multiple instances of `MPPImageClassifier`. + * @param result An `MPPImageClassifierResult` object that contains a list of image classifications. + * @param timestampInMilliseconds The timestamp (in milliseconds) which indicates when the input + * image was sent to the image classifier. + * @param error An optional error parameter populated when there is an error in performing image + * classification on the input live stream image data. + * + */ +- (void)imageClassifier:(MPPImageClassifier *)imageClassifier + didFinishClassificationWithResult:(nullable MPPImageClassifierResult *)result + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(nullable NSError *)error + NS_SWIFT_NAME(imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:)); +@end + /** * Options for setting up a `MPPImageClassifier`. */ NS_SWIFT_NAME(ImageClassifierOptions) @interface MPPImageClassifierOptions : MPPTaskOptions +/** + * Running mode of the image classifier task. Defaults to `MPPRunningModeImage`. + * `MPPImageClassifier` can be created with one of the following running modes: + * 1. `MPPRunningModeImage`: The mode for performing classification on single image inputs. + * 2. `MPPRunningModeVideo`: The mode for performing classification on the decoded frames of a + * video. + * 3. `MPPRunningModeLiveStream`: The mode for performing classification on a live stream of input + * data, such as from the camera. + */ @property(nonatomic) MPPRunningMode runningMode; /** - * The user-defined result callback for processing live stream data. The result callback should only - * be specified when the running mode is set to the live stream mode. - * TODO: Add parameter `MPPImage` in the callback. + * An object that confirms to `MPPImageClassifierLiveStreamDelegate` protocol. This object must + * implement `objectDetector:didFinishDetectionWithResult:timestampInMilliseconds:error:` to receive + * the results of asynchronous classification on images (i.e, when `runningMode = + * MPPRunningModeLiveStream`). */ -@property(nonatomic, copy) void (^completion)(MPPImageClassifierResult *result, NSError *error); +@property(nonatomic, weak, nullable) id + imageClassifierLiveStreamDelegate; /** * The locale to use for display names specified through the TFLite Model Metadata, if any. Defaults diff --git a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifierOptions.m b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifierOptions.m index e109dcc3b..8d3815ff3 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifierOptions.m +++ b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifierOptions.m @@ -33,7 +33,7 @@ imageClassifierOptions.categoryDenylist = self.categoryDenylist; imageClassifierOptions.categoryAllowlist = self.categoryAllowlist; imageClassifierOptions.displayNamesLocale = self.displayNamesLocale; - imageClassifierOptions.completion = self.completion; + imageClassifierOptions.imageClassifierLiveStreamDelegate = self.imageClassifierLiveStreamDelegate; return imageClassifierOptions; } From e47bb165442a61a93af2d83d0c081bc00c6b215a Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 16:52:58 +0530 Subject: [PATCH 187/753] Added validation of C++ image classification result packet in MPPImageClassifierResult+Helpers.mm --- .../sources/MPPImageClassifierResult+Helpers.h | 4 +++- .../sources/MPPImageClassifierResult+Helpers.mm | 13 +++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/mediapipe/tasks/ios/vision/image_classifier/utils/sources/MPPImageClassifierResult+Helpers.h b/mediapipe/tasks/ios/vision/image_classifier/utils/sources/MPPImageClassifierResult+Helpers.h index 0375ac2a5..68d939f45 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/utils/sources/MPPImageClassifierResult+Helpers.h +++ b/mediapipe/tasks/ios/vision/image_classifier/utils/sources/MPPImageClassifierResult+Helpers.h @@ -18,6 +18,8 @@ NS_ASSUME_NONNULL_BEGIN +static const int kMicroSecondsPerMilliSecond = 1000; + @interface MPPImageClassifierResult (Helpers) /** @@ -28,7 +30,7 @@ NS_ASSUME_NONNULL_BEGIN * * @return An `MPPImageClassifierResult` object that contains a list of image classifications. */ -+ (MPPImageClassifierResult *)imageClassifierResultWithClassificationsPacket: ++ (nullable MPPImageClassifierResult *)imageClassifierResultWithClassificationsPacket: (const mediapipe::Packet &)packet; @end diff --git a/mediapipe/tasks/ios/vision/image_classifier/utils/sources/MPPImageClassifierResult+Helpers.mm b/mediapipe/tasks/ios/vision/image_classifier/utils/sources/MPPImageClassifierResult+Helpers.mm index f5199765d..f43ad0d7a 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/utils/sources/MPPImageClassifierResult+Helpers.mm +++ b/mediapipe/tasks/ios/vision/image_classifier/utils/sources/MPPImageClassifierResult+Helpers.mm @@ -17,8 +17,6 @@ #include "mediapipe/tasks/cc/components/containers/proto/classifications.pb.h" -static const int kMicroSecondsPerMilliSecond = 1000; - namespace { using ClassificationResultProto = ::mediapipe::tasks::components::containers::proto::ClassificationResult; @@ -27,9 +25,16 @@ using ::mediapipe::Packet; @implementation MPPImageClassifierResult (Helpers) -+ (MPPImageClassifierResult *)imageClassifierResultWithClassificationsPacket: ++ (nullable MPPImageClassifierResult *)imageClassifierResultWithClassificationsPacket: (const Packet &)packet { - MPPClassificationResult *classificationResult = [MPPClassificationResult + MPPClassificationResult *classificationResult; + MPPImageClassifierResult *imageClassifierResult; + + if (!packet.ValidateAsType().ok()) { + return nil; + } + + classificationResult = [MPPClassificationResult classificationResultWithProto:packet.Get()]; return [[MPPImageClassifierResult alloc] From a21c08bf4d5a2e75c6f70579987a18102d78241a Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 17:00:12 +0530 Subject: [PATCH 188/753] Added method for creating unique dispatch queue names in MPPVisionTaskRunner --- .../common/utils/sources/NSString+Helpers.h | 1 + .../common/utils/sources/NSString+Helpers.mm | 4 ++++ mediapipe/tasks/ios/vision/core/BUILD | 1 + .../vision/core/sources/MPPVisionTaskRunner.h | 14 +++++++++++ .../core/sources/MPPVisionTaskRunner.mm | 23 ++++++++++++++----- 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h b/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h index 8433baaaf..1697a28e4 100644 --- a/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h +++ b/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h @@ -24,6 +24,7 @@ NS_ASSUME_NONNULL_BEGIN + (NSString *)stringWithCppString:(std::string)text; ++ (NSString *)uuidString; @end NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm b/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm index b7d486e80..dfc7749be 100644 --- a/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm +++ b/mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.mm @@ -24,4 +24,8 @@ return [NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]; } ++ (NSString *)uuidString{ + return [[NSUUID UUID] UUIDString]; +} + @end diff --git a/mediapipe/tasks/ios/vision/core/BUILD b/mediapipe/tasks/ios/vision/core/BUILD index 4b72fc91d..328d9e892 100644 --- a/mediapipe/tasks/ios/vision/core/BUILD +++ b/mediapipe/tasks/ios/vision/core/BUILD @@ -58,6 +58,7 @@ objc_library( "//mediapipe/framework/formats:rect_cc_proto", "//mediapipe/tasks/ios/common:MPPCommon", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", + "//mediapipe/tasks/ios/common/utils:NSStringHelpers", "//mediapipe/tasks/ios/core:MPPTaskRunner", "//third_party/apple_frameworks:UIKit", "@com_google_absl//absl/status:statusor", diff --git a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h index 92b5563ef..318b24051 100644 --- a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h +++ b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h @@ -141,6 +141,20 @@ NS_ASSUME_NONNULL_BEGIN (mediapipe::tasks::core::PacketsCallback)packetsCallback error:(NSError **)error NS_UNAVAILABLE; +/** + * This method returns a unique dispatch queue name by adding the given suffix and a `UUID` to the + * pre-defined queue name prefix for vision tasks. The vision tasks can use this method to get + * unique dispatch queue names which are consistent with other vision tasks. + * Dispatch queue names need not be unique, but for easy debugging we ensure that the queue names + * are unique. + * + * @param suffix A suffix that identifies a dispatch queue's functionality. + * + * @return A unique dispatch queue name by adding the given suffix and a `UUID` to the pre-defined + * queue name prefix for vision tasks. + */ ++ (const char *)uniqueDispatchQueueNameWithSuffix:(NSString *)suffix; + - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; diff --git a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm index 40b68a211..0089e516f 100644 --- a/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm +++ b/mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.mm @@ -16,6 +16,7 @@ #import "mediapipe/tasks/ios/common/sources/MPPCommon.h" #import "mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h" +#import "mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h" #include "absl/status/statusor.h" @@ -37,6 +38,8 @@ static const NSInteger kMPPOrientationDegreesDown = -180; /** Rotation degrees for a 90 degree rotation to the left. */ static const NSInteger kMPPOrientationDegreesLeft = -270; +static NSString *const kTaskPrefix = @"com.mediapipe.tasks.vision"; + @interface MPPVisionTaskRunner () { MPPRunningMode _runningMode; } @@ -54,18 +57,21 @@ static const NSInteger kMPPOrientationDegreesLeft = -270; if (packetsCallback) { [MPPCommonUtils createCustomError:error withCode:MPPTasksErrorCodeInvalidArgumentError - description:@"The vision task is in image or video mode, a " - @"user-defined result callback should not be provided."]; + description:@"The vision task is in image or video mode. The " + @"delegate must not be set in the task's options."]; return nil; } break; } case MPPRunningModeLiveStream: { if (!packetsCallback) { - [MPPCommonUtils createCustomError:error - withCode:MPPTasksErrorCodeInvalidArgumentError - description:@"The vision task is in live stream mode, a user-defined " - @"result callback must be provided."]; + [MPPCommonUtils + createCustomError:error + withCode:MPPTasksErrorCodeInvalidArgumentError + description: + @"The vision task is in live stream mode. An object must be set as the " + @"delegate of the task in its options to ensure asynchronous delivery of " + @"results."]; return nil; } break; @@ -197,4 +203,9 @@ static const NSInteger kMPPOrientationDegreesLeft = -270; return [self sendPacketMap:packetMap error:error]; } ++ (const char *)uniqueDispatchQueueNameWithSuffix:(NSString *)suffix { + return [NSString stringWithFormat:@"%@.%@_%@", kTaskPrefix, suffix, [NSString uuidString]] + .UTF8String; +} + @end From ab135190e586b0928ff8fa9d2ca101da20e2cdb1 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 17:03:40 +0530 Subject: [PATCH 189/753] Updated iOS object detector to use delegates instead of callbacks for async calls --- .../object_detector/MPPObjectDetectorTests.m | 94 +++++++++++-------- .../sources/MPPObjectDetector.h | 3 + .../sources/MPPObjectDetector.mm | 43 +++++++-- .../sources/MPPObjectDetectorOptions.h | 61 +++++++++++- .../sources/MPPObjectDetectorOptions.m | 2 +- 5 files changed, 148 insertions(+), 55 deletions(-) diff --git a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m index fd9466b7d..9ccfece91 100644 --- a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m +++ b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m @@ -25,6 +25,8 @@ static NSDictionary *const kCatsAndDogsRotatedImage = static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; static const float pixelDifferenceTolerance = 10.0f; static const float scoreDifferenceTolerance = 0.02f; +static NSString *const kLiveStreamTestsDictObjectDetectorKey = @"object_detector"; +static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; #define AssertEqualErrors(error, expectedError) \ XCTAssertNotNil(error); \ @@ -58,7 +60,10 @@ static const float scoreDifferenceTolerance = 0.02f; XCTAssertEqualWithAccuracy(boundingBox.size.height, expectedBoundingBox.size.height, \ pixelDifferenceTolerance, @"index i = %d", idx); -@interface MPPObjectDetectorTests : XCTestCase +@interface MPPObjectDetectorTests : XCTestCase { + NSDictionary *liveStreamSucceedsTestDict; + NSDictionary *outOfOrderTimestampTestDict; +} @end @implementation MPPObjectDetectorTests @@ -446,31 +451,28 @@ static const float scoreDifferenceTolerance = 0.02f; #pragma mark Running Mode Tests -- (void)testCreateObjectDetectorFailsWithResultListenerInNonLiveStreamMode { +- (void)testCreateObjectDetectorFailsWithDelegateInNonLiveStreamMode { MPPRunningMode runningModesToTest[] = {MPPRunningModeImage, MPPRunningModeVideo}; for (int i = 0; i < sizeof(runningModesToTest) / sizeof(runningModesToTest[0]); i++) { MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; options.runningMode = runningModesToTest[i]; - options.completion = - ^(MPPObjectDetectionResult *result, NSInteger timestampInMilliseconds, NSError *error) { - }; + options.objectDetectorLiveStreamDelegate = self; [self assertCreateObjectDetectorWithOptions:options failsWithExpectedError: - [NSError - errorWithDomain:kExpectedErrorDomain - code:MPPTasksErrorCodeInvalidArgumentError - userInfo:@{ - NSLocalizedDescriptionKey : - @"The vision task is in image or video mode, a " - @"user-defined result callback should not be provided." - }]]; + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : + @"The vision task is in image or video mode. The " + @"delegate must not be set in the task's options." + }]]; } } -- (void)testCreateObjectDetectorFailsWithMissingResultListenerInLiveStreamMode { +- (void)testCreateObjectDetectorFailsWithMissingDelegateInLiveStreamMode { MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; options.runningMode = MPPRunningModeLiveStream; @@ -481,8 +483,11 @@ static const float scoreDifferenceTolerance = 0.02f; code:MPPTasksErrorCodeInvalidArgumentError userInfo:@{ NSLocalizedDescriptionKey : - @"The vision task is in live stream mode, a " - @"user-defined result callback must be provided." + @"The vision task is in live stream mode. An " + @"object must be set as the " + @"delegate of the task in its options to ensure " + @"asynchronous delivery of " + @"results." }]]; } @@ -563,10 +568,7 @@ static const float scoreDifferenceTolerance = 0.02f; MPPObjectDetectorOptions *options = [self objectDetectorOptionsWithModelName:kModelName]; options.runningMode = MPPRunningModeLiveStream; - options.completion = - ^(MPPObjectDetectionResult *result, NSInteger timestampInMilliseconds, NSError *error) { - - }; + options.objectDetectorLiveStreamDelegate = self; MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; @@ -631,23 +633,17 @@ static const float scoreDifferenceTolerance = 0.02f; options.maxResults = maxResults; options.runningMode = MPPRunningModeLiveStream; + options.objectDetectorLiveStreamDelegate = self; XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:@"detectWithOutOfOrderTimestampsAndLiveStream"]; expectation.expectedFulfillmentCount = 1; - options.completion = - ^(MPPObjectDetectionResult *result, NSInteger timestampInMilliseconds, NSError *error) { - [self assertObjectDetectionResult:result - isEqualToExpectedResult: - [MPPObjectDetectorTests - expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: - timestampInMilliseconds] - expectedDetectionsCount:maxResults]; - [expectation fulfill]; - }; - MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + liveStreamSucceedsTestDict = @{ + kLiveStreamTestsDictObjectDetectorKey : objectDetector, + kLiveStreamTestsDictExpectationKey : expectation + }; MPPImage *image = [self imageWithFileInfo:kCatsAndDogsImage]; @@ -693,19 +689,15 @@ static const float scoreDifferenceTolerance = 0.02f; expectation.expectedFulfillmentCount = iterationCount + 1; expectation.inverted = YES; - options.completion = - ^(MPPObjectDetectionResult *result, NSInteger timestampInMilliseconds, NSError *error) { - [self assertObjectDetectionResult:result - isEqualToExpectedResult: - [MPPObjectDetectorTests - expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: - timestampInMilliseconds] - expectedDetectionsCount:maxResults]; - [expectation fulfill]; - }; + options.objectDetectorLiveStreamDelegate = self; MPPObjectDetector *objectDetector = [self objectDetectorWithOptionsSucceeds:options]; + liveStreamSucceedsTestDict = @{ + kLiveStreamTestsDictObjectDetectorKey : objectDetector, + kLiveStreamTestsDictExpectationKey : expectation + }; + // TODO: Mimic initialization from CMSampleBuffer as live stream mode is most likely to be used // with the iOS camera. AVCaptureVideoDataOutput sample buffer delegates provide frames of type // `CMSampleBuffer`. @@ -718,4 +710,24 @@ static const float scoreDifferenceTolerance = 0.02f; [self waitForExpectations:@[ expectation ] timeout:0.5]; } +#pragma mark MPPObjectDetectorLiveStreamDelegate Methods +- (void)objectDetector:(MPPObjectDetector *)objectDetector + didFinishDetectionWithResult:(MPPObjectDetectionResult *)objectDetectionResult + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(NSError *)error { + NSInteger maxResults = 4; + [self assertObjectDetectionResult:objectDetectionResult + isEqualToExpectedResult: + [MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: + timestampInMilliseconds] + expectedDetectionsCount:maxResults]; + + if (objectDetector == outOfOrderTimestampTestDict[kLiveStreamTestsDictObjectDetectorKey]) { + [outOfOrderTimestampTestDict[kLiveStreamTestsDictExpectationKey] fulfill]; + } else if (objectDetector == liveStreamSucceedsTestDict[kLiveStreamTestsDictObjectDetectorKey]) { + [liveStreamSucceedsTestDict[kLiveStreamTestsDictExpectationKey] fulfill]; + } +} + @end diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h index 4443f56d1..249ee0434 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h @@ -137,6 +137,9 @@ NS_SWIFT_NAME(ObjectDetector) * the provided `MPPImage`. Only use this method when the `MPPObjectDetector` is created with * `MPPRunningModeLiveStream`. Results are provided asynchronously via the `completion` callback * provided in the `MPPObjectDetectorOptions`. + * The object which needs to be continuously notified of the available results of object + * detection must confirm to `MPPObjectDetectorLiveStreamDelegate` protocol and implement the + * `objectDetector:didFinishDetectionWithResult:timestampInMilliseconds:error:` delegate method. * * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent * to the object detector. The input timestamps must be monotonically increasing. diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm index f0914cdb1..5dfbfdab8 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm @@ -37,8 +37,8 @@ static NSString *const kImageOutStreamName = @"image_out"; static NSString *const kImageTag = @"IMAGE"; static NSString *const kNormRectStreamName = @"norm_rect_in"; static NSString *const kNormRectTag = @"NORM_RECT"; - static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorGraph"; +static NSString *const kTaskName = @"objectDetector"; #define InputPacketMap(imagePacket, normalizedRectPacket) \ { \ @@ -51,6 +51,7 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG /** iOS Vision Task Runner */ MPPVisionTaskRunner *_visionTaskRunner; } +@property(nonatomic, weak) id objectDetectorLiveStreamDelegate; @end @implementation MPPObjectDetector @@ -78,11 +79,32 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG PacketsCallback packetsCallback = nullptr; - if (options.completion) { + if (options.objectDetectorLiveStreamDelegate) { + _objectDetectorLiveStreamDelegate = options.objectDetectorLiveStreamDelegate; + + // Capturing `self` as weak in order to avoid `self` being kept in memory + // and cause a retain cycle, after self is set to `nil`. + MPPObjectDetector *__weak weakSelf = self; + dispatch_queue_t callbackQueue = + dispatch_queue_create([MPPVisionTaskRunner uniqueDispatchQueueNameWithSuffix:kTaskName], NULL); packetsCallback = [=](absl::StatusOr statusOrPackets) { + if (!weakSelf) { + return; + } + if (![weakSelf.objectDetectorLiveStreamDelegate + respondsToSelector:@selector + (objectDetector:didFinishDetectionWithResult:timestampInMilliseconds:error:)]) { + return; + } + NSError *callbackError = nil; if (![MPPCommonUtils checkCppError:statusOrPackets.status() toError:&callbackError]) { - options.completion(nil, Timestamp::Unset().Value(), callbackError); + dispatch_async(callbackQueue, ^{ + [weakSelf.objectDetectorLiveStreamDelegate objectDetector:weakSelf + didFinishDetectionWithResult:nil + timestampInMilliseconds:Timestamp::Unset().Value() + error:callbackError]; + }); return; } @@ -95,10 +117,15 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG objectDetectionResultWithDetectionsPacket:statusOrPackets.value()[kDetectionsStreamName .cppString]]; - options.completion(result, - outputPacketMap[kImageOutStreamName.cppString].Timestamp().Value() / - kMicroSecondsPerMilliSecond, - callbackError); + NSInteger timeStampInMilliseconds = + outputPacketMap[kImageOutStreamName.cppString].Timestamp().Value() / + kMicroSecondsPerMilliSecond; + dispatch_async(callbackQueue, ^{ + [weakSelf.objectDetectorLiveStreamDelegate objectDetector:weakSelf + didFinishDetectionWithResult:result + timestampInMilliseconds:timeStampInMilliseconds + error:callbackError]; + }); }; } @@ -112,6 +139,7 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG return nil; } } + return self; } @@ -224,5 +252,4 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG return [_visionTaskRunner processLiveStreamPacketMap:inputPacketMap.value() error:error]; } - @end diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h index 79bc9baa6..c60c8acac 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h @@ -20,19 +20,70 @@ NS_ASSUME_NONNULL_BEGIN +@class MPPObjectDetector; + +/** + * This protocol defines an interface for the delegates of `MPPObjectDetector` object to receive + * results of performing asynchronous object detection on images + * (i.e, when `runningMode` = `MPPRunningModeLiveStream`). + * + * The delegate of `MPPObjectDetector` must adopt `MPPObjectDetectorLiveStreamDelegate` protocol. + * The methods in this protocol are optional. + */ +NS_SWIFT_NAME(ObjectDetectorLiveStreamDelegate) +@protocol MPPObjectDetectorLiveStreamDelegate + +@optional + +/** + * This method notifies a delegate that the results of asynchronous object detection of + * an image submitted to the `MPPObjectDetector` is available. + * + * This method is called on a private serial dispatch queue created by the `MPPObjectDetector` + * for performing the asynchronous delegates calls. + * + * @param objectDetector The object detector which performed the object detection. + * This is useful to test equality when there are multiple instances of `MPPObjectDetector`. + * @param result The `MPPObjectDetectionResult` object that contains a list of detections, each + * detection has a bounding box that is expressed in the unrotated input frame of reference + * coordinates system, i.e. in `[0,image_width) x [0,image_height)`, which are the dimensions of the + * underlying image data. + * @param timestampInMilliseconds The timestamp (in milliseconds) which indicates when the input + * image was sent to the object detector. + * @param error An optional error parameter populated when there is an error in performing object + * detection on the input live stream image data. + * + */ +- (void)objectDetector:(MPPObjectDetector *)objectDetector + didFinishDetectionWithResult:(nullable MPPObjectDetectionResult *)result + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(nullable NSError *)error + NS_SWIFT_NAME(objectDetector(_:didFinishDetection:timestampInMilliseconds:error:)); +@end + /** Options for setting up a `MPPObjectDetector`. */ NS_SWIFT_NAME(ObjectDetectorOptions) @interface MPPObjectDetectorOptions : MPPTaskOptions +/** + * Running mode of the object detector task. Defaults to `MPPRunningModeImage`. + * `MPPImageClassifier` can be created with one of the following running modes: + * 1. `MPPRunningModeImage`: The mode for performing object detection on single image inputs. + * 2. `MPPRunningModeVideo`: The mode for performing object detection on the decoded frames of a + * video. + * 3. `MPPRunningModeLiveStream`: The mode for performing object detection on a live stream of + * input data, such as from the camera. + */ @property(nonatomic) MPPRunningMode runningMode; /** - * The user-defined result callback for processing live stream data. The result callback should only - * be specified when the running mode is set to the live stream mode. - * TODO: Add parameter `MPPImage` in the callback. + * An object that confirms to `MPPObjectDetectorLiveStreamDelegate` protocol. This object must + * implement `objectDetector:didFinishDetectionWithResult:timestampInMilliseconds:error:` to receive + * the results of performing asynchronous object detection on images (i.e, when `runningMode` = + * `MPPRunningModeLiveStream`). */ -@property(nonatomic, copy) void (^completion) - (MPPObjectDetectionResult *__nullable result, NSInteger timestampMs, NSError *error); +@property(nonatomic, weak, nullable) id + objectDetectorLiveStreamDelegate; /** * The locale to use for display names specified through the TFLite Model Metadata, if any. Defaults diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.m b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.m index 73f8ce5b5..b93a6b30b 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.m +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.m @@ -33,7 +33,7 @@ objectDetectorOptions.categoryDenylist = self.categoryDenylist; objectDetectorOptions.categoryAllowlist = self.categoryAllowlist; objectDetectorOptions.displayNamesLocale = self.displayNamesLocale; - objectDetectorOptions.completion = self.completion; + objectDetectorOptions.objectDetectorLiveStreamDelegate = self.objectDetectorLiveStreamDelegate; return objectDetectorOptions; } From 87593a2aded4b8907db4d551e77840d88e179a60 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 17:05:17 +0530 Subject: [PATCH 190/753] Updated docuemntation of MPPObjectDetector --- .../ios/vision/object_detector/sources/MPPObjectDetector.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h index 249ee0434..4ac8cc773 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h @@ -135,8 +135,7 @@ NS_SWIFT_NAME(ObjectDetector) * Sends live stream image data of type `MPPImage` to perform object detection using the whole * image as region of interest. Rotation will be applied according to the `orientation` property of * the provided `MPPImage`. Only use this method when the `MPPObjectDetector` is created with - * `MPPRunningModeLiveStream`. Results are provided asynchronously via the `completion` callback - * provided in the `MPPObjectDetectorOptions`. + * `MPPRunningModeLiveStream`. * The object which needs to be continuously notified of the available results of object * detection must confirm to `MPPObjectDetectorLiveStreamDelegate` protocol and implement the * `objectDetector:didFinishDetectionWithResult:timestampInMilliseconds:error:` delegate method. From 381ffcb474c6df8cb7f17f0beced787727a7cd1c Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 17:10:07 +0530 Subject: [PATCH 191/753] Added hash implementation for iOS normalized keypoint --- .../tasks/ios/components/containers/sources/MPPDetection.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mediapipe/tasks/ios/components/containers/sources/MPPDetection.m b/mediapipe/tasks/ios/components/containers/sources/MPPDetection.m index c245478db..c61cf0b39 100644 --- a/mediapipe/tasks/ios/components/containers/sources/MPPDetection.m +++ b/mediapipe/tasks/ios/components/containers/sources/MPPDetection.m @@ -28,7 +28,12 @@ return self; } -// TODO: Implement hash +- (NSUInteger)hash { + NSUInteger nonNullPropertiesHash = + @(self.location.x).hash ^ @(self.location.y).hash ^ @(self.score).hash; + + return self.label ? nonNullPropertiesHash ^ self.label.hash : nonNullPropertiesHash; +} - (BOOL)isEqual:(nullable id)object { if (!object) { From 1136d4d5156b02749819c691c740fe0010488d3e Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 18:58:49 +0530 Subject: [PATCH 192/753] Updated CVPixelBuffer to support pixel format type of 32RGBA --- mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm b/mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm index 75dfcc650..5258b540f 100644 --- a/mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm +++ b/mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm @@ -162,6 +162,7 @@ using ::mediapipe::ImageFrame; OSType pixelBufferFormat = CVPixelBufferGetPixelFormatType(pixelBuffer); switch (pixelBufferFormat) { + case kCVPixelFormatType_32RGBA: case kCVPixelFormatType_32BGRA: { return [MPPCVPixelBufferUtils rgbImageFrameFromCVPixelBuffer:pixelBuffer error:error]; } From d401439daa2f1791265b34d3a81d6466c7f9c125 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 19:22:11 +0530 Subject: [PATCH 193/753] Updated formatting --- .../tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm b/mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm index 5258b540f..667279b9f 100644 --- a/mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm +++ b/mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm @@ -170,7 +170,8 @@ using ::mediapipe::ImageFrame; [MPPCommonUtils createCustomError:error withCode:MPPTasksErrorCodeInvalidArgumentError description:@"Unsupported pixel format for CVPixelBuffer. Supported " - @"pixel format types are kCVPixelFormatType_32BGRA"]; + @"pixel format types are kCVPixelFormatType_32BGRA and " + @"kCVPixelFormatType_32RGBA"]; } } From ddd1515f88f5f7a9ab316eaff19f59f2a1ce9949 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 19:40:15 +0530 Subject: [PATCH 194/753] Updated documentation --- .../sources/MPPImageClassifier.h | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.h b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.h index 024eee0aa..549fa9fa4 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.h +++ b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.h @@ -85,6 +85,14 @@ NS_SWIFT_NAME(ImageClassifier) * interest. Rotation will be applied according to the `orientation` property of the provided * `MPPImage`. Only use this method when the `MPPImageClassifier` is created with * `MPPRunningModeImage`. + * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is + * RGB with an Alpha channel. * * @param image The `MPPImage` on which image classification is to be performed. * @param error An optional error parameter populated when there is an error in performing image @@ -102,6 +110,15 @@ NS_SWIFT_NAME(ImageClassifier) * of the provided `MPPImage`. Only use this method when the `MPPImageClassifier` is created with * `MPPRunningModeImage`. * + * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is + * RGB with an Alpha channel. + * * @param image The `MPPImage` on which image classification is to be performed. * @param roi A `CGRect` specifying the region of interest within the given `MPPImage`, on which * image classification should be performed. @@ -121,6 +138,18 @@ NS_SWIFT_NAME(ImageClassifier) * the provided `MPPImage`. Only use this method when the `MPPImageClassifier` is created with * `MPPRunningModeVideo`. * + * It's required to provide the video frame's timestamp (in milliseconds). The input timestamps must + * be monotonically increasing. + * + * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is + * RGB with an Alpha channel. + * * @param image The `MPPImage` on which image classification is to be performed. * @param timestampInMilliseconds The video frame's timestamp (in milliseconds). The input * timestamps must be monotonically increasing. @@ -143,6 +172,15 @@ NS_SWIFT_NAME(ImageClassifier) * It's required to provide the video frame's timestamp (in milliseconds). The input timestamps must * be monotonically increasing. * + * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is + * RGB with an Alpha channel. + * * @param image A live stream image data of type `MPPImage` on which image classification is to be * performed. * @param timestampInMilliseconds The video frame's timestamp (in milliseconds). The input @@ -165,6 +203,7 @@ NS_SWIFT_NAME(ImageClassifier) * image as region of interest. Rotation will be applied according to the `orientation` property of * the provided `MPPImage`. Only use this method when the `MPPImageClassifier` is created with * `MPPRunningModeLiveStream`. + * * The object which needs to be continuously notified of the available results of image * classification must confirm to `MPPImageClassifierLiveStreamDelegate` protocol and implement the * `imageClassifier:didFinishClassificationWithResult:timestampInMilliseconds:error:` @@ -173,6 +212,19 @@ NS_SWIFT_NAME(ImageClassifier) * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent * to the image classifier. The input timestamps must be monotonically increasing. * + * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If the input `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color + * space is RGB with an Alpha channel. + * + * If this method is used for classifying live camera frames using `AVFoundation`, ensure that you + * request `AVCaptureVideoDataOutput` to output frames in `kCMPixelFormat_32RGBA` using its + * `videoSettings` property. + * * @param image A live stream image data of type `MPPImage` on which image classification is to be * performed. * @param timestampInMilliseconds The timestamp (in milliseconds) which indicates when the input @@ -192,6 +244,7 @@ NS_SWIFT_NAME(ImageClassifier) * specified region of interest.. Rotation will be applied according to the `orientation` property * of the provided `MPPImage`. Only use this method when the `MPPImageClassifier` is created with * `MPPRunningModeLiveStream`. + * * The object which needs to be continuously notified of the available results of image * classification must confirm to `MPPImageClassifierLiveStreamDelegate` protocol and implement the * `imageClassifier:didFinishClassificationWithResult:timestampInMilliseconds:error:` delegate @@ -199,6 +252,19 @@ NS_SWIFT_NAME(ImageClassifier) * * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent * to the image classifier. The input timestamps must be monotonically increasing. + * + * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If the input `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color + * space is RGB with an Alpha channel. + * + * If this method is used for classifying live camera frames using `AVFoundation`, ensure that you + * request `AVCaptureVideoDataOutput` to output frames in `kCMPixelFormat_32RGBA` using its + * `videoSettings` property. * * @param image A live stream image data of type `MPPImage` on which image classification is to be * performed. From 8ec0724b65c03dddddc2e13c09f6ea9238cdfc1d Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 19:44:11 +0530 Subject: [PATCH 195/753] Updated documentation to include note about rgba images --- .../sources/MPPObjectDetector.h | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h index 4ac8cc773..82404849b 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h @@ -95,6 +95,15 @@ NS_SWIFT_NAME(ObjectDetector) * interest. Rotation will be applied according to the `orientation` property of the provided * `MPPImage`. Only use this method when the `MPPObjectDetector` is created with * `MPPRunningModeImage`. + * + * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is + * RGB with an Alpha channel. * * @param image The `MPPImage` on which object detection is to be performed. * @param error An optional error parameter populated when there is an error in performing object @@ -114,6 +123,15 @@ NS_SWIFT_NAME(ObjectDetector) * image as region of interest. Rotation will be applied according to the `orientation` property of * the provided `MPPImage`. Only use this method when the `MPPObjectDetector` is created with * `MPPRunningModeVideo`. + * + * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is + * RGB with an Alpha channel. * * @param image The `MPPImage` on which object detection is to be performed. * @param timestampInMilliseconds The video frame's timestamp (in milliseconds). The input @@ -136,6 +154,7 @@ NS_SWIFT_NAME(ObjectDetector) * image as region of interest. Rotation will be applied according to the `orientation` property of * the provided `MPPImage`. Only use this method when the `MPPObjectDetector` is created with * `MPPRunningModeLiveStream`. + * * The object which needs to be continuously notified of the available results of object * detection must confirm to `MPPObjectDetectorLiveStreamDelegate` protocol and implement the * `objectDetector:didFinishDetectionWithResult:timestampInMilliseconds:error:` delegate method. @@ -143,6 +162,19 @@ NS_SWIFT_NAME(ObjectDetector) * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent * to the object detector. The input timestamps must be monotonically increasing. * + * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If the input `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color + * space is RGB with an Alpha channel. + * + * If this method is used for classifying live camera frames using `AVFoundation`, ensure that you + * request `AVCaptureVideoDataOutput` to output frames in `kCMPixelFormat_32RGBA` using its + * `videoSettings` property. + * * @param image A live stream image data of type `MPPImage` on which object detection is to be * performed. * @param timestampInMilliseconds The timestamp (in milliseconds) which indicates when the input From 33ae23c53aacd144377c7cf37850021ed600a46a Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 19:51:54 +0530 Subject: [PATCH 196/753] Increased wait time for image classifier asynchronous tests --- .../test/vision/image_classifier/MPPImageClassifierTests.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m b/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m index a2fd68482..d873d409a 100644 --- a/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m +++ b/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m @@ -652,7 +652,7 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; }]; AssertEqualErrors(error, expectedError); - [self waitForExpectations:@[ expectation ] timeout:1e-2f]; + [self waitForExpectations:@[ expectation ] timeout:0.5f]; } - (void)testClassifyWithLiveStreamModeSucceeds { @@ -699,7 +699,7 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; XCTAssertTrue([imageClassifier classifyAsyncImage:image timestampInMilliseconds:i error:nil]); } - [self waitForExpectations:@[ expectation ] timeout:1e-2f]; + [self waitForExpectations:@[ expectation ] timeout:0.5f]; } - (void)imageClassifier:(MPPImageClassifier *)imageClassifier From 00712d727ea1fc9a238096fdc1344a0b23c016d1 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 19:53:06 +0530 Subject: [PATCH 197/753] Updated wait time for object detector tests --- .../ios/test/vision/object_detector/MPPObjectDetectorTests.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m index 9ccfece91..bc4e24af8 100644 --- a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m +++ b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m @@ -660,7 +660,7 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; @"INVALID_ARGUMENT: Input timestamp must be monotonically increasing." }]; AssertEqualErrors(error, expectedError); - [self waitForExpectations:@[ expectation ] timeout:1.0]; + [self waitForExpectations:@[ expectation ] timeout:0.5f]; } - (void)testDetectWithLiveStreamModeSucceeds { @@ -707,7 +707,7 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; XCTAssertTrue([objectDetector detectAsyncInImage:image timestampInMilliseconds:i error:nil]); } - [self waitForExpectations:@[ expectation ] timeout:0.5]; + [self waitForExpectations:@[ expectation ] timeout:0.5f]; } #pragma mark MPPObjectDetectorLiveStreamDelegate Methods From a4e11eac7851394e125a07693763c4b12b0dae95 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 19:55:19 +0530 Subject: [PATCH 198/753] Added constants for time out --- .../test/vision/object_detector/MPPObjectDetectorTests.m | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m index bc4e24af8..daa984ecf 100644 --- a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m +++ b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m @@ -660,7 +660,9 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; @"INVALID_ARGUMENT: Input timestamp must be monotonically increasing." }]; AssertEqualErrors(error, expectedError); - [self waitForExpectations:@[ expectation ] timeout:0.5f]; + + NSTimeInterval timeout = 0.5f; + [self waitForExpectations:@[ expectation ] timeout:timeout]; } - (void)testDetectWithLiveStreamModeSucceeds { @@ -707,7 +709,8 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; XCTAssertTrue([objectDetector detectAsyncInImage:image timestampInMilliseconds:i error:nil]); } - [self waitForExpectations:@[ expectation ] timeout:0.5f]; + NSTimeInterval timeout = 0.5f; + [self waitForExpectations:@[ expectation ] timeout:timeout]; } #pragma mark MPPObjectDetectorLiveStreamDelegate Methods From 08282d9fd78057bd0727848fd7b729b8ef9362c0 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 19:59:39 +0530 Subject: [PATCH 199/753] Updated time out for image classifier async tests --- .../test/vision/image_classifier/MPPImageClassifierTests.m | 6 ++++-- .../test/vision/object_detector/MPPObjectDetectorTests.m | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m b/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m index d873d409a..7eb93df8e 100644 --- a/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m +++ b/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m @@ -652,7 +652,8 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; }]; AssertEqualErrors(error, expectedError); - [self waitForExpectations:@[ expectation ] timeout:0.5f]; + NSTimeInterval timeout = 0.5f; + [self waitForExpectations:@[ expectation ] timeout:timeout]; } - (void)testClassifyWithLiveStreamModeSucceeds { @@ -699,7 +700,8 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; XCTAssertTrue([imageClassifier classifyAsyncImage:image timestampInMilliseconds:i error:nil]); } - [self waitForExpectations:@[ expectation ] timeout:0.5f]; + NSTimeInterval timeout = 0.5f; + [self waitForExpectations:@[ expectation ] timeout:timeout]; } - (void)imageClassifier:(MPPImageClassifier *)imageClassifier diff --git a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m index fd9466b7d..d34078744 100644 --- a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m +++ b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m @@ -715,7 +715,7 @@ static const float scoreDifferenceTolerance = 0.02f; XCTAssertTrue([objectDetector detectAsyncInImage:image timestampInMilliseconds:i error:nil]); } - [self waitForExpectations:@[ expectation ] timeout:0.5]; + [self waitForExpectations:@[ expectation ] timeout:0.5f]; } @end From 3df4f7db6458b64b5055c5300448872e0a4f5648 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 20:00:29 +0530 Subject: [PATCH 200/753] Updated time out for object detector --- .../test/vision/object_detector/MPPObjectDetectorTests.m | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m index d34078744..d3b81703b 100644 --- a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m +++ b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m @@ -664,7 +664,9 @@ static const float scoreDifferenceTolerance = 0.02f; @"INVALID_ARGUMENT: Input timestamp must be monotonically increasing." }]; AssertEqualErrors(error, expectedError); - [self waitForExpectations:@[ expectation ] timeout:1.0]; + + NSTimeInterval timeout = 0.5f; + [self waitForExpectations:@[ expectation ] timeout:timeout]; } - (void)testDetectWithLiveStreamModeSucceeds { @@ -715,7 +717,8 @@ static const float scoreDifferenceTolerance = 0.02f; XCTAssertTrue([objectDetector detectAsyncInImage:image timestampInMilliseconds:i error:nil]); } - [self waitForExpectations:@[ expectation ] timeout:0.5f]; + NSTimeInterval timeout = 0.5f; + [self waitForExpectations:@[ expectation ] timeout:timeout]; } @end From 767db32d690354d17849579dd510c98c557984d5 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 4 May 2023 09:27:21 -0700 Subject: [PATCH 201/753] Support multiple poses for PoseLandmarker PiperOrigin-RevId: 529430797 --- .../vision/pose_landmarker/pose_landmarker.ts | 15 ++++--- .../pose_landmarker_result.d.ts | 6 +-- .../pose_landmarker/pose_landmarker_test.ts | 43 +++++++++++++++++-- 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts index 2d72bf1dc..d21a9a6db 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts @@ -309,7 +309,7 @@ export class PoseLandmarker extends VisionTaskRunner { if (!('worldLandmarks' in this.result)) { return; } - if (!('landmarks' in this.result)) { + if (!('auxilaryLandmarks' in this.result)) { return; } if (this.outputSegmentationMasks && !('segmentationMasks' in this.result)) { @@ -332,10 +332,11 @@ export class PoseLandmarker extends VisionTaskRunner { * Converts raw data into a landmark, and adds it to our landmarks list. */ private addJsLandmarks(data: Uint8Array[]): void { + this.result.landmarks = []; for (const binaryProto of data) { const poseLandmarksProto = NormalizedLandmarkList.deserializeBinary(binaryProto); - this.result.landmarks = convertToLandmarks(poseLandmarksProto); + this.result.landmarks.push(convertToLandmarks(poseLandmarksProto)); } } @@ -344,11 +345,12 @@ export class PoseLandmarker extends VisionTaskRunner { * worldLandmarks list. */ private adddJsWorldLandmarks(data: Uint8Array[]): void { + this.result.worldLandmarks = []; for (const binaryProto of data) { const poseWorldLandmarksProto = LandmarkList.deserializeBinary(binaryProto); - this.result.worldLandmarks = - convertToWorldLandmarks(poseWorldLandmarksProto); + this.result.worldLandmarks.push( + convertToWorldLandmarks(poseWorldLandmarksProto)); } } @@ -357,11 +359,12 @@ export class PoseLandmarker extends VisionTaskRunner { * landmarks list. */ private addJsAuxiliaryLandmarks(data: Uint8Array[]): void { + this.result.auxilaryLandmarks = []; for (const binaryProto of data) { const auxiliaryLandmarksProto = NormalizedLandmarkList.deserializeBinary(binaryProto); - this.result.auxilaryLandmarks = - convertToLandmarks(auxiliaryLandmarksProto); + this.result.auxilaryLandmarks.push( + convertToLandmarks(auxiliaryLandmarksProto)); } } diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts index 66d0498a6..d4d3d3bec 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts @@ -26,13 +26,13 @@ export {Category, Landmark, NormalizedLandmark}; */ export declare interface PoseLandmarkerResult { /** Pose landmarks of detected poses. */ - landmarks: NormalizedLandmark[]; + landmarks: NormalizedLandmark[][]; /** Pose landmarks in world coordinates of detected poses. */ - worldLandmarks: Landmark[]; + worldLandmarks: Landmark[][]; /** Detected auxiliary landmarks, used for deriving ROI for next frame. */ - auxilaryLandmarks: NormalizedLandmark[]; + auxilaryLandmarks: NormalizedLandmark[][]; /** Segmentation mask for the detected pose. */ segmentationMasks?: MPImage[]; diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts index 794df68b8..c97b0d7b0 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts @@ -222,9 +222,9 @@ describe('PoseLandmarker', () => { .toHaveBeenCalledTimes(1); expect(poseLandmarker.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); - expect(result.landmarks).toEqual([{'x': 0, 'y': 0, 'z': 0}]); - expect(result.worldLandmarks).toEqual([{'x': 0, 'y': 0, 'z': 0}]); - expect(result.auxilaryLandmarks).toEqual([{'x': 0, 'y': 0, 'z': 0}]); + expect(result.landmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); + expect(result.worldLandmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); + expect(result.auxilaryLandmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); expect(result.segmentationMasks![0]).toBeInstanceOf(MPImage); done(); }); @@ -261,6 +261,43 @@ describe('PoseLandmarker', () => { expect(landmarks1).toEqual(landmarks2); }); + it('supports multiple poses', (done) => { + const landmarksProto = [ + createLandmarks(0.1, 0.2, 0.3).serializeBinary(), + createLandmarks(0.4, 0.5, 0.6).serializeBinary() + ]; + const worldLandmarksProto = [ + createWorldLandmarks(1, 2, 3).serializeBinary(), + createWorldLandmarks(4, 5, 6).serializeBinary() + ]; + + poseLandmarker.setOptions({numPoses: 1}); + + // Pass the test data to our listener + poseLandmarker.fakeWasmModule._waitUntilIdle.and.callFake(() => { + poseLandmarker.listeners.get('normalized_landmarks')! + (landmarksProto, 1337); + poseLandmarker.listeners.get('world_landmarks')! + (worldLandmarksProto, 1337); + poseLandmarker.listeners.get('auxiliary_landmarks')! + (landmarksProto, 1337); + }); + + // Invoke the pose landmarker + poseLandmarker.detect({} as HTMLImageElement, result => { + expect(result.landmarks).toEqual([ + [{'x': 0.1, 'y': 0.2, 'z': 0.3}], [{'x': 0.4, 'y': 0.5, 'z': 0.6}] + ]); + expect(result.worldLandmarks).toEqual([ + [{'x': 1, 'y': 2, 'z': 3}], [{'x': 4, 'y': 5, 'z': 6}] + ]); + expect(result.auxilaryLandmarks).toEqual([ + [{'x': 0.1, 'y': 0.2, 'z': 0.3}], [{'x': 0.4, 'y': 0.5, 'z': 0.6}] + ]); + done(); + }); + }); + it('invokes listener once masks are avaiblae', (done) => { const landmarksProto = [createLandmarks().serializeBinary()]; const worldLandmarksProto = [createWorldLandmarks().serializeBinary()]; From 253662149e367105896b65e2ba7a6a3bbffbdfe9 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 23:03:03 +0530 Subject: [PATCH 202/753] Updated pixel format types in object detector --- .../tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm b/mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm index 75dfcc650..667279b9f 100644 --- a/mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm +++ b/mediapipe/tasks/ios/vision/core/utils/sources/MPPImage+Utils.mm @@ -162,6 +162,7 @@ using ::mediapipe::ImageFrame; OSType pixelBufferFormat = CVPixelBufferGetPixelFormatType(pixelBuffer); switch (pixelBufferFormat) { + case kCVPixelFormatType_32RGBA: case kCVPixelFormatType_32BGRA: { return [MPPCVPixelBufferUtils rgbImageFrameFromCVPixelBuffer:pixelBuffer error:error]; } @@ -169,7 +170,8 @@ using ::mediapipe::ImageFrame; [MPPCommonUtils createCustomError:error withCode:MPPTasksErrorCodeInvalidArgumentError description:@"Unsupported pixel format for CVPixelBuffer. Supported " - @"pixel format types are kCVPixelFormatType_32BGRA"]; + @"pixel format types are kCVPixelFormatType_32BGRA and " + @"kCVPixelFormatType_32RGBA"]; } } From 64cad80543945bf897769adb9000aaf9354fe788 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 4 May 2023 10:31:50 -0700 Subject: [PATCH 203/753] Internal change. PiperOrigin-RevId: 529449175 --- mediapipe/framework/tool/template_parser.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mediapipe/framework/tool/template_parser.cc b/mediapipe/framework/tool/template_parser.cc index f012ac418..ad799c34f 100644 --- a/mediapipe/framework/tool/template_parser.cc +++ b/mediapipe/framework/tool/template_parser.cc @@ -974,7 +974,7 @@ class TemplateParser::Parser::ParserImpl { } // Consumes an identifier and saves its value in the identifier parameter. - // Returns false if the token is not of type IDENTFIER. + // Returns false if the token is not of type IDENTIFIER. bool ConsumeIdentifier(std::string* identifier) { if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { *identifier = tokenizer_.current().text; @@ -1672,7 +1672,9 @@ class TemplateParser::Parser::MediaPipeParserImpl if (field_type == ProtoUtilLite::FieldType::TYPE_MESSAGE) { *args = {""}; } else { - MEDIAPIPE_CHECK_OK(ProtoUtilLite::Serialize({"1"}, field_type, args)); + constexpr char kPlaceholderValue[] = "1"; + MEDIAPIPE_CHECK_OK( + ProtoUtilLite::Serialize({kPlaceholderValue}, field_type, args)); } } From 47013d289eda63967457bd134dc479837efb6a56 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 23:19:12 +0530 Subject: [PATCH 204/753] Added flow limiter calculator in MediaPipeTasksCommon --- mediapipe/tasks/ios/BUILD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index c839acd84..e05f03d61 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -42,6 +42,7 @@ OBJC_COMMON_DEPS = [ "//mediapipe/tasks/ios/components/containers:MPPClassificationResult", "//mediapipe/tasks/ios/components/containers:MPPCategory", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", + "//mediapipe/calculators/core:flow_limiter_calculator", "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", @@ -172,6 +173,7 @@ apple_static_library( minimum_os_version = MPP_TASK_MINIMUM_OS_VERSION, platform_type = "ios", deps = [ + "//mediapipe/calculators/core:flow_limiter_calculator", "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", From 330976ce9ec18399bb2b483840845ef51313f403 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 4 May 2023 23:51:41 +0530 Subject: [PATCH 205/753] Added utils of containers and core to MPPTaskCommon to avoid warnings in xcode --- mediapipe/tasks/ios/BUILD | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index e05f03d61..6d18baf3d 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -34,13 +34,13 @@ licenses(["notice"]) # 2. Task graphs. These will be built with ":MediaPipeTaskGraphs_library". # 3. gpu targets which will be built with the ":MediaPipeTaskGraphs_library". OBJC_COMMON_DEPS = [ - "//mediapipe/tasks/ios/core:MPPBaseOptions", + "//mediapipe/tasks/ios/core/utils:MPPBaseOptionsHelpers", "//mediapipe/tasks/ios/core:MPPTaskInfo", "//mediapipe/tasks/ios/core:MPPTaskOptions", "//mediapipe/tasks/ios/core:MPPTaskResult", "//mediapipe/tasks/ios/core:MPPTaskRunner", - "//mediapipe/tasks/ios/components/containers:MPPClassificationResult", - "//mediapipe/tasks/ios/components/containers:MPPCategory", + "//mediapipe/tasks/ios/components/containers/utils:MPPClassificationResultHelpers", + "//mediapipe/tasks/ios/components/containers/utils:MPPCategoryHelpers", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", "//mediapipe/calculators/core:flow_limiter_calculator", "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", @@ -204,9 +204,9 @@ apple_static_xcframework( }, deps = [ "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", - "//mediapipe/tasks/ios/components/containers:MPPCategory", - "//mediapipe/tasks/ios/components/containers:MPPClassificationResult", - "//mediapipe/tasks/ios/core:MPPBaseOptions", + "//mediapipe/tasks/ios/components/containers/utils:MPPCategoryHelpers", + "//mediapipe/tasks/ios/components/containers/utils:MPPClassificationResultHelpers", + "//mediapipe/tasks/ios/core/utils:MPPBaseOptionsHelpers", "//mediapipe/tasks/ios/core:MPPTaskInfo", "//mediapipe/tasks/ios/core:MPPTaskOptions", "//mediapipe/tasks/ios/core:MPPTaskResult", From 1db1c29f5016cafb1934eadf15de2ce8e6241588 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Fri, 5 May 2023 01:04:04 +0530 Subject: [PATCH 206/753] Added code comments --- .../ios/vision/object_detector/sources/MPPObjectDetector.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm index 5dfbfdab8..6daebcf90 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm @@ -85,6 +85,11 @@ static NSString *const kTaskName = @"objectDetector"; // Capturing `self` as weak in order to avoid `self` being kept in memory // and cause a retain cycle, after self is set to `nil`. MPPObjectDetector *__weak weakSelf = self; + + // Create a private serial dispatch queue in which the deleagte method will be called + // asynchronously. This is to ensure that if the client performs a long running operation in + // the delegate method, the queue on which the C++ callbacks is invoked is not blocked and is + // freed up to continue with its operations. dispatch_queue_t callbackQueue = dispatch_queue_create([MPPVisionTaskRunner uniqueDispatchQueueNameWithSuffix:kTaskName], NULL); packetsCallback = [=](absl::StatusOr statusOrPackets) { From 12b0b6fad104c5a5cb19dbd68e9a708ddaf6cfd7 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 4 May 2023 13:15:01 -0700 Subject: [PATCH 207/753] Internal change PiperOrigin-RevId: 529495239 --- README.md | 195 ++++++------ docs/index.md | 195 ++++++------ .../python/vision/object_detector/dataset.py | 3 +- .../vision/object_detector/hyperparameters.py | 18 +- .../face_stylizer/face_stylizer_graph.cc | 7 +- mediapipe/tasks/web/vision/core/BUILD | 6 +- mediapipe/tasks/web/vision/core/image.test.ts | 3 +- mediapipe/tasks/web/vision/core/image.ts | 296 +----------------- .../tasks/web/vision/core/image_converter.ts | 83 +++++ .../web/vision/core/image_shader_context.ts | 243 ++++++++++++++ .../web/vision/core/vision_task_runner.ts | 3 +- 11 files changed, 534 insertions(+), 518 deletions(-) create mode 100644 mediapipe/tasks/web/vision/core/image_converter.ts create mode 100644 mediapipe/tasks/web/vision/core/image_shader_context.ts diff --git a/README.md b/README.md index a82c88ab1..cb3d56de6 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ title: Home nav_order: 1 --- -![MediaPipe](https://mediapipe.dev/images/mediapipe_small.png) - ---- **Attention:** *Thanks for your interest in MediaPipe! We have moved to @@ -14,86 +12,111 @@ 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). --------------------------------------------------------------------------------- +**On-device machine learning for everyone** -## Live ML anywhere +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. -[MediaPipe](https://google.github.io/mediapipe/) offers cross-platform, customizable -ML solutions for live and streaming media. +* [See demos](https://goo.gle/mediapipe-studio) +* [Learn more](https://developers.google.com/mediapipe/solutions) -![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* +## Get started ----- +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). -## ML solutions in MediaPipe +## Solutions -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) +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. -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) +These libraries and resources provide the core functionality for each MediaPipe +Solution: - - +* **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. -[]() | [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) | | | ✅ | | | +These tools let you customize and evaluate solutions: -See also -[MediaPipe Models and Model Cards](https://google.github.io/mediapipe/solutions/models) -for ML models released in MediaPipe. +* **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). -## Getting started +### Legacy solutions -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). +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 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). +For more on the legacy solutions, see the [documentation](https://github.com/google/mediapipe/tree/master/docs/solutions). -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). +## Framework -## Publications +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. + +[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 +125,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 +154,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. diff --git a/docs/index.md b/docs/index.md index a82c88ab1..cb3d56de6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,8 +4,6 @@ title: Home nav_order: 1 --- -![MediaPipe](https://mediapipe.dev/images/mediapipe_small.png) - ---- **Attention:** *Thanks for your interest in MediaPipe! We have moved to @@ -14,86 +12,111 @@ 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). --------------------------------------------------------------------------------- +**On-device machine learning for everyone** -## Live ML anywhere +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. -[MediaPipe](https://google.github.io/mediapipe/) offers cross-platform, customizable -ML solutions for live and streaming media. +* [See demos](https://goo.gle/mediapipe-studio) +* [Learn more](https://developers.google.com/mediapipe/solutions) -![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* +## Get started ----- +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). -## ML solutions in MediaPipe +## Solutions -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) +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. -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) +These libraries and resources provide the core functionality for each MediaPipe +Solution: - - +* **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. -[]() | [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) | | | ✅ | | | +These tools let you customize and evaluate solutions: -See also -[MediaPipe Models and Model Cards](https://google.github.io/mediapipe/solutions/models) -for ML models released in MediaPipe. +* **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). -## Getting started +### Legacy solutions -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). +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 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). +For more on the legacy solutions, see the [documentation](https://github.com/google/mediapipe/tree/master/docs/solutions). -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). +## Framework -## Publications +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. + +[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 +125,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 +154,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. diff --git a/mediapipe/model_maker/python/vision/object_detector/dataset.py b/mediapipe/model_maker/python/vision/object_detector/dataset.py index 6899d8612..c18a071b2 100644 --- a/mediapipe/model_maker/python/vision/object_detector/dataset.py +++ b/mediapipe/model_maker/python/vision/object_detector/dataset.py @@ -106,7 +106,7 @@ class Dataset(classification_dataset.ClassificationDataset): ... Each .xml annotation file should have the following format: - file0.jpg + file0.jpg kangaroo @@ -114,6 +114,7 @@ class Dataset(classification_dataset.ClassificationDataset): 89 386 262 + ... diff --git a/mediapipe/model_maker/python/vision/object_detector/hyperparameters.py b/mediapipe/model_maker/python/vision/object_detector/hyperparameters.py index 1bc7514f2..35fb630ae 100644 --- a/mediapipe/model_maker/python/vision/object_detector/hyperparameters.py +++ b/mediapipe/model_maker/python/vision/object_detector/hyperparameters.py @@ -27,8 +27,6 @@ class HParams(hp.BaseHParams): learning_rate: Learning rate to use for gradient descent training. batch_size: Batch size for training. epochs: Number of training iterations over the dataset. - do_fine_tuning: If true, the base module is trained together with the - classification layer on top. cosine_decay_epochs: The number of epochs for cosine decay learning rate. See https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/schedules/CosineDecay @@ -39,13 +37,13 @@ class HParams(hp.BaseHParams): """ # Parameters from BaseHParams class. - learning_rate: float = 0.003 - batch_size: int = 32 - epochs: int = 10 + learning_rate: float = 0.3 + batch_size: int = 8 + epochs: int = 30 # Parameters for cosine learning rate decay cosine_decay_epochs: Optional[int] = None - cosine_decay_alpha: float = 0.0 + cosine_decay_alpha: float = 1.0 @dataclasses.dataclass @@ -67,8 +65,8 @@ class QATHParams: for more information. """ - learning_rate: float = 0.03 - batch_size: int = 32 - epochs: int = 10 - decay_steps: int = 231 + learning_rate: float = 0.3 + batch_size: int = 8 + epochs: int = 15 + decay_steps: int = 8 decay_rate: float = 0.96 diff --git a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc index cb49ef59d..d7265a146 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc +++ b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc @@ -361,9 +361,10 @@ class FaceStylizerGraph : public core::ModelTaskGraph { auto& tensors_to_image = graph.AddNode("mediapipe.tasks.TensorsToImageCalculator"); - ConfigureTensorsToImageCalculator( - image_to_tensor_options, - &tensors_to_image.GetOptions()); + auto& tensors_to_image_options = + tensors_to_image.GetOptions(); + tensors_to_image_options.mutable_input_tensor_float_range()->set_min(-1); + tensors_to_image_options.mutable_input_tensor_float_range()->set_max(1); face_alignment_image >> tensors_to_image.In(kTensorsTag); face_alignment = tensors_to_image.Out(kImageTag).Cast(); diff --git a/mediapipe/tasks/web/vision/core/BUILD b/mediapipe/tasks/web/vision/core/BUILD index c53247ba7..05a5b3b83 100644 --- a/mediapipe/tasks/web/vision/core/BUILD +++ b/mediapipe/tasks/web/vision/core/BUILD @@ -41,7 +41,11 @@ mediapipe_ts_library( mediapipe_ts_library( name = "image", - srcs = ["image.ts"], + srcs = [ + "image.ts", + "image_converter.ts", + "image_shader_context.ts", + ], ) mediapipe_ts_library( diff --git a/mediapipe/tasks/web/vision/core/image.test.ts b/mediapipe/tasks/web/vision/core/image.test.ts index 73eb44240..da3bd76b2 100644 --- a/mediapipe/tasks/web/vision/core/image.test.ts +++ b/mediapipe/tasks/web/vision/core/image.test.ts @@ -16,7 +16,8 @@ import 'jasmine'; -import {MPImage, MPImageShaderContext, MPImageType} from './image'; +import {MPImage, MPImageType} from './image'; +import {MPImageShaderContext} from './image_shader_context'; const WIDTH = 2; const HEIGHT = 2; diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index 7d6997d37..e2b21c0e6 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -14,6 +14,9 @@ * limitations under the License. */ +import {DefaultColorConverter} from '../../../../tasks/web/vision/core/image_converter'; +import {assertNotNull, MPImageShaderContext} from '../../../../tasks/web/vision/core/image_shader_context'; + /** The underlying type of the image. */ export enum MPImageType { /** Represents the native `UInt8ClampedArray` type. */ @@ -34,235 +37,6 @@ export enum MPImageType { export type MPImageContainer = Uint8ClampedArray|Float32Array|ImageData|ImageBitmap|WebGLTexture; -const VERTEX_SHADER = ` - attribute vec2 aVertex; - attribute vec2 aTex; - varying vec2 vTex; - void main(void) { - gl_Position = vec4(aVertex, 0.0, 1.0); - vTex = aTex; - }`; - -const FRAGMENT_SHADER = ` - precision mediump float; - varying vec2 vTex; - uniform sampler2D inputTexture; - void main() { - gl_FragColor = texture2D(inputTexture, vTex); - } - `; - -function assertNotNull(value: T|null, msg: string): T { - if (value === null) { - throw new Error(`Unable to obtain required WebGL resource: ${msg}`); - } - return value; -} - -// TODO: Move internal-only types to different module. - -/** - * Utility class that encapsulates the buffers used by `MPImageShaderContext`. - * For internal use only. - */ -class MPImageShaderBuffers { - constructor( - private readonly gl: WebGL2RenderingContext, - private readonly vertexArrayObject: WebGLVertexArrayObject, - private readonly vertexBuffer: WebGLBuffer, - private readonly textureBuffer: WebGLBuffer) {} - - bind() { - this.gl.bindVertexArray(this.vertexArrayObject); - } - - unbind() { - this.gl.bindVertexArray(null); - } - - close() { - this.gl.deleteVertexArray(this.vertexArrayObject); - this.gl.deleteBuffer(this.vertexBuffer); - this.gl.deleteBuffer(this.textureBuffer); - } -} - -/** - * A class that encapsulates the shaders used by an MPImage. Can be re-used - * across MPImages that use the same WebGL2Rendering context. - * - * For internal use only. - */ -export class MPImageShaderContext { - private gl?: WebGL2RenderingContext; - private framebuffer?: WebGLFramebuffer; - private program?: WebGLProgram; - private vertexShader?: WebGLShader; - private fragmentShader?: WebGLShader; - private aVertex?: GLint; - private aTex?: GLint; - - /** - * The shader buffers used for passthrough renders that don't modify the - * input texture. - */ - private shaderBuffersPassthrough?: MPImageShaderBuffers; - - /** - * The shader buffers used for passthrough renders that flip the input texture - * vertically before conversion to a different type. This is used to flip the - * texture to the expected orientation for drawing in the browser. - */ - private shaderBuffersFlipVertically?: MPImageShaderBuffers; - - private compileShader(source: string, type: number): WebGLShader { - const gl = this.gl!; - const shader = - assertNotNull(gl.createShader(type), 'Failed to create WebGL shader'); - gl.shaderSource(shader, source); - gl.compileShader(shader); - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - const info = gl.getShaderInfoLog(shader); - throw new Error(`Could not compile WebGL shader: ${info}`); - } - gl.attachShader(this.program!, shader); - return shader; - } - - private setupShaders(): void { - const gl = this.gl!; - this.program = - assertNotNull(gl.createProgram()!, 'Failed to create WebGL program'); - - this.vertexShader = this.compileShader(VERTEX_SHADER, gl.VERTEX_SHADER); - this.fragmentShader = - this.compileShader(FRAGMENT_SHADER, gl.FRAGMENT_SHADER); - - gl.linkProgram(this.program); - const linked = gl.getProgramParameter(this.program, gl.LINK_STATUS); - if (!linked) { - const info = gl.getProgramInfoLog(this.program); - throw new Error(`Error during program linking: ${info}`); - } - - this.aVertex = gl.getAttribLocation(this.program, 'aVertex'); - this.aTex = gl.getAttribLocation(this.program, 'aTex'); - } - - private createBuffers(flipVertically: boolean): MPImageShaderBuffers { - const gl = this.gl!; - const vertexArrayObject = - assertNotNull(gl.createVertexArray(), 'Failed to create vertex array'); - gl.bindVertexArray(vertexArrayObject); - - const vertexBuffer = - assertNotNull(gl.createBuffer(), 'Failed to create buffer'); - gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); - gl.enableVertexAttribArray(this.aVertex!); - gl.vertexAttribPointer(this.aVertex!, 2, gl.FLOAT, false, 0, 0); - gl.bufferData( - gl.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), - gl.STATIC_DRAW); - - const textureBuffer = - assertNotNull(gl.createBuffer(), 'Failed to create buffer'); - gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer); - gl.enableVertexAttribArray(this.aTex!); - gl.vertexAttribPointer(this.aTex!, 2, gl.FLOAT, false, 0, 0); - - const bufferData = - flipVertically ? [0, 1, 0, 0, 1, 0, 1, 1] : [0, 0, 0, 1, 1, 1, 1, 0]; - gl.bufferData( - gl.ARRAY_BUFFER, new Float32Array(bufferData), gl.STATIC_DRAW); - - gl.bindBuffer(gl.ARRAY_BUFFER, null); - gl.bindVertexArray(null); - - return new MPImageShaderBuffers( - gl, vertexArrayObject, vertexBuffer, textureBuffer); - } - - private getShaderBuffers(flipVertically: boolean): MPImageShaderBuffers { - if (flipVertically) { - if (!this.shaderBuffersFlipVertically) { - this.shaderBuffersFlipVertically = - this.createBuffers(/* flipVertically= */ true); - } - return this.shaderBuffersFlipVertically; - } else { - if (!this.shaderBuffersPassthrough) { - this.shaderBuffersPassthrough = - this.createBuffers(/* flipVertically= */ false); - } - return this.shaderBuffersPassthrough; - } - } - - private maybeInitGL(gl: WebGL2RenderingContext): void { - if (!this.gl) { - this.gl = gl; - } else if (gl !== this.gl) { - throw new Error('Cannot change GL context once initialized'); - } - } - - /** Runs the callback using the shader. */ - run( - gl: WebGL2RenderingContext, flipVertically: boolean, - callback: () => T): T { - this.maybeInitGL(gl); - - if (!this.program) { - this.setupShaders(); - } - - const shaderBuffers = this.getShaderBuffers(flipVertically); - gl.useProgram(this.program!); - shaderBuffers.bind(); - const result = callback(); - shaderBuffers.unbind(); - - return result; - } - - /** - * Binds a framebuffer to the canvas. If the framebuffer does not yet exist, - * creates it first. Binds the provided texture to the framebuffer. - */ - bindFramebuffer(gl: WebGL2RenderingContext, texture: WebGLTexture): void { - this.maybeInitGL(gl); - if (!this.framebuffer) { - this.framebuffer = - assertNotNull(gl.createFramebuffer(), 'Failed to create framebuffe.'); - } - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - gl.framebufferTexture2D( - gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); - } - - unbindFramebuffer(): void { - this.gl?.bindFramebuffer(this.gl.FRAMEBUFFER, null); - } - - close() { - if (this.program) { - const gl = this.gl!; - gl.deleteProgram(this.program); - gl.deleteShader(this.vertexShader!); - gl.deleteShader(this.fragmentShader!); - } - if (this.framebuffer) { - this.gl!.deleteFramebuffer(this.framebuffer); - } - if (this.shaderBuffersPassthrough) { - this.shaderBuffersPassthrough.close(); - } - if (this.shaderBuffersFlipVertically) { - this.shaderBuffersFlipVertically.close(); - } - } -} - /** A four channel color with a red, green, blue and alpha values. */ export type RGBAColor = [number, number, number, number]; @@ -329,70 +103,6 @@ export interface MPImageChannelConverter { */ uint8ToFloatConverter?: (value: number) => number; } -/** - * Color converter that falls back to a default implementation if the - * user-provided converter does not specify a conversion. - */ -class DefaultColorConverter implements Required { - private static readonly WARNINGS_LOGGED = new Set(); - - constructor(private readonly customConverter: MPImageChannelConverter) {} - - floatToRGBAConverter(v: number): RGBAColor { - if (this.customConverter.floatToRGBAConverter) { - return this.customConverter.floatToRGBAConverter(v); - } - this.logWarningOnce('floatToRGBAConverter'); - return [v * 255, v * 255, v * 255, 255]; - } - - uint8ToRGBAConverter(v: number): RGBAColor { - if (this.customConverter.uint8ToRGBAConverter) { - return this.customConverter.uint8ToRGBAConverter(v); - } - this.logWarningOnce('uint8ToRGBAConverter'); - return [v, v, v, 255]; - } - - rgbaToFloatConverter(r: number, g: number, b: number, a: number): number { - if (this.customConverter.rgbaToFloatConverter) { - return this.customConverter.rgbaToFloatConverter(r, g, b, a); - } - this.logWarningOnce('rgbaToFloatConverter'); - return (r / 3 + g / 3 + b / 3) / 255; - } - - rgbaToUint8Converter(r: number, g: number, b: number, a: number): number { - if (this.customConverter.rgbaToUint8Converter) { - return this.customConverter.rgbaToUint8Converter(r, g, b, a); - } - this.logWarningOnce('rgbaToUint8Converter'); - return r / 3 + g / 3 + b / 3; - } - - floatToUint8Converter(v: number): number { - if (this.customConverter.floatToUint8Converter) { - return this.customConverter.floatToUint8Converter(v); - } - this.logWarningOnce('floatToUint8Converter'); - return v * 255; - } - - uint8ToFloatConverter(v: number): number { - if (this.customConverter.uint8ToFloatConverter) { - return this.customConverter.uint8ToFloatConverter(v); - } - this.logWarningOnce('uint8ToFloatConverter'); - return v / 255; - } - - private logWarningOnce(methodName: string): void { - if (!DefaultColorConverter.WARNINGS_LOGGED.has(methodName)) { - console.log(`Using default ${methodName}`); - DefaultColorConverter.WARNINGS_LOGGED.add(methodName); - } - } -} /** * The wrapper class for MediaPipe Image objects. diff --git a/mediapipe/tasks/web/vision/core/image_converter.ts b/mediapipe/tasks/web/vision/core/image_converter.ts new file mode 100644 index 000000000..348b89b82 --- /dev/null +++ b/mediapipe/tasks/web/vision/core/image_converter.ts @@ -0,0 +1,83 @@ +/** + * Copyright 2023 The MediaPipe Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {MPImageChannelConverter, RGBAColor} from '../../../../tasks/web/vision/core/image'; + +/** + * Color converter that falls back to a default implementation if the + * user-provided converter does not specify a conversion. + */ +export class DefaultColorConverter implements + Required { + private static readonly WARNINGS_LOGGED = new Set(); + + constructor(private readonly customConverter: MPImageChannelConverter) {} + + floatToRGBAConverter(v: number): RGBAColor { + if (this.customConverter.floatToRGBAConverter) { + return this.customConverter.floatToRGBAConverter(v); + } + this.logWarningOnce('floatToRGBAConverter'); + return [v * 255, v * 255, v * 255, 255]; + } + + uint8ToRGBAConverter(v: number): RGBAColor { + if (this.customConverter.uint8ToRGBAConverter) { + return this.customConverter.uint8ToRGBAConverter(v); + } + this.logWarningOnce('uint8ToRGBAConverter'); + return [v, v, v, 255]; + } + + rgbaToFloatConverter(r: number, g: number, b: number, a: number): number { + if (this.customConverter.rgbaToFloatConverter) { + return this.customConverter.rgbaToFloatConverter(r, g, b, a); + } + this.logWarningOnce('rgbaToFloatConverter'); + return (r / 3 + g / 3 + b / 3) / 255; + } + + rgbaToUint8Converter(r: number, g: number, b: number, a: number): number { + if (this.customConverter.rgbaToUint8Converter) { + return this.customConverter.rgbaToUint8Converter(r, g, b, a); + } + this.logWarningOnce('rgbaToUint8Converter'); + return r / 3 + g / 3 + b / 3; + } + + floatToUint8Converter(v: number): number { + if (this.customConverter.floatToUint8Converter) { + return this.customConverter.floatToUint8Converter(v); + } + this.logWarningOnce('floatToUint8Converter'); + return v * 255; + } + + uint8ToFloatConverter(v: number): number { + if (this.customConverter.uint8ToFloatConverter) { + return this.customConverter.uint8ToFloatConverter(v); + } + this.logWarningOnce('uint8ToFloatConverter'); + return v / 255; + } + + private logWarningOnce(methodName: string): void { + if (!DefaultColorConverter.WARNINGS_LOGGED.has(methodName)) { + console.log(`Using default ${methodName}`); + DefaultColorConverter.WARNINGS_LOGGED.add(methodName); + } + } +} diff --git a/mediapipe/tasks/web/vision/core/image_shader_context.ts b/mediapipe/tasks/web/vision/core/image_shader_context.ts new file mode 100644 index 000000000..eb17d001a --- /dev/null +++ b/mediapipe/tasks/web/vision/core/image_shader_context.ts @@ -0,0 +1,243 @@ +/** + * 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. + */ + +const VERTEX_SHADER = ` + attribute vec2 aVertex; + attribute vec2 aTex; + varying vec2 vTex; + void main(void) { + gl_Position = vec4(aVertex, 0.0, 1.0); + vTex = aTex; + }`; + +const FRAGMENT_SHADER = ` + precision mediump float; + varying vec2 vTex; + uniform sampler2D inputTexture; + void main() { + gl_FragColor = texture2D(inputTexture, vTex); + } + `; + +/** Helper to assert that `value` is not null. */ +export function assertNotNull(value: T|null, msg: string): T { + if (value === null) { + throw new Error(`Unable to obtain required WebGL resource: ${msg}`); + } + return value; +} + +/** + * Utility class that encapsulates the buffers used by `MPImageShaderContext`. + * For internal use only. + */ +class MPImageShaderBuffers { + constructor( + private readonly gl: WebGL2RenderingContext, + private readonly vertexArrayObject: WebGLVertexArrayObject, + private readonly vertexBuffer: WebGLBuffer, + private readonly textureBuffer: WebGLBuffer) {} + + bind() { + this.gl.bindVertexArray(this.vertexArrayObject); + } + + unbind() { + this.gl.bindVertexArray(null); + } + + close() { + this.gl.deleteVertexArray(this.vertexArrayObject); + this.gl.deleteBuffer(this.vertexBuffer); + this.gl.deleteBuffer(this.textureBuffer); + } +} + +/** + * A class that encapsulates the shaders used by an MPImage. Can be re-used + * across MPImages that use the same WebGL2Rendering context. + * + * For internal use only. + */ +export class MPImageShaderContext { + private gl?: WebGL2RenderingContext; + private framebuffer?: WebGLFramebuffer; + private program?: WebGLProgram; + private vertexShader?: WebGLShader; + private fragmentShader?: WebGLShader; + private aVertex?: GLint; + private aTex?: GLint; + + /** + * The shader buffers used for passthrough renders that don't modify the + * input texture. + */ + private shaderBuffersPassthrough?: MPImageShaderBuffers; + + /** + * The shader buffers used for passthrough renders that flip the input texture + * vertically before conversion to a different type. This is used to flip the + * texture to the expected orientation for drawing in the browser. + */ + private shaderBuffersFlipVertically?: MPImageShaderBuffers; + + private compileShader(source: string, type: number): WebGLShader { + const gl = this.gl!; + const shader = + assertNotNull(gl.createShader(type), 'Failed to create WebGL shader'); + gl.shaderSource(shader, source); + gl.compileShader(shader); + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + const info = gl.getShaderInfoLog(shader); + throw new Error(`Could not compile WebGL shader: ${info}`); + } + gl.attachShader(this.program!, shader); + return shader; + } + + private setupShaders(): void { + const gl = this.gl!; + this.program = + assertNotNull(gl.createProgram()!, 'Failed to create WebGL program'); + + this.vertexShader = this.compileShader(VERTEX_SHADER, gl.VERTEX_SHADER); + this.fragmentShader = + this.compileShader(FRAGMENT_SHADER, gl.FRAGMENT_SHADER); + + gl.linkProgram(this.program); + const linked = gl.getProgramParameter(this.program, gl.LINK_STATUS); + if (!linked) { + const info = gl.getProgramInfoLog(this.program); + throw new Error(`Error during program linking: ${info}`); + } + + this.aVertex = gl.getAttribLocation(this.program, 'aVertex'); + this.aTex = gl.getAttribLocation(this.program, 'aTex'); + } + + private createBuffers(flipVertically: boolean): MPImageShaderBuffers { + const gl = this.gl!; + const vertexArrayObject = + assertNotNull(gl.createVertexArray(), 'Failed to create vertex array'); + gl.bindVertexArray(vertexArrayObject); + + const vertexBuffer = + assertNotNull(gl.createBuffer(), 'Failed to create buffer'); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.enableVertexAttribArray(this.aVertex!); + gl.vertexAttribPointer(this.aVertex!, 2, gl.FLOAT, false, 0, 0); + gl.bufferData( + gl.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), + gl.STATIC_DRAW); + + const textureBuffer = + assertNotNull(gl.createBuffer(), 'Failed to create buffer'); + gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer); + gl.enableVertexAttribArray(this.aTex!); + gl.vertexAttribPointer(this.aTex!, 2, gl.FLOAT, false, 0, 0); + + const bufferData = + flipVertically ? [0, 1, 0, 0, 1, 0, 1, 1] : [0, 0, 0, 1, 1, 1, 1, 0]; + gl.bufferData( + gl.ARRAY_BUFFER, new Float32Array(bufferData), gl.STATIC_DRAW); + + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.bindVertexArray(null); + + return new MPImageShaderBuffers( + gl, vertexArrayObject, vertexBuffer, textureBuffer); + } + + private getShaderBuffers(flipVertically: boolean): MPImageShaderBuffers { + if (flipVertically) { + if (!this.shaderBuffersFlipVertically) { + this.shaderBuffersFlipVertically = + this.createBuffers(/* flipVertically= */ true); + } + return this.shaderBuffersFlipVertically; + } else { + if (!this.shaderBuffersPassthrough) { + this.shaderBuffersPassthrough = + this.createBuffers(/* flipVertically= */ false); + } + return this.shaderBuffersPassthrough; + } + } + + private maybeInitGL(gl: WebGL2RenderingContext): void { + if (!this.gl) { + this.gl = gl; + } else if (gl !== this.gl) { + throw new Error('Cannot change GL context once initialized'); + } + } + + /** Runs the callback using the shader. */ + run( + gl: WebGL2RenderingContext, flipVertically: boolean, + callback: () => T): T { + this.maybeInitGL(gl); + + if (!this.program) { + this.setupShaders(); + } + + const shaderBuffers = this.getShaderBuffers(flipVertically); + gl.useProgram(this.program!); + shaderBuffers.bind(); + const result = callback(); + shaderBuffers.unbind(); + + return result; + } + + /** + * Binds a framebuffer to the canvas. If the framebuffer does not yet exist, + * creates it first. Binds the provided texture to the framebuffer. + */ + bindFramebuffer(gl: WebGL2RenderingContext, texture: WebGLTexture): void { + this.maybeInitGL(gl); + if (!this.framebuffer) { + this.framebuffer = + assertNotNull(gl.createFramebuffer(), 'Failed to create framebuffe.'); + } + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + } + + unbindFramebuffer(): void { + this.gl?.bindFramebuffer(this.gl.FRAMEBUFFER, null); + } + + close() { + if (this.program) { + const gl = this.gl!; + gl.deleteProgram(this.program); + gl.deleteShader(this.vertexShader!); + gl.deleteShader(this.fragmentShader!); + } + if (this.framebuffer) { + this.gl!.deleteFramebuffer(this.framebuffer); + } + if (this.shaderBuffersPassthrough) { + this.shaderBuffersPassthrough.close(); + } + if (this.shaderBuffersFlipVertically) { + this.shaderBuffersFlipVertically.close(); + } + } +} diff --git a/mediapipe/tasks/web/vision/core/vision_task_runner.ts b/mediapipe/tasks/web/vision/core/vision_task_runner.ts index 285dbf900..3ff6e0604 100644 --- a/mediapipe/tasks/web/vision/core/vision_task_runner.ts +++ b/mediapipe/tasks/web/vision/core/vision_task_runner.ts @@ -17,8 +17,9 @@ import {NormalizedRect} from '../../../../framework/formats/rect_pb'; import {TaskRunner} from '../../../../tasks/web/core/task_runner'; import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; -import {MPImage, MPImageShaderContext} from '../../../../tasks/web/vision/core/image'; +import {MPImage} from '../../../../tasks/web/vision/core/image'; import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; +import {MPImageShaderContext} from '../../../../tasks/web/vision/core/image_shader_context'; import {GraphRunner, ImageSource, WasmMediaPipeConstructor} from '../../../../web/graph_runner/graph_runner'; import {SupportImage, WasmImage} from '../../../../web/graph_runner/graph_runner_image_lib'; import {isWebKit} from '../../../../web/graph_runner/platform_utils'; From 61cfe2ca9bacf914c64bb57d4b841263f9b91d67 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 4 May 2023 17:33:40 -0700 Subject: [PATCH 208/753] Object Detector remove nms operation from exported tflite PiperOrigin-RevId: 529559380 --- .../python/vision/object_detector/BUILD | 13 ++++ .../python/vision/object_detector/__init__.py | 1 + .../vision/object_detector/detection.py | 34 +++++++++ .../vision/object_detector/detection_test.py | 73 +++++++++++++++++++ .../python/vision/object_detector/model.py | 3 +- .../vision/object_detector/object_detector.py | 53 +++++++++++++- .../vision/object_detector/preprocessor.py | 42 ++++++----- 7 files changed, 199 insertions(+), 20 deletions(-) create mode 100644 mediapipe/model_maker/python/vision/object_detector/detection.py create mode 100644 mediapipe/model_maker/python/vision/object_detector/detection_test.py diff --git a/mediapipe/model_maker/python/vision/object_detector/BUILD b/mediapipe/model_maker/python/vision/object_detector/BUILD index f9c3f00fc..d8177a083 100644 --- a/mediapipe/model_maker/python/vision/object_detector/BUILD +++ b/mediapipe/model_maker/python/vision/object_detector/BUILD @@ -88,6 +88,17 @@ py_test( ], ) +py_library( + name = "detection", + srcs = ["detection.py"], +) + +py_test( + name = "detection_test", + srcs = ["detection_test.py"], + deps = [":detection"], +) + py_library( name = "hyperparameters", srcs = ["hyperparameters.py"], @@ -116,6 +127,7 @@ py_library( name = "model", srcs = ["model.py"], deps = [ + ":detection", ":model_options", ":model_spec", ], @@ -163,6 +175,7 @@ py_library( "//mediapipe/model_maker/python/core/tasks:classifier", "//mediapipe/model_maker/python/core/utils:model_util", "//mediapipe/model_maker/python/core/utils:quantization", + "//mediapipe/tasks/python/metadata/metadata_writers:metadata_info", "//mediapipe/tasks/python/metadata/metadata_writers:metadata_writer", "//mediapipe/tasks/python/metadata/metadata_writers:object_detector", ], diff --git a/mediapipe/model_maker/python/vision/object_detector/__init__.py b/mediapipe/model_maker/python/vision/object_detector/__init__.py index 4670b343c..3e0a62bf8 100644 --- a/mediapipe/model_maker/python/vision/object_detector/__init__.py +++ b/mediapipe/model_maker/python/vision/object_detector/__init__.py @@ -32,6 +32,7 @@ ObjectDetectorOptions = object_detector_options.ObjectDetectorOptions # Remove duplicated and non-public API del dataset del dataset_util # pylint: disable=undefined-variable +del detection # pylint: disable=undefined-variable del hyperparameters del model # pylint: disable=undefined-variable del model_options diff --git a/mediapipe/model_maker/python/vision/object_detector/detection.py b/mediapipe/model_maker/python/vision/object_detector/detection.py new file mode 100644 index 000000000..769189b24 --- /dev/null +++ b/mediapipe/model_maker/python/vision/object_detector/detection.py @@ -0,0 +1,34 @@ +# 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. +"""Custom Detection export module for Object Detection.""" + +from typing import Any, Mapping + +from official.vision.serving import detection + + +class DetectionModule(detection.DetectionModule): + """A serving detection module for exporting the model. + + This module overrides the tensorflow_models DetectionModule by only outputting + the pre-nms detection_boxes and detection_scores. + """ + + def serve(self, images) -> Mapping[str, Any]: + result = super().serve(images) + final_outputs = { + 'detection_boxes': result['detection_boxes'], + 'detection_scores': result['detection_scores'], + } + return final_outputs diff --git a/mediapipe/model_maker/python/vision/object_detector/detection_test.py b/mediapipe/model_maker/python/vision/object_detector/detection_test.py new file mode 100644 index 000000000..34f16c21c --- /dev/null +++ b/mediapipe/model_maker/python/vision/object_detector/detection_test.py @@ -0,0 +1,73 @@ +# 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. + +from unittest import mock +import tensorflow as tf + +from mediapipe.model_maker.python.vision.object_detector import detection +from official.core import config_definitions as cfg +from official.vision import configs +from official.vision.serving import detection as detection_module + + +class ObjectDetectorTest(tf.test.TestCase): + + @mock.patch.object(detection_module.DetectionModule, 'serve', autospec=True) + def test_detection_module(self, mock_serve): + mock_serve.return_value = { + 'detection_boxes': 1, + 'detection_scores': 2, + 'detection_classes': 3, + 'num_detections': 4, + } + model_config = configs.retinanet.RetinaNet( + min_level=3, + max_level=7, + num_classes=10, + input_size=[256, 256, 3], + anchor=configs.retinanet.Anchor( + num_scales=3, aspect_ratios=[0.5, 1.0, 2.0], anchor_size=3 + ), + backbone=configs.backbones.Backbone( + type='mobilenet', mobilenet=configs.backbones.MobileNet() + ), + decoder=configs.decoders.Decoder( + type='fpn', + fpn=configs.decoders.FPN( + num_filters=128, use_separable_conv=True, use_keras_layer=True + ), + ), + head=configs.retinanet.RetinaNetHead( + num_filters=128, use_separable_conv=True + ), + detection_generator=configs.retinanet.DetectionGenerator(), + norm_activation=configs.common.NormActivation(activation='relu6'), + ) + task_config = configs.retinanet.RetinaNetTask(model=model_config) + params = cfg.ExperimentConfig( + task=task_config, + ) + detection_instance = detection.DetectionModule( + params=params, batch_size=1, input_image_size=[256, 256] + ) + outputs = detection_instance.serve(0) + expected_outputs = { + 'detection_boxes': 1, + 'detection_scores': 2, + } + self.assertAllEqual(outputs, expected_outputs) + + +if __name__ == '__main__': + tf.test.main() diff --git a/mediapipe/model_maker/python/vision/object_detector/model.py b/mediapipe/model_maker/python/vision/object_detector/model.py index e3eb3a651..70e63d5b5 100644 --- a/mediapipe/model_maker/python/vision/object_detector/model.py +++ b/mediapipe/model_maker/python/vision/object_detector/model.py @@ -18,6 +18,7 @@ from typing import Mapping, Optional, Sequence, Union import tensorflow as tf +from mediapipe.model_maker.python.vision.object_detector import detection from mediapipe.model_maker.python.vision.object_detector import model_options as model_opt from mediapipe.model_maker.python.vision.object_detector import model_spec as ms from official.core import config_definitions as cfg @@ -29,7 +30,6 @@ from official.vision.losses import loss_utils from official.vision.modeling import factory from official.vision.modeling import retinanet_model from official.vision.modeling.layers import detection_generator -from official.vision.serving import detection class ObjectDetectorModel(tf.keras.Model): @@ -199,6 +199,7 @@ class ObjectDetectorModel(tf.keras.Model): max_detections=10, max_classes_per_detection=1, normalize_anchor_coordinates=True, + omit_nms=True, ), ) tflite_post_processing_config = ( diff --git a/mediapipe/model_maker/python/vision/object_detector/object_detector.py b/mediapipe/model_maker/python/vision/object_detector/object_detector.py index 746eef1b3..486c3ffa9 100644 --- a/mediapipe/model_maker/python/vision/object_detector/object_detector.py +++ b/mediapipe/model_maker/python/vision/object_detector/object_detector.py @@ -28,6 +28,7 @@ from mediapipe.model_maker.python.vision.object_detector import model_options as from mediapipe.model_maker.python.vision.object_detector import model_spec as ms from mediapipe.model_maker.python.vision.object_detector import object_detector_options from mediapipe.model_maker.python.vision.object_detector import preprocessor +from mediapipe.tasks.python.metadata.metadata_writers import metadata_info from mediapipe.tasks.python.metadata.metadata_writers import metadata_writer from mediapipe.tasks.python.metadata.metadata_writers import object_detector as object_detector_writer from official.vision.evaluation import coco_evaluator @@ -264,6 +265,27 @@ class ObjectDetector(classifier.Classifier): coco_metrics = coco_eval.result() return losses, coco_metrics + def _create_fixed_anchor( + self, anchor_box: List[float] + ) -> object_detector_writer.FixedAnchor: + """Helper function to create FixedAnchor objects from an anchor box array. + + Args: + anchor_box: List of anchor box coordinates in the format of [x_min, y_min, + x_max, y_max]. + + Returns: + A FixedAnchor object representing the anchor_box. + """ + image_shape = self._model_spec.input_image_shape[:2] + y_center_norm = (anchor_box[0] + anchor_box[2]) / (2 * image_shape[0]) + x_center_norm = (anchor_box[1] + anchor_box[3]) / (2 * image_shape[1]) + height_norm = (anchor_box[2] - anchor_box[0]) / image_shape[0] + width_norm = (anchor_box[3] - anchor_box[1]) / image_shape[1] + return object_detector_writer.FixedAnchor( + x_center_norm, y_center_norm, width_norm, height_norm + ) + def export_model( self, model_name: str = 'model.tflite', @@ -328,11 +350,40 @@ class ObjectDetector(classifier.Classifier): converter.target_spec.supported_ops = (tf.lite.OpsSet.TFLITE_BUILTINS,) tflite_model = converter.convert() - writer = object_detector_writer.MetadataWriter.create_for_models_with_nms( + # Build anchors + raw_anchor_boxes = self._preprocessor.anchor_boxes + anchors = [] + for _, anchor_boxes in raw_anchor_boxes.items(): + anchor_boxes_reshaped = anchor_boxes.numpy().reshape((-1, 4)) + for ab in anchor_boxes_reshaped: + anchors.append(self._create_fixed_anchor(ab)) + + ssd_anchors_options = object_detector_writer.SsdAnchorsOptions( + object_detector_writer.FixedAnchorsSchema(anchors) + ) + + tensor_decoding_options = object_detector_writer.TensorsDecodingOptions( + num_classes=self._num_classes, + num_boxes=len(anchors), + num_coords=4, + keypoint_coord_offset=0, + num_keypoints=0, + num_values_per_keypoint=2, + x_scale=1, + y_scale=1, + w_scale=1, + h_scale=1, + apply_exponential_on_box_size=True, + sigmoid_score=False, + ) + writer = object_detector_writer.MetadataWriter.create_for_models_without_nms( tflite_model, self._model_spec.mean_rgb, self._model_spec.stddev_rgb, labels=metadata_writer.Labels().add(list(self._label_names)), + ssd_anchors_options=ssd_anchors_options, + tensors_decoding_options=tensor_decoding_options, + output_tensors_order=metadata_info.RawDetectionOutputTensorsOrder.LOCATION_SCORE, ) tflite_model_with_metadata, metadata_json = writer.populate() model_util.save_tflite(tflite_model_with_metadata, tflite_file) diff --git a/mediapipe/model_maker/python/vision/object_detector/preprocessor.py b/mediapipe/model_maker/python/vision/object_detector/preprocessor.py index b4e08f997..ebea6a07b 100644 --- a/mediapipe/model_maker/python/vision/object_detector/preprocessor.py +++ b/mediapipe/model_maker/python/vision/object_detector/preprocessor.py @@ -44,6 +44,26 @@ class Preprocessor(object): self._aug_scale_max = 2.0 self._max_num_instances = 100 + self._padded_size = preprocess_ops.compute_padded_size( + self._output_size, 2**self._max_level + ) + + input_anchor = anchor.build_anchor_generator( + min_level=self._min_level, + max_level=self._max_level, + num_scales=self._num_scales, + aspect_ratios=self._aspect_ratios, + anchor_size=self._anchor_size, + ) + self._anchor_boxes = input_anchor(image_size=self._output_size) + self._anchor_labeler = anchor.AnchorLabeler( + self._match_threshold, self._unmatched_threshold + ) + + @property + def anchor_boxes(self): + return self._anchor_boxes + def __call__( self, data: Mapping[str, Any], is_training: bool = True ) -> Tuple[tf.Tensor, Mapping[str, Any]]: @@ -90,13 +110,10 @@ class Preprocessor(object): image, image_info = preprocess_ops.resize_and_crop_image( image, self._output_size, - padded_size=preprocess_ops.compute_padded_size( - self._output_size, 2**self._max_level - ), + padded_size=self._padded_size, aug_scale_min=(self._aug_scale_min if is_training else 1.0), aug_scale_max=(self._aug_scale_max if is_training else 1.0), ) - image_height, image_width, _ = image.get_shape().as_list() # Resize and crop boxes. image_scale = image_info[2, :] @@ -110,20 +127,9 @@ class Preprocessor(object): classes = tf.gather(classes, indices) # Assign anchors. - input_anchor = anchor.build_anchor_generator( - min_level=self._min_level, - max_level=self._max_level, - num_scales=self._num_scales, - aspect_ratios=self._aspect_ratios, - anchor_size=self._anchor_size, - ) - anchor_boxes = input_anchor(image_size=(image_height, image_width)) - anchor_labeler = anchor.AnchorLabeler( - self._match_threshold, self._unmatched_threshold - ) (cls_targets, box_targets, _, cls_weights, box_weights) = ( - anchor_labeler.label_anchors( - anchor_boxes, boxes, tf.expand_dims(classes, axis=1) + self._anchor_labeler.label_anchors( + self.anchor_boxes, boxes, tf.expand_dims(classes, axis=1) ) ) @@ -134,7 +140,7 @@ class Preprocessor(object): labels = { 'cls_targets': cls_targets, 'box_targets': box_targets, - 'anchor_boxes': anchor_boxes, + 'anchor_boxes': self.anchor_boxes, 'cls_weights': cls_weights, 'box_weights': box_weights, 'image_info': image_info, From 18d893c6979cbaf3b90e2ec6bf4d03f93bc3197b Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 4 May 2023 20:39:54 -0700 Subject: [PATCH 209/753] Add scribble support to InteractiveSegmenter Web API PiperOrigin-RevId: 529594131 --- mediapipe/tasks/web/vision/core/types.d.ts | 5 ++- .../image_segmenter/image_segmenter_test.ts | 2 +- .../interactive_segmenter.ts | 27 ++++++++++--- .../interactive_segmenter_test.ts | 40 +++++++++++++++---- .../pose_landmarker/pose_landmarker_test.ts | 2 +- 5 files changed, 59 insertions(+), 17 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/types.d.ts b/mediapipe/tasks/web/vision/core/types.d.ts index c985a9f36..64d67bc30 100644 --- a/mediapipe/tasks/web/vision/core/types.d.ts +++ b/mediapipe/tasks/web/vision/core/types.d.ts @@ -19,7 +19,10 @@ import {NormalizedKeypoint} from '../../../../tasks/web/components/containers/ke /** A Region-Of-Interest (ROI) to represent a region within an image. */ export declare interface RegionOfInterest { /** The ROI in keypoint format. */ - keypoint: NormalizedKeypoint; + keypoint?: NormalizedKeypoint; + + /** The ROI as scribbles over the object that the user wants to segment. */ + scribble?: NormalizedKeypoint[]; } /** A connection between two landmarks. */ diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts index c1ccd7997..8c8767ec7 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts @@ -263,7 +263,7 @@ describe('ImageSegmenter', () => { }); }); - it('invokes listener once masks are avaiblae', async () => { + it('invokes listener once masks are available', async () => { const categoryMask = new Uint8ClampedArray([1]); const confidenceMask = new Float32Array([0.0]); let listenerCalled = false; diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts index 67d6ec3f6..60ec9e1c5 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts @@ -338,16 +338,31 @@ export class InteractiveSegmenter extends VisionTaskRunner { const renderData = new RenderDataProto(); const renderAnnotation = new RenderAnnotationProto(); - const color = new ColorProto(); color.setR(255); renderAnnotation.setColor(color); - const point = new RenderAnnotationProto.Point(); - point.setNormalized(true); - point.setX(roi.keypoint.x); - point.setY(roi.keypoint.y); - renderAnnotation.setPoint(point); + if (roi.keypoint && roi.scribble) { + throw new Error('Cannot provide both keypoint and scribble.'); + } else if (roi.keypoint) { + const point = new RenderAnnotationProto.Point(); + point.setNormalized(true); + point.setX(roi.keypoint.x); + point.setY(roi.keypoint.y); + renderAnnotation.setPoint(point); + } else if (roi.scribble) { + const scribble = new RenderAnnotationProto.Scribble(); + for (const coord of roi.scribble) { + const point = new RenderAnnotationProto.Point(); + point.setNormalized(true); + point.setX(coord.x); + point.setY(coord.y); + scribble.addPoint(point); + } + renderAnnotation.setScribble(scribble); + } else { + throw new Error('Must provide either a keypoint or a scribble.'); + } renderData.addRenderAnnotations(renderAnnotation); diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts index 84ecde00b..a361af5a1 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts @@ -26,10 +26,14 @@ import {WasmImage} from '../../../../web/graph_runner/graph_runner_image_lib'; import {InteractiveSegmenter, RegionOfInterest} from './interactive_segmenter'; -const ROI: RegionOfInterest = { +const KEYPOINT: RegionOfInterest = { keypoint: {x: 0.1, y: 0.2} }; +const SCRIBBLE: RegionOfInterest = { + scribble: [{x: 0.1, y: 0.2}, {x: 0.3, y: 0.4}] +}; + class InteractiveSegmenterFake extends InteractiveSegmenter implements MediapipeTasksFake { calculatorName = @@ -134,22 +138,42 @@ describe('InteractiveSegmenter', () => { it('doesn\'t support region of interest', () => { expect(() => { interactiveSegmenter.segment( - {} as HTMLImageElement, ROI, + {} as HTMLImageElement, KEYPOINT, {regionOfInterest: {left: 0, right: 0, top: 0, bottom: 0}}, () => {}); }).toThrowError('This task doesn\'t support region-of-interest.'); }); - it('sends region-of-interest', (done) => { + it('sends region-of-interest with keypoint', (done) => { interactiveSegmenter.fakeWasmModule._waitUntilIdle.and.callFake(() => { expect(interactiveSegmenter.lastRoi).toBeDefined(); expect(interactiveSegmenter.lastRoi!.toObject().renderAnnotationsList![0]) .toEqual(jasmine.objectContaining({ color: {r: 255, b: undefined, g: undefined}, + point: {x: 0.1, y: 0.2, normalized: true}, })); done(); }); - interactiveSegmenter.segment({} as HTMLImageElement, ROI, () => {}); + interactiveSegmenter.segment({} as HTMLImageElement, KEYPOINT, () => {}); + }); + + it('sends region-of-interest with scribble', (done) => { + interactiveSegmenter.fakeWasmModule._waitUntilIdle.and.callFake(() => { + expect(interactiveSegmenter.lastRoi).toBeDefined(); + expect(interactiveSegmenter.lastRoi!.toObject().renderAnnotationsList![0]) + .toEqual(jasmine.objectContaining({ + color: {r: 255, b: undefined, g: undefined}, + scribble: { + pointList: [ + {x: 0.1, y: 0.2, normalized: true}, + {x: 0.3, y: 0.4, normalized: true} + ] + }, + })); + done(); + }); + + interactiveSegmenter.segment({} as HTMLImageElement, SCRIBBLE, () => {}); }); it('supports category mask', async () => { @@ -168,7 +192,7 @@ describe('InteractiveSegmenter', () => { // Invoke the image segmenter return new Promise(resolve => { - interactiveSegmenter.segment({} as HTMLImageElement, ROI, result => { + interactiveSegmenter.segment({} as HTMLImageElement, KEYPOINT, result => { expect(interactiveSegmenter.fakeWasmModule._waitUntilIdle) .toHaveBeenCalled(); expect(result.categoryMask).toBeInstanceOf(MPImage); @@ -199,7 +223,7 @@ describe('InteractiveSegmenter', () => { }); return new Promise(resolve => { // Invoke the image segmenter - interactiveSegmenter.segment({} as HTMLImageElement, ROI, result => { + interactiveSegmenter.segment({} as HTMLImageElement, KEYPOINT, result => { expect(interactiveSegmenter.fakeWasmModule._waitUntilIdle) .toHaveBeenCalled(); expect(result.categoryMask).not.toBeDefined(); @@ -239,7 +263,7 @@ describe('InteractiveSegmenter', () => { return new Promise(resolve => { // Invoke the image segmenter interactiveSegmenter.segment( - {} as HTMLImageElement, ROI, result => { + {} as HTMLImageElement, KEYPOINT, result => { expect(interactiveSegmenter.fakeWasmModule._waitUntilIdle) .toHaveBeenCalled(); expect(result.categoryMask).toBeInstanceOf(MPImage); @@ -276,7 +300,7 @@ describe('InteractiveSegmenter', () => { }); return new Promise(resolve => { - interactiveSegmenter.segment({} as HTMLImageElement, ROI, () => { + interactiveSegmenter.segment({} as HTMLImageElement, KEYPOINT, () => { listenerCalled = true; resolve(); }); diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts index c97b0d7b0..907cb16b3 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts @@ -298,7 +298,7 @@ describe('PoseLandmarker', () => { }); }); - it('invokes listener once masks are avaiblae', (done) => { + it('invokes listener once masks are available', (done) => { const landmarksProto = [createLandmarks().serializeBinary()]; const worldLandmarksProto = [createWorldLandmarks().serializeBinary()]; const masks = [ From c24e7a250c964a945612418f231012118b74531e Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 4 May 2023 22:58:30 -0700 Subject: [PATCH 210/753] Internal change PiperOrigin-RevId: 529617578 --- .../tasks/cc/vision/image_segmenter/BUILD | 2 + .../image_segmenter/image_segmenter_graph.cc | 51 +++++++++++++++---- third_party/external_files.bzl | 8 +-- 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/mediapipe/tasks/cc/vision/image_segmenter/BUILD b/mediapipe/tasks/cc/vision/image_segmenter/BUILD index 183b1bb86..fc977c0b5 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/BUILD +++ b/mediapipe/tasks/cc/vision/image_segmenter/BUILD @@ -63,6 +63,8 @@ cc_library( "//mediapipe/calculators/image:image_properties_calculator", "//mediapipe/calculators/image:image_transformation_calculator", "//mediapipe/calculators/image:image_transformation_calculator_cc_proto", + "//mediapipe/calculators/image:set_alpha_calculator", + "//mediapipe/calculators/image:set_alpha_calculator_cc_proto", "//mediapipe/calculators/tensor:image_to_tensor_calculator", "//mediapipe/calculators/tensor:image_to_tensor_calculator_cc_proto", "//mediapipe/calculators/tensor:inference_calculator", diff --git a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_graph.cc b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_graph.cc index a52d3fa9a..6ecfa3685 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_graph.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_graph.cc @@ -23,6 +23,7 @@ limitations under the License. #include "absl/strings/str_format.h" #include "mediapipe/calculators/image/image_clone_calculator.pb.h" #include "mediapipe/calculators/image/image_transformation_calculator.pb.h" +#include "mediapipe/calculators/image/set_alpha_calculator.pb.h" #include "mediapipe/calculators/tensor/tensor_converter_calculator.pb.h" #include "mediapipe/framework/api2/builder.h" #include "mediapipe/framework/api2/port.h" @@ -249,7 +250,8 @@ void ConfigureTensorConverterCalculator( // the tflite model. absl::StatusOr ConvertImageToTensors( Source image_in, Source norm_rect_in, bool use_gpu, - const core::ModelResources& model_resources, Graph& graph) { + bool is_hair_segmentation, const core::ModelResources& model_resources, + Graph& graph) { ASSIGN_OR_RETURN(const tflite::Tensor* tflite_input_tensor, GetInputTensor(model_resources)); if (tflite_input_tensor->shape()->size() != 4) { @@ -294,9 +296,17 @@ absl::StatusOr ConvertImageToTensors( // Convert from Image to legacy ImageFrame or GpuBuffer. auto& from_image = graph.AddNode("FromImageCalculator"); image_on_device >> from_image.In(kImageTag); - auto image_cpu_or_gpu = + Source image_cpu_or_gpu = from_image.Out(use_gpu ? kImageGpuTag : kImageCpuTag); + if (is_hair_segmentation) { + auto& set_alpha = graph.AddNode("SetAlphaCalculator"); + set_alpha.GetOptions() + .set_alpha_value(0); + image_cpu_or_gpu >> set_alpha.In(use_gpu ? kImageGpuTag : kImageTag); + image_cpu_or_gpu = set_alpha.Out(use_gpu ? kImageGpuTag : kImageTag); + } + // Resize the input image to the model input size. auto& image_transformation = graph.AddNode("ImageTransformationCalculator"); ConfigureImageTransformationCalculator( @@ -461,22 +471,41 @@ class ImageSegmenterGraph : public core::ModelTaskGraph { bool use_gpu = components::processors::DetermineImagePreprocessingGpuBackend( task_options.base_options().acceleration()); - ASSIGN_OR_RETURN(auto image_and_tensors, - ConvertImageToTensors(image_in, norm_rect_in, use_gpu, - model_resources, graph)); - // Adds inference subgraph and connects its input stream to the output - // tensors produced by the ImageToTensorCalculator. - auto& inference = AddInference( - model_resources, task_options.base_options().acceleration(), graph); - image_and_tensors.tensors >> inference.In(kTensorsTag); - // Adds segmentation calculators for output streams. + // Adds segmentation calculators for output streams. Add this calculator + // first to get the labels. auto& tensor_to_images = graph.AddNode("mediapipe.tasks.TensorsToSegmentationCalculator"); RET_CHECK_OK(ConfigureTensorsToSegmentationCalculator( task_options, model_resources, &tensor_to_images .GetOptions())); + const auto& tensor_to_images_options = + tensor_to_images.GetOptions(); + + // TODO: remove special logic for hair segmentation model. + // The alpha channel of hair segmentation model indicates the interested + // area. The model was designed for live stream mode, so that the mask of + // previous frame is used as the indicator for the next frame. For the first + // frame, it expects the alpha channel to be empty. To consolidate IMAGE, + // VIDEO and LIVE_STREAM mode in mediapipe tasks, here we forcely set the + // alpha channel to be empty if we find the model is the hair segmentation + // model. + bool is_hair_segmentation = false; + if (tensor_to_images_options.label_items_size() == 2 && + tensor_to_images_options.label_items().at(1).name() == "hair") { + is_hair_segmentation = true; + } + + ASSIGN_OR_RETURN( + auto image_and_tensors, + ConvertImageToTensors(image_in, norm_rect_in, use_gpu, + is_hair_segmentation, model_resources, graph)); + // Adds inference subgraph and connects its input stream to the output + // tensors produced by the ImageToTensorCalculator. + auto& inference = AddInference( + model_resources, task_options.base_options().acceleration(), graph); + image_and_tensors.tensors >> inference.In(kTensorsTag); inference.Out(kTensorsTag) >> tensor_to_images.In(kTensorsTag); // Adds image property calculator for output size. diff --git a/third_party/external_files.bzl b/third_party/external_files.bzl index af9361bb3..599248f48 100644 --- a/third_party/external_files.bzl +++ b/third_party/external_files.bzl @@ -204,8 +204,8 @@ def external_files(): http_file( name = "com_google_mediapipe_conv2d_input_channel_1_tflite", - sha256 = "126edac445967799f3b8b124d15483b1506f6d6cb57a501c1636eb8f2fb3734f", - urls = ["https://storage.googleapis.com/mediapipe-assets/conv2d_input_channel_1.tflite?generation=1678218348519744"], + sha256 = "ccb667092f3aed3a35a57fb3478fecc0c8f6360dbf477a9db9c24e5b3ec4273e", + urls = ["https://storage.googleapis.com/mediapipe-assets/conv2d_input_channel_1.tflite?generation=1683252905577703"], ) http_file( @@ -246,8 +246,8 @@ def external_files(): http_file( name = "com_google_mediapipe_dense_tflite", - sha256 = "be9323068461b1cbf412692ee916be30dcb1a5fb59a9ee875d470bc340d9e869", - urls = ["https://storage.googleapis.com/mediapipe-assets/dense.tflite?generation=1678218351373709"], + sha256 = "6795e7c3a263f44e97be048a5e1166e0921b453bfbaf037f4f69ac5c059ee945", + urls = ["https://storage.googleapis.com/mediapipe-assets/dense.tflite?generation=1683252907920466"], ) http_file( From ecc8dca8ba160157cf23ed7c82773de2a73eba88 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Fri, 5 May 2023 10:26:29 -0700 Subject: [PATCH 211/753] Internal change PiperOrigin-RevId: 529752098 --- mediapipe/framework/BUILD | 4 +++- mediapipe/framework/profiler/testing/BUILD | 4 +--- mediapipe/model_maker/models/gesture_recognizer/BUILD | 4 +--- mediapipe/model_maker/models/text_classifier/BUILD | 4 +--- mediapipe/model_maker/python/core/BUILD | 4 +--- mediapipe/model_maker/python/core/data/BUILD | 4 +--- mediapipe/model_maker/python/core/tasks/BUILD | 4 +--- mediapipe/model_maker/python/core/utils/BUILD | 4 +--- mediapipe/model_maker/python/text/core/BUILD | 4 +--- mediapipe/model_maker/python/text/text_classifier/BUILD | 4 +--- mediapipe/model_maker/python/vision/BUILD | 4 +--- mediapipe/model_maker/python/vision/gesture_recognizer/BUILD | 4 +--- mediapipe/model_maker/python/vision/image_classifier/BUILD | 4 +--- mediapipe/model_maker/python/vision/object_detector/BUILD | 4 +--- 14 files changed, 16 insertions(+), 40 deletions(-) diff --git a/mediapipe/framework/BUILD b/mediapipe/framework/BUILD index ae788ed58..126261c90 100644 --- a/mediapipe/framework/BUILD +++ b/mediapipe/framework/BUILD @@ -33,7 +33,9 @@ bzl_library( srcs = [ "transitive_protos.bzl", ], - visibility = ["//mediapipe/framework:__subpackages__"], + visibility = [ + "//mediapipe/framework:__subpackages__", + ], ) bzl_library( diff --git a/mediapipe/framework/profiler/testing/BUILD b/mediapipe/framework/profiler/testing/BUILD index 0b0d256e5..67668ef7d 100644 --- a/mediapipe/framework/profiler/testing/BUILD +++ b/mediapipe/framework/profiler/testing/BUILD @@ -15,9 +15,7 @@ licenses(["notice"]) -package( - default_visibility = ["//mediapipe/framework:__subpackages__"], -) +package(default_visibility = ["//mediapipe/framework:__subpackages__"]) cc_library( name = "simple_calculator", diff --git a/mediapipe/model_maker/models/gesture_recognizer/BUILD b/mediapipe/model_maker/models/gesture_recognizer/BUILD index 947508f1b..c57d7a2c9 100644 --- a/mediapipe/model_maker/models/gesture_recognizer/BUILD +++ b/mediapipe/model_maker/models/gesture_recognizer/BUILD @@ -19,9 +19,7 @@ load( licenses(["notice"]) -package( - default_visibility = ["//mediapipe/model_maker/python/vision/gesture_recognizer:__subpackages__"], -) +package(default_visibility = ["//mediapipe/model_maker/python/vision/gesture_recognizer:__subpackages__"]) mediapipe_files( srcs = [ diff --git a/mediapipe/model_maker/models/text_classifier/BUILD b/mediapipe/model_maker/models/text_classifier/BUILD index d9d55048d..460d6cfd1 100644 --- a/mediapipe/model_maker/models/text_classifier/BUILD +++ b/mediapipe/model_maker/models/text_classifier/BUILD @@ -19,9 +19,7 @@ load( licenses(["notice"]) -package( - default_visibility = ["//mediapipe/model_maker/python/text/text_classifier:__subpackages__"], -) +package(default_visibility = ["//mediapipe/model_maker/python/text/text_classifier:__subpackages__"]) mediapipe_files( srcs = [ diff --git a/mediapipe/model_maker/python/core/BUILD b/mediapipe/model_maker/python/core/BUILD index 6331e638e..0ed20a2fe 100644 --- a/mediapipe/model_maker/python/core/BUILD +++ b/mediapipe/model_maker/python/core/BUILD @@ -14,9 +14,7 @@ # Placeholder for internal Python strict library and test compatibility macro. -package( - default_visibility = ["//mediapipe:__subpackages__"], -) +package(default_visibility = ["//mediapipe:__subpackages__"]) licenses(["notice"]) diff --git a/mediapipe/model_maker/python/core/data/BUILD b/mediapipe/model_maker/python/core/data/BUILD index cc0381f60..1c2fb7a44 100644 --- a/mediapipe/model_maker/python/core/data/BUILD +++ b/mediapipe/model_maker/python/core/data/BUILD @@ -17,9 +17,7 @@ licenses(["notice"]) -package( - default_visibility = ["//mediapipe:__subpackages__"], -) +package(default_visibility = ["//mediapipe:__subpackages__"]) py_library( name = "data_util", diff --git a/mediapipe/model_maker/python/core/tasks/BUILD b/mediapipe/model_maker/python/core/tasks/BUILD index 6a3e60c97..818d78feb 100644 --- a/mediapipe/model_maker/python/core/tasks/BUILD +++ b/mediapipe/model_maker/python/core/tasks/BUILD @@ -15,9 +15,7 @@ # Placeholder for internal Python strict library and test compatibility macro. # Placeholder for internal Python strict test compatibility macro. -package( - default_visibility = ["//mediapipe:__subpackages__"], -) +package(default_visibility = ["//mediapipe:__subpackages__"]) licenses(["notice"]) diff --git a/mediapipe/model_maker/python/core/utils/BUILD b/mediapipe/model_maker/python/core/utils/BUILD index e86cbb1e3..ef9cab290 100644 --- a/mediapipe/model_maker/python/core/utils/BUILD +++ b/mediapipe/model_maker/python/core/utils/BUILD @@ -17,9 +17,7 @@ licenses(["notice"]) -package( - default_visibility = ["//mediapipe:__subpackages__"], -) +package(default_visibility = ["//mediapipe:__subpackages__"]) py_library( name = "test_util", diff --git a/mediapipe/model_maker/python/text/core/BUILD b/mediapipe/model_maker/python/text/core/BUILD index 3ba4e8e6e..d99f46b77 100644 --- a/mediapipe/model_maker/python/text/core/BUILD +++ b/mediapipe/model_maker/python/text/core/BUILD @@ -14,9 +14,7 @@ # Placeholder for internal Python strict library and test compatibility macro. -package( - default_visibility = ["//mediapipe:__subpackages__"], -) +package(default_visibility = ["//mediapipe:__subpackages__"]) licenses(["notice"]) diff --git a/mediapipe/model_maker/python/text/text_classifier/BUILD b/mediapipe/model_maker/python/text/text_classifier/BUILD index 1ae3e2873..9fe96849b 100644 --- a/mediapipe/model_maker/python/text/text_classifier/BUILD +++ b/mediapipe/model_maker/python/text/text_classifier/BUILD @@ -15,9 +15,7 @@ # Placeholder for internal Python strict library and test compatibility macro. # Placeholder for internal Python strict test compatibility macro. -package( - default_visibility = ["//mediapipe:__subpackages__"], -) +package(default_visibility = ["//mediapipe:__subpackages__"]) licenses(["notice"]) diff --git a/mediapipe/model_maker/python/vision/BUILD b/mediapipe/model_maker/python/vision/BUILD index 4410d859f..b7d0d13a6 100644 --- a/mediapipe/model_maker/python/vision/BUILD +++ b/mediapipe/model_maker/python/vision/BUILD @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -package( - default_visibility = ["//mediapipe:__subpackages__"], -) +package(default_visibility = ["//mediapipe:__subpackages__"]) licenses(["notice"]) diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/BUILD b/mediapipe/model_maker/python/vision/gesture_recognizer/BUILD index 578723fb0..27f8934b3 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/BUILD +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/BUILD @@ -17,9 +17,7 @@ licenses(["notice"]) -package( - default_visibility = ["//mediapipe:__subpackages__"], -) +package(default_visibility = ["//mediapipe:__subpackages__"]) # TODO: Remove the unnecessary test data once the demo data are moved to an open-sourced # directory. diff --git a/mediapipe/model_maker/python/vision/image_classifier/BUILD b/mediapipe/model_maker/python/vision/image_classifier/BUILD index 3b6d7551a..73d1d2f7c 100644 --- a/mediapipe/model_maker/python/vision/image_classifier/BUILD +++ b/mediapipe/model_maker/python/vision/image_classifier/BUILD @@ -17,9 +17,7 @@ licenses(["notice"]) -package( - default_visibility = ["//mediapipe:__subpackages__"], -) +package(default_visibility = ["//mediapipe:__subpackages__"]) ###################################################################### # Public target of the MediaPipe Model Maker ImageClassifier APIs. diff --git a/mediapipe/model_maker/python/vision/object_detector/BUILD b/mediapipe/model_maker/python/vision/object_detector/BUILD index d8177a083..75c08dbc8 100644 --- a/mediapipe/model_maker/python/vision/object_detector/BUILD +++ b/mediapipe/model_maker/python/vision/object_detector/BUILD @@ -17,9 +17,7 @@ licenses(["notice"]) -package( - default_visibility = ["//mediapipe:__subpackages__"], -) +package(default_visibility = ["//mediapipe:__subpackages__"]) py_library( name = "object_detector_import", From f065910559c6883f78ef085418f49a674e4abad8 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 5 May 2023 13:26:29 -0700 Subject: [PATCH 212/753] Create non-callback APIs for APIs that return callbacks. PiperOrigin-RevId: 529799515 --- mediapipe/tasks/web/vision/core/image.ts | 8 +- .../web/vision/core/vision_task_runner.ts | 12 +- .../web/vision/face_stylizer/face_stylizer.ts | 173 ++++++++++++++---- .../face_stylizer/face_stylizer_test.ts | 47 ++--- .../vision/image_segmenter/image_segmenter.ts | 94 ++++++++-- .../image_segmenter/image_segmenter_test.ts | 17 ++ .../interactive_segmenter.ts | 84 ++++++--- .../interactive_segmenter_test.ts | 18 ++ .../vision/pose_landmarker/pose_landmarker.ts | 122 +++++++++--- .../pose_landmarker/pose_landmarker_test.ts | 22 +++ 10 files changed, 465 insertions(+), 132 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index e2b21c0e6..df7586ded 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -273,9 +273,13 @@ export class MPImage { case MPImageType.IMAGE_DATA: return this.containers.find(img => img instanceof ImageData); case MPImageType.IMAGE_BITMAP: - return this.containers.find(img => img instanceof ImageBitmap); + return this.containers.find( + img => typeof ImageBitmap !== 'undefined' && + img instanceof ImageBitmap); case MPImageType.WEBGL_TEXTURE: - return this.containers.find(img => img instanceof WebGLTexture); + return this.containers.find( + img => typeof WebGLTexture !== 'undefined' && + img instanceof WebGLTexture); default: throw new Error(`Type is not supported: ${type}`); } diff --git a/mediapipe/tasks/web/vision/core/vision_task_runner.ts b/mediapipe/tasks/web/vision/core/vision_task_runner.ts index 3ff6e0604..c31195508 100644 --- a/mediapipe/tasks/web/vision/core/vision_task_runner.ts +++ b/mediapipe/tasks/web/vision/core/vision_task_runner.ts @@ -230,7 +230,8 @@ export abstract class VisionTaskRunner extends TaskRunner { * (adding an alpha channel if necessary), passes through WebGLTextures and * throws for Float32Array-backed images. */ - protected convertToMPImage(wasmImage: WasmImage): MPImage { + protected convertToMPImage(wasmImage: WasmImage, shouldCopyData: boolean): + MPImage { const {data, width, height} = wasmImage; const pixels = width * height; @@ -263,10 +264,11 @@ export abstract class VisionTaskRunner extends TaskRunner { container = data; } - return new MPImage( - [container], /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, - this.graphRunner.wasmModule.canvas!, this.shaderContext, width, - height); + const image = new MPImage( + [container], /* ownsImageBitmap= */ false, + /* ownsWebGLTexture= */ false, this.graphRunner.wasmModule.canvas!, + this.shaderContext, width, height); + return shouldCopyData ? image.clone() : image; } /** Closes and cleans up the resources held by this task. */ diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts index 2a9adb315..641ab61d2 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts @@ -50,7 +50,8 @@ export type FaceStylizerCallback = (image: MPImage|null) => void; /** Performs face stylization on images. */ export class FaceStylizer extends VisionTaskRunner { - private userCallback: FaceStylizerCallback = () => {}; + private userCallback?: FaceStylizerCallback; + private result?: MPImage|null; private readonly options: FaceStylizerGraphOptionsProto; /** @@ -130,21 +131,58 @@ export class FaceStylizer extends VisionTaskRunner { return super.applyOptions(options); } - /** - * Performs face stylization on the provided single image. The method returns - * synchronously once the callback returns. Only use this method when the - * FaceStylizer is created with the image running mode. + * Performs face stylization on the provided single image and invokes the + * callback with result. The method returns synchronously once the callback + * returns. Only use this method when the FaceStylizer is created with the + * image running mode. * * @param image An image to process. - * @param callback The callback that is invoked with the stylized image. The - * lifetime of the returned data is only guaranteed for the duration of the - * callback. + * @param callback The callback that is invoked with the stylized image or + * `null` if no face was detected. The lifetime of the returned data is + * only guaranteed for the duration of the callback. */ stylize(image: ImageSource, callback: FaceStylizerCallback): void; /** - * Performs face stylization on the provided single image. The method returns - * synchronously once the callback returns. Only use this method when the + * Performs face stylization on the provided single image and invokes the + * callback with result. The method returns synchronously once the callback + * returns. Only use this method when the FaceStylizer is created with the + * image running mode. + * + * The 'imageProcessingOptions' parameter can be used to specify one or all + * of: + * - the rotation to apply to the image before performing stylization, by + * setting its 'rotationDegrees' property. + * - the region-of-interest on which to perform stylization, by setting its + * 'regionOfInterest' property. If not specified, the full image is used. + * If both are specified, the crop around the region-of-interest is extracted + * first, then the specified rotation is applied to the crop. + * + * @param image An image to process. + * @param imageProcessingOptions the `ImageProcessingOptions` specifying how + * to process the input image before running inference. + * @param callback The callback that is invoked with the stylized image or + * `null` if no face was detected. The lifetime of the returned data is + * only guaranteed for the duration of the callback. + */ + stylize( + image: ImageSource, imageProcessingOptions: ImageProcessingOptions, + callback: FaceStylizerCallback): void; + /** + * Performs face stylization on the provided single image and returns the + * result. This method creates a copy of the resulting image and should not be + * used in high-throughput applictions. Only use this method when the + * FaceStylizer is created with the image running mode. + * + * @param image An image to process. + * @return A stylized face or `null` if no face was detected. The result is + * copied to avoid lifetime issues. + */ + stylize(image: ImageSource): MPImage|null; + /** + * Performs face stylization on the provided single image and returns the + * result. This method creates a copy of the resulting image and should not be + * used in high-throughput applictions. Only use this method when the * FaceStylizer is created with the image running mode. * * The 'imageProcessingOptions' parameter can be used to specify one or all @@ -159,18 +197,16 @@ export class FaceStylizer extends VisionTaskRunner { * @param image An image to process. * @param imageProcessingOptions the `ImageProcessingOptions` specifying how * to process the input image before running inference. - * @param callback The callback that is invoked with the stylized image. The - * lifetime of the returned data is only guaranteed for the duration of the - * callback. + * @return A stylized face or `null` if no face was detected. The result is + * copied to avoid lifetime issues. */ - stylize( - image: ImageSource, imageProcessingOptions: ImageProcessingOptions, - callback: FaceStylizerCallback): void; + stylize(image: ImageSource, imageProcessingOptions: ImageProcessingOptions): + MPImage|null; stylize( image: ImageSource, - imageProcessingOptionsOrCallback: ImageProcessingOptions| + imageProcessingOptionsOrCallback?: ImageProcessingOptions| FaceStylizerCallback, - callback?: FaceStylizerCallback): void { + callback?: FaceStylizerCallback): MPImage|null|void { const imageProcessingOptions = typeof imageProcessingOptionsOrCallback !== 'function' ? imageProcessingOptionsOrCallback : @@ -178,14 +214,19 @@ export class FaceStylizer extends VisionTaskRunner { this.userCallback = typeof imageProcessingOptionsOrCallback === 'function' ? imageProcessingOptionsOrCallback : - callback!; + callback; this.processImageData(image, imageProcessingOptions ?? {}); - this.userCallback = () => {}; + + if (!this.userCallback) { + return this.result; + } } /** - * Performs face stylization on the provided video frame. Only use this method - * when the FaceStylizer is created with the video running mode. + * Performs face stylization on the provided video frame and invokes the + * callback with result. The method returns synchronously once the callback + * returns. Only use this method when the FaceStylizer is created with the + * video running mode. * * The input frame can be of any size. It's required to provide the video * frame's timestamp (in milliseconds). The input timestamps must be @@ -193,16 +234,18 @@ export class FaceStylizer extends VisionTaskRunner { * * @param videoFrame A video frame to process. * @param timestamp The timestamp of the current frame, in ms. - * @param callback The callback that is invoked with the stylized image. The - * lifetime of the returned data is only guaranteed for the duration of - * the callback. + * @param callback The callback that is invoked with the stylized image or + * `null` if no face was detected. The lifetime of the returned data is only + * guaranteed for the duration of the callback. */ stylizeForVideo( videoFrame: ImageSource, timestamp: number, callback: FaceStylizerCallback): void; /** - * Performs face stylization on the provided video frame. Only use this - * method when the FaceStylizer is created with the video running mode. + * Performs face stylization on the provided video frame and invokes the + * callback with result. The method returns synchronously once the callback + * returns. Only use this method when the FaceStylizer is created with the + * video running mode. * * The 'imageProcessingOptions' parameter can be used to specify one or all * of: @@ -221,18 +264,63 @@ export class FaceStylizer extends VisionTaskRunner { * @param imageProcessingOptions the `ImageProcessingOptions` specifying how * to process the input image before running inference. * @param timestamp The timestamp of the current frame, in ms. - * @param callback The callback that is invoked with the stylized image. The - * lifetime of the returned data is only guaranteed for the duration of - * the callback. + * @param callback The callback that is invoked with the stylized image or + * `null` if no face was detected. The lifetime of the returned data is only + * guaranteed for the duration of the callback. */ stylizeForVideo( videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, timestamp: number, callback: FaceStylizerCallback): void; + /** + * Performs face stylization on the provided video frame. This method creates + * a copy of the resulting image and should not be used in high-throughput + * applictions. Only use this method when the FaceStylizer is created with the + * video running mode. + * + * The input frame can be of any size. It's required to provide the video + * frame's timestamp (in milliseconds). The input timestamps must be + * monotonically increasing. + * + * @param videoFrame A video frame to process. + * @param timestamp The timestamp of the current frame, in ms. + * @return A stylized face or `null` if no face was detected. The result is + * copied to avoid lifetime issues. + */ + stylizeForVideo(videoFrame: ImageSource, timestamp: number): MPImage|null; + /** + * Performs face stylization on the provided video frame. This method creates + * a copy of the resulting image and should not be used in high-throughput + * applictions. Only use this method when the FaceStylizer is created with the + * video running mode. + * + * The 'imageProcessingOptions' parameter can be used to specify one or all + * of: + * - the rotation to apply to the image before performing stylization, by + * setting its 'rotationDegrees' property. + * - the region-of-interest on which to perform stylization, by setting its + * 'regionOfInterest' property. If not specified, the full image is used. + * If both are specified, the crop around the region-of-interest is + * extracted first, then the specified rotation is applied to the crop. + * + * The input frame can be of any size. It's required to provide the video + * frame's timestamp (in milliseconds). The input timestamps must be + * monotonically increasing. + * + * @param videoFrame A video frame to process. + * @param imageProcessingOptions the `ImageProcessingOptions` specifying how + * to process the input image before running inference. + * @param timestamp The timestamp of the current frame, in ms. + * @return A stylized face or `null` if no face was detected. The result is + * copied to avoid lifetime issues. + */ + stylizeForVideo( + videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, + timestamp: number): MPImage|null; stylizeForVideo( videoFrame: ImageSource, timestampOrImageProcessingOptions: number|ImageProcessingOptions, - timestampOrCallback: number|FaceStylizerCallback, - callback?: FaceStylizerCallback): void { + timestampOrCallback?: number|FaceStylizerCallback, + callback?: FaceStylizerCallback): MPImage|null|void { const imageProcessingOptions = typeof timestampOrImageProcessingOptions !== 'number' ? timestampOrImageProcessingOptions : @@ -243,9 +331,13 @@ export class FaceStylizer extends VisionTaskRunner { this.userCallback = typeof timestampOrCallback === 'function' ? timestampOrCallback : - callback!; + callback; this.processVideoData(videoFrame, imageProcessingOptions, timestamp); - this.userCallback = () => {}; + this.userCallback = undefined; + + if (!this.userCallback) { + return this.result; + } } /** Updates the MediaPipe graph configuration. */ @@ -270,13 +362,20 @@ export class FaceStylizer extends VisionTaskRunner { this.graphRunner.attachImageListener( STYLIZED_IMAGE_STREAM, (wasmImage, timestamp) => { - const mpImage = this.convertToMPImage(wasmImage); - this.userCallback(mpImage); + const mpImage = this.convertToMPImage( + wasmImage, /* shouldCopyData= */ !this.userCallback); + this.result = mpImage; + if (this.userCallback) { + this.userCallback(mpImage); + } this.setLatestOutputTimestamp(timestamp); }); this.graphRunner.attachEmptyPacketListener( STYLIZED_IMAGE_STREAM, timestamp => { - this.userCallback(null); + this.result = null; + if (this.userCallback) { + this.userCallback(null); + } this.setLatestOutputTimestamp(timestamp); }); diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts index 17764c9e5..8ea8e0f94 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts @@ -99,6 +99,30 @@ describe('FaceStylizer', () => { ]); }); + it('returns result', () => { + if (typeof ImageData === 'undefined') { + console.log('ImageData tests are not supported on Node'); + return; + } + + // Pass the test data to our listener + faceStylizer.fakeWasmModule._waitUntilIdle.and.callFake(() => { + verifyListenersRegistered(faceStylizer); + faceStylizer.imageListener! + ({data: new Uint8ClampedArray([1, 1, 1, 1]), width: 1, height: 1}, + /* timestamp= */ 1337); + }); + + // Invoke the face stylizeer + const image = faceStylizer.stylize({} as HTMLImageElement); + expect(faceStylizer.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); + expect(image).not.toBeNull(); + expect(image!.has(MPImage.TYPE.IMAGE_DATA)).toBeTrue(); + expect(image!.width).toEqual(1); + expect(image!.height).toEqual(1); + image!.close(); + }); + it('invokes callback', (done) => { if (typeof ImageData === 'undefined') { console.log('ImageData tests are not supported on Node'); @@ -125,28 +149,7 @@ describe('FaceStylizer', () => { }); }); - it('invokes callback even when no faes are detected', (done) => { - if (typeof ImageData === 'undefined') { - console.log('ImageData tests are not supported on Node'); - done(); - return; - } - - // Pass the test data to our listener - faceStylizer.fakeWasmModule._waitUntilIdle.and.callFake(() => { - verifyListenersRegistered(faceStylizer); - faceStylizer.emptyPacketListener!(/* timestamp= */ 1337); - }); - - // Invoke the face stylizeer - faceStylizer.stylize({} as HTMLImageElement, image => { - expect(faceStylizer.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); - expect(image).toBeNull(); - done(); - }); - }); - - it('invokes callback even when no faes are detected', (done) => { + it('invokes callback even when no faces are detected', (done) => { // Pass the test data to our listener faceStylizer.fakeWasmModule._waitUntilIdle.and.callFake(() => { verifyListenersRegistered(faceStylizer); diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts index 60b965345..4d0ac18f2 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts @@ -60,7 +60,7 @@ export type ImageSegmenterCallback = (result: ImageSegmenterResult) => void; export class ImageSegmenter extends VisionTaskRunner { private result: ImageSegmenterResult = {}; private labels: string[] = []; - private userCallback: ImageSegmenterCallback = () => {}; + private userCallback?: ImageSegmenterCallback; private outputCategoryMask = DEFAULT_OUTPUT_CATEGORY_MASK; private outputConfidenceMasks = DEFAULT_OUTPUT_CONFIDENCE_MASKS; private readonly options: ImageSegmenterGraphOptionsProto; @@ -224,22 +224,51 @@ export class ImageSegmenter extends VisionTaskRunner { segment( image: ImageSource, imageProcessingOptions: ImageProcessingOptions, callback: ImageSegmenterCallback): void; + /** + * Performs image segmentation on the provided single image and returns the + * segmentation result. This method creates a copy of the resulting masks and + * should not be used in high-throughput applictions. Only use this method + * when the ImageSegmenter is created with running mode `image`. + * + * @param image An image to process. + * @return The segmentation result. The data is copied to avoid lifetime + * issues. + */ + segment(image: ImageSource): ImageSegmenterResult; + /** + * Performs image segmentation on the provided single image and returns the + * segmentation result. This method creates a copy of the resulting masks and + * should not be used in high-v applictions. Only use this method when + * the ImageSegmenter is created with running mode `image`. + * + * @param image An image to process. + * @param imageProcessingOptions the `ImageProcessingOptions` specifying how + * to process the input image before running inference. + * @return The segmentation result. The data is copied to avoid lifetime + * issues. + */ + segment(image: ImageSource, imageProcessingOptions: ImageProcessingOptions): + ImageSegmenterResult; segment( image: ImageSource, - imageProcessingOptionsOrCallback: ImageProcessingOptions| + imageProcessingOptionsOrCallback?: ImageProcessingOptions| ImageSegmenterCallback, - callback?: ImageSegmenterCallback): void { + callback?: ImageSegmenterCallback): ImageSegmenterResult|void { const imageProcessingOptions = typeof imageProcessingOptionsOrCallback !== 'function' ? imageProcessingOptionsOrCallback : {}; + this.userCallback = typeof imageProcessingOptionsOrCallback === 'function' ? imageProcessingOptionsOrCallback : - callback!; + callback; this.reset(); this.processImageData(image, imageProcessingOptions); - this.userCallback = () => {}; + + if (!this.userCallback) { + return this.result; + } } /** @@ -265,7 +294,7 @@ export class ImageSegmenter extends VisionTaskRunner { * * @param videoFrame A video frame to process. * @param imageProcessingOptions the `ImageProcessingOptions` specifying how - * to process the input image before running inference. + * to process the input frame before running inference. * @param timestamp The timestamp of the current frame, in ms. * @param callback The callback that is invoked with the segmented masks. The * lifetime of the returned data is only guaranteed for the duration of the @@ -274,11 +303,41 @@ export class ImageSegmenter extends VisionTaskRunner { segmentForVideo( videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, timestamp: number, callback: ImageSegmenterCallback): void; + /** + * Performs image segmentation on the provided video frame and returns the + * segmentation result. This method creates a copy of the resulting masks and + * should not be used in high-throughput applictions. Only use this method + * when the ImageSegmenter is created with running mode `video`. + * + * @param videoFrame A video frame to process. + * @return The segmentation result. The data is copied to avoid lifetime + * issues. + */ + segmentForVideo(videoFrame: ImageSource, timestamp: number): + ImageSegmenterResult; + /** + * Performs image segmentation on the provided video frame and returns the + * segmentation result. This method creates a copy of the resulting masks and + * should not be used in high-v applictions. Only use this method when + * the ImageSegmenter is created with running mode `video`. + * + * @param videoFrame A video frame to process. + * @param imageProcessingOptions the `ImageProcessingOptions` specifying how + * to process the input frame before running inference. + * @param timestamp The timestamp of the current frame, in ms. + * @return The segmentation result. The data is copied to avoid lifetime + * issues. + */ + segmentForVideo( + videoFrame: ImageSource, + imageProcessingOptions: ImageProcessingOptions, + timestamp: number, + ): ImageSegmenterResult; segmentForVideo( videoFrame: ImageSource, timestampOrImageProcessingOptions: number|ImageProcessingOptions, - timestampOrCallback: number|ImageSegmenterCallback, - callback?: ImageSegmenterCallback): void { + timestampOrCallback?: number|ImageSegmenterCallback, + callback?: ImageSegmenterCallback): ImageSegmenterResult|void { const imageProcessingOptions = typeof timestampOrImageProcessingOptions !== 'number' ? timestampOrImageProcessingOptions : @@ -288,11 +347,14 @@ export class ImageSegmenter extends VisionTaskRunner { timestampOrCallback as number; this.userCallback = typeof timestampOrCallback === 'function' ? timestampOrCallback : - callback!; + callback; this.reset(); this.processVideoData(videoFrame, imageProcessingOptions, timestamp); - this.userCallback = () => {}; + + if (!this.userCallback) { + return this.result; + } } /** @@ -323,7 +385,9 @@ export class ImageSegmenter extends VisionTaskRunner { return; } - this.userCallback(this.result); + if (this.userCallback) { + this.userCallback(this.result); + } } /** Updates the MediaPipe graph configuration. */ @@ -351,8 +415,9 @@ export class ImageSegmenter extends VisionTaskRunner { this.graphRunner.attachImageVectorListener( CONFIDENCE_MASKS_STREAM, (masks, timestamp) => { - this.result.confidenceMasks = - masks.map(wasmImage => this.convertToMPImage(wasmImage)); + this.result.confidenceMasks = masks.map( + wasmImage => this.convertToMPImage( + wasmImage, /* shouldCopyData= */ !this.userCallback)); this.setLatestOutputTimestamp(timestamp); this.maybeInvokeCallback(); }); @@ -370,7 +435,8 @@ export class ImageSegmenter extends VisionTaskRunner { this.graphRunner.attachImageListener( CATEGORY_MASK_STREAM, (mask, timestamp) => { - this.result.categoryMask = this.convertToMPImage(mask); + this.result.categoryMask = this.convertToMPImage( + mask, /* shouldCopyData= */ !this.userCallback); this.setLatestOutputTimestamp(timestamp); this.maybeInvokeCallback(); }); diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts index 8c8767ec7..f9a4fe8a6 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts @@ -292,4 +292,21 @@ describe('ImageSegmenter', () => { }); }); }); + + it('returns result', () => { + const confidenceMask = new Float32Array([0.0]); + + // Pass the test data to our listener + imageSegmenter.fakeWasmModule._waitUntilIdle.and.callFake(() => { + imageSegmenter.confidenceMasksListener!( + [ + {data: confidenceMask, width: 1, height: 1}, + ], + 1337); + }); + + const result = imageSegmenter.segment({} as HTMLImageElement); + expect(result.confidenceMasks![0]).toBeInstanceOf(MPImage); + result.confidenceMasks![0].close(); + }); }); diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts index 60ec9e1c5..72dfd3834 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts @@ -86,7 +86,7 @@ export class InteractiveSegmenter extends VisionTaskRunner { private result: InteractiveSegmenterResult = {}; private outputCategoryMask = DEFAULT_OUTPUT_CATEGORY_MASK; private outputConfidenceMasks = DEFAULT_OUTPUT_CONFIDENCE_MASKS; - private userCallback: InteractiveSegmenterCallback = () => {}; + private userCallback?: InteractiveSegmenterCallback; private readonly options: ImageSegmenterGraphOptionsProto; private readonly segmenterOptions: SegmenterOptionsProto; @@ -186,14 +186,9 @@ export class InteractiveSegmenter extends VisionTaskRunner { /** * Performs interactive segmentation on the provided single image and invokes - * the callback with the response. The `roi` parameter is used to represent a - * user's region of interest for segmentation. - * - * If the output_type is `CATEGORY_MASK`, the callback is invoked with vector - * of images that represent per-category segmented image mask. If the - * output_type is `CONFIDENCE_MASK`, the callback is invoked with a vector of - * images that contains only one confidence image mask. The method returns - * synchronously once the callback returns. + * the callback with the response. The method returns synchronously once the + * callback returns. The `roi` parameter is used to represent a user's region + * of interest for segmentation. * * @param image An image to process. * @param roi The region of interest for segmentation. @@ -206,8 +201,9 @@ export class InteractiveSegmenter extends VisionTaskRunner { callback: InteractiveSegmenterCallback): void; /** * Performs interactive segmentation on the provided single image and invokes - * the callback with the response. The `roi` parameter is used to represent a - * user's region of interest for segmentation. + * the callback with the response. The method returns synchronously once the + * callback returns. The `roi` parameter is used to represent a user's region + * of interest for segmentation. * * The 'image_processing_options' parameter can be used to specify the * rotation to apply to the image before performing segmentation, by setting @@ -215,12 +211,6 @@ export class InteractiveSegmenter extends VisionTaskRunner { * using the 'regionOfInterest' field is NOT supported and will result in an * error. * - * If the output_type is `CATEGORY_MASK`, the callback is invoked with vector - * of images that represent per-category segmented image mask. If the - * output_type is `CONFIDENCE_MASK`, the callback is invoked with a vector of - * images that contains only one confidence image mask. The method returns - * synchronously once the callback returns. - * * @param image An image to process. * @param roi The region of interest for segmentation. * @param imageProcessingOptions the `ImageProcessingOptions` specifying how @@ -233,23 +223,63 @@ export class InteractiveSegmenter extends VisionTaskRunner { image: ImageSource, roi: RegionOfInterest, imageProcessingOptions: ImageProcessingOptions, callback: InteractiveSegmenterCallback): void; + /** + * Performs interactive segmentation on the provided video frame and returns + * the segmentation result. This method creates a copy of the resulting masks + * and should not be used in high-throughput applictions. The `roi` parameter + * is used to represent a user's region of interest for segmentation. + * + * @param image An image to process. + * @param roi The region of interest for segmentation. + * @return The segmentation result. The data is copied to avoid lifetime + * limits. + */ + segment(image: ImageSource, roi: RegionOfInterest): + InteractiveSegmenterResult; + /** + * Performs interactive segmentation on the provided video frame and returns + * the segmentation result. This method creates a copy of the resulting masks + * and should not be used in high-throughput applictions. The `roi` parameter + * is used to represent a user's region of interest for segmentation. + * + * The 'image_processing_options' parameter can be used to specify the + * rotation to apply to the image before performing segmentation, by setting + * its 'rotationDegrees' field. Note that specifying a region-of-interest + * using the 'regionOfInterest' field is NOT supported and will result in an + * error. + * + * @param image An image to process. + * @param roi The region of interest for segmentation. + * @param imageProcessingOptions the `ImageProcessingOptions` specifying how + * to process the input image before running inference. + * @return The segmentation result. The data is copied to avoid lifetime + * limits. + */ segment( image: ImageSource, roi: RegionOfInterest, - imageProcessingOptionsOrCallback: ImageProcessingOptions| + imageProcessingOptions: ImageProcessingOptions): + InteractiveSegmenterResult; + segment( + image: ImageSource, roi: RegionOfInterest, + imageProcessingOptionsOrCallback?: ImageProcessingOptions| InteractiveSegmenterCallback, - callback?: InteractiveSegmenterCallback): void { + callback?: InteractiveSegmenterCallback): InteractiveSegmenterResult| + void { const imageProcessingOptions = typeof imageProcessingOptionsOrCallback !== 'function' ? imageProcessingOptionsOrCallback : {}; this.userCallback = typeof imageProcessingOptionsOrCallback === 'function' ? imageProcessingOptionsOrCallback : - callback!; + callback; this.reset(); this.processRenderData(roi, this.getSynctheticTimestamp()); this.processImageData(image, imageProcessingOptions); - this.userCallback = () => {}; + + if (!this.userCallback) { + return this.result; + } } private reset(): void { @@ -265,7 +295,9 @@ export class InteractiveSegmenter extends VisionTaskRunner { return; } - this.userCallback(this.result); + if (this.userCallback) { + this.userCallback(this.result); + } } /** Updates the MediaPipe graph configuration. */ @@ -295,8 +327,9 @@ export class InteractiveSegmenter extends VisionTaskRunner { this.graphRunner.attachImageVectorListener( CONFIDENCE_MASKS_STREAM, (masks, timestamp) => { - this.result.confidenceMasks = - masks.map(wasmImage => this.convertToMPImage(wasmImage)); + this.result.confidenceMasks = masks.map( + wasmImage => this.convertToMPImage( + wasmImage, /* shouldCopyData= */ !this.userCallback)); this.setLatestOutputTimestamp(timestamp); this.maybeInvokeCallback(); }); @@ -314,7 +347,8 @@ export class InteractiveSegmenter extends VisionTaskRunner { this.graphRunner.attachImageListener( CATEGORY_MASK_STREAM, (mask, timestamp) => { - this.result.categoryMask = this.convertToMPImage(mask); + this.result.categoryMask = this.convertToMPImage( + mask, /* shouldCopyData= */ !this.userCallback); this.setLatestOutputTimestamp(timestamp); this.maybeInvokeCallback(); }); diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts index a361af5a1..52742e371 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts @@ -306,4 +306,22 @@ describe('InteractiveSegmenter', () => { }); }); }); + + it('returns result', () => { + const confidenceMask = new Float32Array([0.0]); + + // Pass the test data to our listener + interactiveSegmenter.fakeWasmModule._waitUntilIdle.and.callFake(() => { + interactiveSegmenter.confidenceMasksListener!( + [ + {data: confidenceMask, width: 1, height: 1}, + ], + 1337); + }); + + const result = + interactiveSegmenter.segment({} as HTMLImageElement, KEYPOINT); + expect(result.confidenceMasks![0]).toBeInstanceOf(MPImage); + result.confidenceMasks![0].close(); + }); }); diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts index d21a9a6db..7c2743062 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts @@ -64,7 +64,7 @@ export type PoseLandmarkerCallback = (result: PoseLandmarkerResult) => void; export class PoseLandmarker extends VisionTaskRunner { private result: Partial = {}; private outputSegmentationMasks = false; - private userCallback: PoseLandmarkerCallback = () => {}; + private userCallback?: PoseLandmarkerCallback; private readonly options: PoseLandmarkerGraphOptions; private readonly poseLandmarksDetectorGraphOptions: PoseLandmarksDetectorGraphOptions; @@ -200,21 +200,22 @@ export class PoseLandmarker extends VisionTaskRunner { } /** - * Performs pose detection on the provided single image and waits - * synchronously for the response. Only use this method when the - * PoseLandmarker is created with running mode `image`. + * Performs pose detection on the provided single image and invokes the + * callback with the response. The method returns synchronously once the + * callback returns. Only use this method when the PoseLandmarker is created + * with running mode `image`. * * @param image An image to process. * @param callback The callback that is invoked with the result. The * lifetime of the returned masks is only guaranteed for the duration of * the callback. - * @return The detected pose landmarks. */ detect(image: ImageSource, callback: PoseLandmarkerCallback): void; /** - * Performs pose detection on the provided single image and waits - * synchronously for the response. Only use this method when the - * PoseLandmarker is created with running mode `image`. + * Performs pose detection on the provided single image and invokes the + * callback with the response. The method returns synchronously once the + * callback returns. Only use this method when the PoseLandmarker is created + * with running mode `image`. * * @param image An image to process. * @param imageProcessingOptions the `ImageProcessingOptions` specifying how @@ -222,16 +223,42 @@ export class PoseLandmarker extends VisionTaskRunner { * @param callback The callback that is invoked with the result. The * lifetime of the returned masks is only guaranteed for the duration of * the callback. - * @return The detected pose landmarks. */ detect( image: ImageSource, imageProcessingOptions: ImageProcessingOptions, callback: PoseLandmarkerCallback): void; + /** + * Performs pose detection on the provided single image and waits + * synchronously for the response. This method creates a copy of the resulting + * masks and should not be used in high-throughput applictions. Only + * use this method when the PoseLandmarker is created with running mode + * `image`. + * + * @param image An image to process. + * @return The landmarker result. Any masks are copied to avoid lifetime + * limits. + * @return The detected pose landmarks. + */ + detect(image: ImageSource): PoseLandmarkerResult; + /** + * Performs pose detection on the provided single image and waits + * synchronously for the response. This method creates a copy of the resulting + * masks and should not be used in high-throughput applictions. Only + * use this method when the PoseLandmarker is created with running mode + * `image`. + * + * @param image An image to process. + * @return The landmarker result. Any masks are copied to avoid lifetime + * limits. + * @return The detected pose landmarks. + */ + detect(image: ImageSource, imageProcessingOptions: ImageProcessingOptions): + PoseLandmarkerResult; detect( image: ImageSource, - imageProcessingOptionsOrCallback: ImageProcessingOptions| + imageProcessingOptionsOrCallback?: ImageProcessingOptions| PoseLandmarkerCallback, - callback?: PoseLandmarkerCallback): void { + callback?: PoseLandmarkerCallback): PoseLandmarkerResult|void { const imageProcessingOptions = typeof imageProcessingOptionsOrCallback !== 'function' ? imageProcessingOptionsOrCallback : @@ -242,28 +269,32 @@ export class PoseLandmarker extends VisionTaskRunner { this.resetResults(); this.processImageData(image, imageProcessingOptions); - this.userCallback = () => {}; + + if (!this.userCallback) { + return this.result as PoseLandmarkerResult; + } } /** - * Performs pose detection on the provided video frame and waits - * synchronously for the response. Only use this method when the - * PoseLandmarker is created with running mode `video`. + * Performs pose detection on the provided video frame and invokes the + * callback with the response. The method returns synchronously once the + * callback returns. Only use this method when the PoseLandmarker is created + * with running mode `video`. * * @param videoFrame A video frame to process. * @param timestamp The timestamp of the current frame, in ms. * @param callback The callback that is invoked with the result. The * lifetime of the returned masks is only guaranteed for the duration of * the callback. - * @return The detected pose landmarks. */ detectForVideo( videoFrame: ImageSource, timestamp: number, callback: PoseLandmarkerCallback): void; /** - * Performs pose detection on the provided video frame and waits - * synchronously for the response. Only use this method when the - * PoseLandmarker is created with running mode `video`. + * Performs pose detection on the provided video frame and invokes the + * callback with the response. The method returns synchronously once the + * callback returns. Only use this method when the PoseLandmarker is created + * with running mode `video`. * * @param videoFrame A video frame to process. * @param imageProcessingOptions the `ImageProcessingOptions` specifying how @@ -272,16 +303,45 @@ export class PoseLandmarker extends VisionTaskRunner { * @param callback The callback that is invoked with the result. The * lifetime of the returned masks is only guaranteed for the duration of * the callback. - * @return The detected pose landmarks. */ detectForVideo( videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, timestamp: number, callback: PoseLandmarkerCallback): void; + /** + * Performs pose detection on the provided video frame and returns the result. + * This method creates a copy of the resulting masks and should not be used + * in high-throughput applictions. Only use this method when the + * PoseLandmarker is created with running mode `video`. + * + * @param videoFrame A video frame to process. + * @param timestamp The timestamp of the current frame, in ms. + * @return The landmarker result. Any masks are copied to extend the + * lifetime of the returned data. + */ + detectForVideo(videoFrame: ImageSource, timestamp: number): + PoseLandmarkerResult; + /** + * Performs pose detection on the provided video frame and returns the result. + * This method creates a copy of the resulting masks and should not be used + * in high-throughput applictions. The method returns synchronously once the + * callback returns. Only use this method when the PoseLandmarker is created + * with running mode `video`. + * + * @param videoFrame A video frame to process. + * @param imageProcessingOptions the `ImageProcessingOptions` specifying how + * to process the input image before running inference. + * @param timestamp The timestamp of the current frame, in ms. + * @return The landmarker result. Any masks are copied to extend the lifetime + * of the returned data. + */ + detectForVideo( + videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, + timestamp: number): PoseLandmarkerResult; detectForVideo( videoFrame: ImageSource, timestampOrImageProcessingOptions: number|ImageProcessingOptions, - timestampOrCallback: number|PoseLandmarkerCallback, - callback?: PoseLandmarkerCallback): void { + timestampOrCallback?: number|PoseLandmarkerCallback, + callback?: PoseLandmarkerCallback): PoseLandmarkerResult|void { const imageProcessingOptions = typeof timestampOrImageProcessingOptions !== 'number' ? timestampOrImageProcessingOptions : @@ -291,10 +351,14 @@ export class PoseLandmarker extends VisionTaskRunner { timestampOrCallback as number; this.userCallback = typeof timestampOrCallback === 'function' ? timestampOrCallback : - callback!; + callback; + this.resetResults(); this.processVideoData(videoFrame, imageProcessingOptions, timestamp); - this.userCallback = () => {}; + + if (!this.userCallback) { + return this.result as PoseLandmarkerResult; + } } private resetResults(): void { @@ -315,7 +379,10 @@ export class PoseLandmarker extends VisionTaskRunner { if (this.outputSegmentationMasks && !('segmentationMasks' in this.result)) { return; } - this.userCallback(this.result as Required); + + if (this.userCallback) { + this.userCallback(this.result as Required); + } } /** Sets the default values for the graph. */ @@ -438,8 +505,9 @@ export class PoseLandmarker extends VisionTaskRunner { 'SEGMENTATION_MASK:' + SEGMENTATION_MASK_STREAM); this.graphRunner.attachImageVectorListener( SEGMENTATION_MASK_STREAM, (masks, timestamp) => { - this.result.segmentationMasks = - masks.map(wasmImage => this.convertToMPImage(wasmImage)); + this.result.segmentationMasks = masks.map( + wasmImage => this.convertToMPImage( + wasmImage, /* shouldCopyData= */ !this.userCallback)); this.setLatestOutputTimestamp(timestamp); this.maybeInvokeCallback(); }); diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts index 907cb16b3..62efa5a3c 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts @@ -331,4 +331,26 @@ describe('PoseLandmarker', () => { listenerCalled = true; }); }); + + it('returns result', () => { + const landmarksProto = [createLandmarks().serializeBinary()]; + const worldLandmarksProto = [createWorldLandmarks().serializeBinary()]; + + // Pass the test data to our listener + poseLandmarker.fakeWasmModule._waitUntilIdle.and.callFake(() => { + poseLandmarker.listeners.get('normalized_landmarks')! + (landmarksProto, 1337); + poseLandmarker.listeners.get('world_landmarks')! + (worldLandmarksProto, 1337); + poseLandmarker.listeners.get('auxiliary_landmarks')! + (landmarksProto, 1337); + }); + + // Invoke the pose landmarker + const result = poseLandmarker.detect({} as HTMLImageElement); + expect(poseLandmarker.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); + expect(result.landmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); + expect(result.worldLandmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); + expect(result.auxilaryLandmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); + }); }); From f6d0a5e03a793c5ddafbcca93267e03364d075c7 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 5 May 2023 14:27:11 -0700 Subject: [PATCH 213/753] Make the timestamp the second argument in all xForVideo() methods PiperOrigin-RevId: 529814792 --- .../web/vision/face_stylizer/face_stylizer.ts | 32 +++++++++---------- .../vision/image_segmenter/image_segmenter.ts | 32 ++++++++----------- .../vision/pose_landmarker/pose_landmarker.ts | 30 ++++++++--------- 3 files changed, 44 insertions(+), 50 deletions(-) diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts index 641ab61d2..8169e6775 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts @@ -261,16 +261,17 @@ export class FaceStylizer extends VisionTaskRunner { * monotonically increasing. * * @param videoFrame A video frame to process. + * @param timestamp The timestamp of the current frame, in ms. * @param imageProcessingOptions the `ImageProcessingOptions` specifying how * to process the input image before running inference. - * @param timestamp The timestamp of the current frame, in ms. * @param callback The callback that is invoked with the stylized image or * `null` if no face was detected. The lifetime of the returned data is only * guaranteed for the duration of the callback. */ stylizeForVideo( - videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, - timestamp: number, callback: FaceStylizerCallback): void; + videoFrame: ImageSource, timestamp: number, + imageProcessingOptions: ImageProcessingOptions, + callback: FaceStylizerCallback): void; /** * Performs face stylization on the provided video frame. This method creates * a copy of the resulting image and should not be used in high-throughput @@ -307,30 +308,29 @@ export class FaceStylizer extends VisionTaskRunner { * monotonically increasing. * * @param videoFrame A video frame to process. + * @param timestamp The timestamp of the current frame, in ms. * @param imageProcessingOptions the `ImageProcessingOptions` specifying how * to process the input image before running inference. - * @param timestamp The timestamp of the current frame, in ms. * @return A stylized face or `null` if no face was detected. The result is * copied to avoid lifetime issues. */ - stylizeForVideo( - videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, - timestamp: number): MPImage|null; stylizeForVideo( videoFrame: ImageSource, - timestampOrImageProcessingOptions: number|ImageProcessingOptions, - timestampOrCallback?: number|FaceStylizerCallback, + timestamp: number, + imageProcessingOptions: ImageProcessingOptions, + ): MPImage|null; + stylizeForVideo( + videoFrame: ImageSource, timestamp: number, + imageProcessingOptionsOrCallback?: ImageProcessingOptions| + FaceStylizerCallback, callback?: FaceStylizerCallback): MPImage|null|void { const imageProcessingOptions = - typeof timestampOrImageProcessingOptions !== 'number' ? - timestampOrImageProcessingOptions : + typeof imageProcessingOptionsOrCallback !== 'function' ? + imageProcessingOptionsOrCallback : {}; - const timestamp = typeof timestampOrImageProcessingOptions === 'number' ? - timestampOrImageProcessingOptions : - timestampOrCallback as number; - this.userCallback = typeof timestampOrCallback === 'function' ? - timestampOrCallback : + this.userCallback = typeof imageProcessingOptionsOrCallback === 'function' ? + imageProcessingOptionsOrCallback : callback; this.processVideoData(videoFrame, imageProcessingOptions, timestamp); this.userCallback = undefined; diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts index 4d0ac18f2..b4e9f804d 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts @@ -293,16 +293,17 @@ export class ImageSegmenter extends VisionTaskRunner { * created with running mode `video`. * * @param videoFrame A video frame to process. + * @param timestamp The timestamp of the current frame, in ms. * @param imageProcessingOptions the `ImageProcessingOptions` specifying how * to process the input frame before running inference. - * @param timestamp The timestamp of the current frame, in ms. * @param callback The callback that is invoked with the segmented masks. The * lifetime of the returned data is only guaranteed for the duration of the * callback. */ segmentForVideo( - videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, - timestamp: number, callback: ImageSegmenterCallback): void; + videoFrame: ImageSource, timestamp: number, + imageProcessingOptions: ImageProcessingOptions, + callback: ImageSegmenterCallback): void; /** * Performs image segmentation on the provided video frame and returns the * segmentation result. This method creates a copy of the resulting masks and @@ -322,31 +323,26 @@ export class ImageSegmenter extends VisionTaskRunner { * the ImageSegmenter is created with running mode `video`. * * @param videoFrame A video frame to process. + * @param timestamp The timestamp of the current frame, in ms. * @param imageProcessingOptions the `ImageProcessingOptions` specifying how * to process the input frame before running inference. - * @param timestamp The timestamp of the current frame, in ms. * @return The segmentation result. The data is copied to avoid lifetime * issues. */ segmentForVideo( - videoFrame: ImageSource, - imageProcessingOptions: ImageProcessingOptions, - timestamp: number, - ): ImageSegmenterResult; + videoFrame: ImageSource, timestamp: number, + imageProcessingOptions: ImageProcessingOptions): ImageSegmenterResult; segmentForVideo( - videoFrame: ImageSource, - timestampOrImageProcessingOptions: number|ImageProcessingOptions, - timestampOrCallback?: number|ImageSegmenterCallback, + videoFrame: ImageSource, timestamp: number, + imageProcessingOptionsOrCallback?: ImageProcessingOptions| + ImageSegmenterCallback, callback?: ImageSegmenterCallback): ImageSegmenterResult|void { const imageProcessingOptions = - typeof timestampOrImageProcessingOptions !== 'number' ? - timestampOrImageProcessingOptions : + typeof imageProcessingOptionsOrCallback !== 'function' ? + imageProcessingOptionsOrCallback : {}; - const timestamp = typeof timestampOrImageProcessingOptions === 'number' ? - timestampOrImageProcessingOptions : - timestampOrCallback as number; - this.userCallback = typeof timestampOrCallback === 'function' ? - timestampOrCallback : + this.userCallback = typeof imageProcessingOptionsOrCallback === 'function' ? + imageProcessingOptionsOrCallback : callback; this.reset(); diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts index 7c2743062..7cb37d5e2 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts @@ -297,16 +297,17 @@ export class PoseLandmarker extends VisionTaskRunner { * with running mode `video`. * * @param videoFrame A video frame to process. + * @param timestamp The timestamp of the current frame, in ms. * @param imageProcessingOptions the `ImageProcessingOptions` specifying how * to process the input image before running inference. - * @param timestamp The timestamp of the current frame, in ms. * @param callback The callback that is invoked with the result. The * lifetime of the returned masks is only guaranteed for the duration of * the callback. */ detectForVideo( - videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, - timestamp: number, callback: PoseLandmarkerCallback): void; + videoFrame: ImageSource, timestamp: number, + imageProcessingOptions: ImageProcessingOptions, + callback: PoseLandmarkerCallback): void; /** * Performs pose detection on the provided video frame and returns the result. * This method creates a copy of the resulting masks and should not be used @@ -328,29 +329,26 @@ export class PoseLandmarker extends VisionTaskRunner { * with running mode `video`. * * @param videoFrame A video frame to process. + * @param timestamp The timestamp of the current frame, in ms. * @param imageProcessingOptions the `ImageProcessingOptions` specifying how * to process the input image before running inference. - * @param timestamp The timestamp of the current frame, in ms. * @return The landmarker result. Any masks are copied to extend the lifetime * of the returned data. */ detectForVideo( - videoFrame: ImageSource, imageProcessingOptions: ImageProcessingOptions, - timestamp: number): PoseLandmarkerResult; + videoFrame: ImageSource, timestamp: number, + imageProcessingOptions: ImageProcessingOptions): PoseLandmarkerResult; detectForVideo( - videoFrame: ImageSource, - timestampOrImageProcessingOptions: number|ImageProcessingOptions, - timestampOrCallback?: number|PoseLandmarkerCallback, + videoFrame: ImageSource, timestamp: number, + imageProcessingOptionsOrCallback?: ImageProcessingOptions| + PoseLandmarkerCallback, callback?: PoseLandmarkerCallback): PoseLandmarkerResult|void { const imageProcessingOptions = - typeof timestampOrImageProcessingOptions !== 'number' ? - timestampOrImageProcessingOptions : + typeof imageProcessingOptionsOrCallback !== 'function' ? + imageProcessingOptionsOrCallback : {}; - const timestamp = typeof timestampOrImageProcessingOptions === 'number' ? - timestampOrImageProcessingOptions : - timestampOrCallback as number; - this.userCallback = typeof timestampOrCallback === 'function' ? - timestampOrCallback : + this.userCallback = typeof imageProcessingOptionsOrCallback === 'function' ? + imageProcessingOptionsOrCallback : callback; this.resetResults(); From 2fa03a3699874944ba2d211b88576ddfb449b71d Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Sat, 6 May 2023 04:23:49 +0530 Subject: [PATCH 214/753] Added flow limiter calculator and conditionally selected xcframework in iOS framework targets --- mediapipe/tasks/ios/BUILD | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index c839acd84..5f1d9d6e4 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -46,6 +46,7 @@ OBJC_COMMON_DEPS = [ "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", + "//mediapipe/calculators/core:flow_limiter_calculator", "//mediapipe/gpu:metal_shared_resources", ] @@ -124,9 +125,7 @@ apple_static_xcframework( # when the frameworks are imported in iOS projects. # Also avoids opencv since it will be built with # ":MediaPipeTaskGraphs_library". - avoid_deps = OBJC_COMMON_DEPS + [ - "@ios_opencv//:OpencvFramework", - ], + avoid_deps = OBJC_COMMON_DEPS, bundle_name = "MediaPipeTasksVision", ios = { "simulator": [ @@ -176,9 +175,15 @@ apple_static_library( "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", - "@ios_opencv//:OpencvFramework", + "//mediapipe/calculators/core:flow_limiter_calculator", "@org_tensorflow//third_party/icu/data:conversion_data", - ], + ] + select({ + "//third_party:opencv_ios_sim_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + "//third_party:opencv_ios_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + "//third_party:opencv_ios_x86_64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + "//third_party:opencv_ios_sim_fat_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + "//conditions:default": ["@ios_opencv//:OpencvFramework"], + }), ) apple_static_xcframework( From 78224aaee658a53c8994ed79c22fd4f7ee9778d9 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Sat, 6 May 2023 04:24:36 +0530 Subject: [PATCH 215/753] Updated shell script to build ios opencv from source --- mediapipe/tasks/ios/build_ios_framework.sh | 32 ++++++++-------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index bb2fafc1f..64f3f5fc3 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -79,24 +79,11 @@ def format(target): EOF local OUTPUT_PATH=$(bazel cquery $1 --output=starlark --starlark:file="${STARLARK_FILE}" 2> /dev/null) - rm -rf "${STARLARK_OUTPUT_TMPDIR}" echo ${OUTPUT_PATH} } -# This function builds a target using the command passed in as argument and -# uses cquery to find the path to the output of the target. -function build_target { - # Build using the command passed as argument. - "${BAZEL}" build $1 - - # Get the path to the output file of the target. - local OUTPUT_PATH=$(get_output_file_path "$1") - - echo ${OUTPUT_PATH} -} - # This function builds 3 the xcframework and associated graph libraries if any # for a given framework name. function build_ios_frameworks_and_libraries { @@ -110,21 +97,24 @@ function build_ios_frameworks_and_libraries { # the order of a few MBs. # Build Task Library xcframework. - local FRAMEWORK_CQUERY_COMMAND="-c opt --apple_generate_dsym=false ${FULL_FRAMEWORK_TARGET}" - IOS_FRAMEWORK_PATH="$(build_target "${FRAMEWORK_CQUERY_COMMAND}")" + local FRAMEWORK_CQUERY_COMMAND="-c opt --apple_generate_dsym=false --define OPENCV=source ${FULL_FRAMEWORK_TARGET}" + ${BAZEL} build ${FRAMEWORK_CQUERY_COMMAND} + IOS_FRAMEWORK_PATH="$(get_output_file_path "${FRAMEWORK_CQUERY_COMMAND}")" # `MediaPipeTasksCommon` pods must also include the task graph libraries which # are to be force loaded. Hence the graph libraies are only built if the framework # name is `MediaPipeTasksCommon`.` case $FRAMEWORK_NAME in "MediaPipeTasksCommon") - local IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_sim_fat --apple_generate_dsym=false //mediapipe/tasks/ios:MediaPipeTaskGraphs_library" - IOS_GRAPHS_SIMULATOR_LIBRARY_PATH="$(build_target "${IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND}")" - - # Build static library for iOS devices with arch ios_arm64. We don't need to build for armv7 since + local IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_sim_fat --apple_generate_dsym=false --define OPENCV=source //mediapipe/tasks/ios:MediaPipeTaskGraphs_library" + ${BAZEL} build ${IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND} + IOS_GRAPHS_SIMULATOR_LIBRARY_PATH="$(get_output_file_path "${IOS_SIM_FAT_LIBRARY_CQUERY_COMMAND}")" + + # Build static library for iOS devices with arch ios_arm64. We don't need to build for armv7 since # our deployment target is iOS 11.0. iOS 11.0 and upwards is not supported by old armv7 devices. - local IOS_DEVICE_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_arm64 --apple_generate_dsym=false //mediapipe/tasks/ios:MediaPipeTaskGraphs_library" - IOS_GRAPHS_DEVICE_LIBRARY_PATH="$(build_target "${IOS_DEVICE_LIBRARY_CQUERY_COMMAND}")" + local IOS_DEVICE_LIBRARY_CQUERY_COMMAND="-c opt --config=ios_arm64 --apple_generate_dsym=false --define OPENCV=source //mediapipe/tasks/ios:MediaPipeTaskGraphs_library" + ${BAZEL} build ${IOS_DEVICE_LIBRARY_CQUERY_COMMAND} + IOS_GRAPHS_DEVICE_LIBRARY_PATH="$(get_output_file_path "${IOS_DEVICE_LIBRARY_CQUERY_COMMAND}")" ;; *) ;; From 6427c49d2d5aa293aa906e9313b42dd25434336d Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Sat, 6 May 2023 04:25:24 +0530 Subject: [PATCH 216/753] Aded version of dependency to podspec template --- mediapipe/tasks/ios/MediaPipeTasksText.podspec.template | 2 +- mediapipe/tasks/ios/MediaPipeTasksVision.podspec.template | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/ios/MediaPipeTasksText.podspec.template b/mediapipe/tasks/ios/MediaPipeTasksText.podspec.template index 144d36f88..105f1c4f0 100644 --- a/mediapipe/tasks/ios/MediaPipeTasksText.podspec.template +++ b/mediapipe/tasks/ios/MediaPipeTasksText.podspec.template @@ -12,7 +12,7 @@ Pod::Spec.new do |s| s.module_name = 'MediaPipeTasksText' s.static_framework = true - s.dependency 'MediaPipeTasksCommon' + s.dependency 'MediaPipeTasksCommon', '${MPP_TASKS_COMMON_VERSION}' s.library = 'c++' s.vendored_frameworks = 'frameworks/MediaPipeTasksText.xcframework' end diff --git a/mediapipe/tasks/ios/MediaPipeTasksVision.podspec.template b/mediapipe/tasks/ios/MediaPipeTasksVision.podspec.template index 373c1768b..4c0c0170b 100644 --- a/mediapipe/tasks/ios/MediaPipeTasksVision.podspec.template +++ b/mediapipe/tasks/ios/MediaPipeTasksVision.podspec.template @@ -12,7 +12,7 @@ Pod::Spec.new do |s| s.module_name = 'MediaPipeTasksVision' s.static_framework = true - s.dependency 'MediaPipeTasksCommon' + s.dependency 'MediaPipeTasksCommon', '${MPP_TASKS_COMMON_VERSION}' s.library = 'c++' s.vendored_frameworks = 'frameworks/MediaPipeTasksVision.xcframework' end From 1daf4d74ee0a23f21bbac9389d61ed61f2a60233 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Sat, 6 May 2023 04:35:51 +0530 Subject: [PATCH 217/753] Updated common dependencies to link in helpers --- mediapipe/tasks/ios/BUILD | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index 5f1d9d6e4..84cfeaa47 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -33,14 +33,18 @@ licenses(["notice"]) # will be built with ":MediaPipeTasksCommon_framework" # 2. Task graphs. These will be built with ":MediaPipeTaskGraphs_library". # 3. gpu targets which will be built with the ":MediaPipeTaskGraphs_library". +# +# Instead of linking options and containers, we link their helpers to +# `MPPTasksCommon` to avoid duplicated method warnings in categories when text +# and vision frameworks are installed in the same Xcode project. OBJC_COMMON_DEPS = [ - "//mediapipe/tasks/ios/core:MPPBaseOptions", + "//mediapipe/tasks/ios/core/utils:MPPBaseOptionsHelpers", "//mediapipe/tasks/ios/core:MPPTaskInfo", "//mediapipe/tasks/ios/core:MPPTaskOptions", "//mediapipe/tasks/ios/core:MPPTaskResult", "//mediapipe/tasks/ios/core:MPPTaskRunner", - "//mediapipe/tasks/ios/components/containers:MPPClassificationResult", - "//mediapipe/tasks/ios/components/containers:MPPCategory", + "//mediapipe/tasks/ios/components/containers/utils:MPPClassificationResultHelpers", + "//mediapipe/tasks/ios/components/containers/utils:MPPCategoryHelpers", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", @@ -207,9 +211,9 @@ apple_static_xcframework( }, deps = [ "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", - "//mediapipe/tasks/ios/components/containers:MPPCategory", - "//mediapipe/tasks/ios/components/containers:MPPClassificationResult", - "//mediapipe/tasks/ios/core:MPPBaseOptions", + "//mediapipe/tasks/ios/components/containers/utils:MPPCategoryHelpers", + "//mediapipe/tasks/ios/components/containers/utils:MPPClassificationResultHelpers", + "//mediapipe/tasks/ios/core/utils:MPPBaseOptionsHelpers", "//mediapipe/tasks/ios/core:MPPTaskInfo", "//mediapipe/tasks/ios/core:MPPTaskOptions", "//mediapipe/tasks/ios/core:MPPTaskResult", From 26fce393e8eceac02a0f47b8fafbb623423013cd Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Sat, 6 May 2023 04:36:49 +0530 Subject: [PATCH 218/753] Removed opencv framework target from vision runner deps --- mediapipe/tasks/ios/vision/core/BUILD | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/mediapipe/tasks/ios/vision/core/BUILD b/mediapipe/tasks/ios/vision/core/BUILD index b797fcb94..8ca156767 100644 --- a/mediapipe/tasks/ios/vision/core/BUILD +++ b/mediapipe/tasks/ios/vision/core/BUILD @@ -61,11 +61,5 @@ objc_library( "//mediapipe/tasks/ios/core:MPPTaskRunner", "//third_party/apple_frameworks:UIKit", "@com_google_absl//absl/status:statusor", - "@ios_opencv//:OpencvFramework", - ] + select({ - "@//third_party:opencv_ios_sim_arm64_source_build": ["@ios_opencv_source//:opencv_xcframework"], - "@//third_party:opencv_ios_sim_fat_source_build": ["@ios_opencv_source//:opencv_xcframework"], - "@//third_party:opencv_ios_arm64_source_build": ["@ios_opencv_source//:opencv_xcframework"], - "//conditions:default": [], - }), + ], ) From d22a1318f6d3c3d705ab3195ff1b903706538bf5 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Sat, 6 May 2023 04:37:09 +0530 Subject: [PATCH 219/753] Updated condition checks in third_party/BUILD --- third_party/BUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/BUILD b/third_party/BUILD index 60fa73799..451e0c8aa 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -104,7 +104,7 @@ config_setting( }, values = { "apple_platform_type": "ios", - "ios_multi_cpus": "sim_arm64, x86_64", + "ios_multi_cpus": "sim_arm64,x86_64", }, ) @@ -113,8 +113,8 @@ alias( actual = select({ ":opencv_source_build": ":opencv_cmake", ":opencv_ios_sim_arm64_source_build": "@ios_opencv_source//:opencv", - ":opencv_ios_sim_fat_source_build": "@ios_opencv_source//:opencv", ":opencv_ios_arm64_source_build": "@ios_opencv_source//:opencv", + ":opencv_ios_x86_64_source_build": "@ios_opencv_source//:opencv", "//conditions:default": ":opencv_binary", }), visibility = ["//visibility:public"], From 4349ac48b0dfad3da98bc75b544f91d22d56b0b6 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Sat, 6 May 2023 04:39:09 +0530 Subject: [PATCH 220/753] Changed opencv framework version to 4.5.3 --- WORKSPACE | 10 +- third_party/opencv_ios_source.BUILD | 10 +- third_party/opencv_ios_source.bzl | 10 +- third_party/opencv_ios_xcframework_files.bzl | 891 ++++++++++--------- 4 files changed, 463 insertions(+), 458 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index ee2506ed7..84a156bc2 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -375,16 +375,20 @@ 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.1 sources is necessary for +# 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 = "5fbc26ee09e148a4d494b225d04217f7c913ca1a4d46115b70cca3565d7bbe05", + sha256 = "a61e7a4618d353140c857f25843f39b2abe5f451b018aab1604ef0bc34cd23d5", build_file = "@//third_party:opencv_ios_source.BUILD", type = "zip", - url = "https://github.com/opencv/opencv/archive/refs/tags/4.5.1.zip", + url = "https://github.com/opencv/opencv/archive/refs/tags/4.5.3.zip", ) http_archive( diff --git a/third_party/opencv_ios_source.BUILD b/third_party/opencv_ios_source.BUILD index c0cb65908..e8d0e0618 100644 --- a/third_party/opencv_ios_source.BUILD +++ b/third_party/opencv_ios_source.BUILD @@ -25,12 +25,14 @@ load( # for MediaPipe iOS Task libraries are built. Shipping with OPENCV built with # Swift support throws linker errors when the MediaPipe framework is used from # an iOS project. +# When building on M1 Macs, cmake version cannot be higher than 3.24.0. This is +# is mentioned in an open issue in the opencv github repo. genrule( name = "build_opencv_xcframework", - srcs = glob(["opencv-4.5.1/**"]), + srcs = glob(["opencv-4.5.3/**"]), outs = ["opencv2.xcframework.zip"], cmd = "&&".join([ - "$(location opencv-4.5.1/platforms/apple/build_xcframework.py) \ + "$(location opencv-4.5.3/platforms/apple/build_xcframework.py) \ --iphonesimulator_archs arm64,x86_64 \ --iphoneos_archs arm64 \ --without dnn \ @@ -89,8 +91,8 @@ cc_library( "@//mediapipe:ios_sim_arm64": [ ":opencv_xcframework_simulator_headers", ], - "@//mediapipe:ios_arm64": [ - ":opencv_xcframework_simulator_headers", + "@//mediapipe:ios_arm64" : [ + ":opencv_xcframework_device_headers" ], # A value from above is chosen arbitarily. "//conditions:default": [ diff --git a/third_party/opencv_ios_source.bzl b/third_party/opencv_ios_source.bzl index e46fb4cac..ddf2e4136 100644 --- a/third_party/opencv_ios_source.bzl +++ b/third_party/opencv_ios_source.bzl @@ -27,12 +27,10 @@ _OPENCV_SIMULATOR_PLATFORM_DIR_NAME = "ios-arm64_x86_64-simulator" _OPENCV_DEVICE_PLATFORM_DIR_NAME = "ios-arm64" def _select_headers_impl(ctx): - _files = [ - f - for f in ctx.files.srcs - if (f.basename.endswith(".h") or f.basename.endswith(".hpp")) and - f.dirname.find(ctx.attr.platform) != -1 - ] + # Should match with `/`. Othewise `ios-arm64` matches to `ios-arm64_x86-64` + _files = [f for f in ctx.files.srcs + if (f.basename.endswith(".h") or f.basename.endswith(".hpp")) + and f.dirname.find(ctx.attr.platform + "/") != -1] return [DefaultInfo(files = depset(_files))] # This rule selects only the headers from an apple static xcframework filtered by diff --git a/third_party/opencv_ios_xcframework_files.bzl b/third_party/opencv_ios_xcframework_files.bzl index f3ea23883..29baef810 100644 --- a/third_party/opencv_ios_xcframework_files.bzl +++ b/third_party/opencv_ios_xcframework_files.bzl @@ -17,452 +17,453 @@ OPENCV_XCFRAMEWORK_INFO_PLIST_PATH = "opencv2.xcframework/Info.plist" OPENCV_XCFRAMEWORK_IOS_SIMULATOR_FILE_PATHS = [ - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Resources/Info.plist", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Moments.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfRect2d.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfFloat4.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfPoint2i.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/tracking.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/legacy/constants_c.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/background_segm.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/video.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Double3.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfByte.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Range.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Core.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Size2f.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/world.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/opencv2-Swift.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/fast_math.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda_types.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/check.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cv_cpu_dispatch.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utility.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/softfloat.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cv_cpu_helper.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cvstd.inl.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/msa_macros.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_rvv.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/simd_utils.impl.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_wasm.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_neon.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_avx.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_avx512.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_vsx.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/interface.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_msa.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_cpp.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_forward.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_sse.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_sse_em.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/hal.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/async.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/bufferpool.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/ovx.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/optim.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/va_intel.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cvdef.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/warp.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/filters.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/dynamic_smem.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/reduce.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/utility.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/warp_shuffle.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/border_interpolate.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/transform.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/saturate_cast.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/vec_math.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/functional.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/limits.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/type_traits.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/vec_distance.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/block.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/reduce.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/reduce_key_val.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/color_detail.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/type_traits_detail.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/vec_distance_detail.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/transform_detail.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/emulation.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/color.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/datamov_utils.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/funcattrib.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/common.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/vec_traits.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/simd_functions.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/warp_reduce.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/scan.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/traits.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opengl.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cvstd_wrapper.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda.inl.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/eigen.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda_stream_accessor.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/ocl.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/affine.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/mat.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/logger.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/allocator_stats.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/allocator_stats.impl.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/logtag.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/filesystem.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/tls.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/trace.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/instrumentation.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/logger.defines.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/quaternion.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/neon_utils.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/sse_utils.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/version.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/opencl_info.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_gl.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_definitions.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_hsa_extension.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_clamdblas.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_core.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_20.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_core_wrappers.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_gl_wrappers.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_clamdfft.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_gl.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_core.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/ocl_defs.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/opencl_svm.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/ocl_genbase.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/detail/async_promise.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/detail/exception_ptr.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/simd_intrinsics.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/matx.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/directx.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/base.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/operations.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/vsx_utils.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/persistence.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/mat.inl.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/types_c.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cvstd.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/types.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/bindings_utils.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/quaternion.inl.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/saturate.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/core_c.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/core.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Converters.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Mat.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Algorithm.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/opencv.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Mat+Converters.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/ByteVector.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/imgproc.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/imgproc_c.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/hal/interface.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/hal/hal.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/detail/gcgraph.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/types_c.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/highgui.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/features2d.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point2f.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/KeyPoint.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Rect2f.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Float6.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfKeyPoint.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfRect2i.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/FloatVector.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/TermCriteria.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/opencv2.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Int4.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfDMatch.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Scalar.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point3f.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfDouble.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/IntVector.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/RotatedRect.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfFloat6.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/cvconfig.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/DoubleVector.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Size2d.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MinMaxLocResult.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfInt4.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Rect2i.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point2i.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfPoint3.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfRotatedRect.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/DMatch.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/TickMeter.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point3i.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/ios.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/legacy/constants_c.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/macosx.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/imgcodecs.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/imgcodecs_c.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/CvType.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/CVObjcUtil.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Size2i.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Float4.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/registry.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/cap_ios.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/legacy/constants_c.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/videoio.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/videoio_c.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfFloat.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Rect2d.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfPoint2f.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point2d.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/highgui/highgui.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/highgui/highgui_c.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Double2.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/CvCamera2.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/features2d/hal/interface.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/features2d/features2d.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/opencv_modules.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core.hpp", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfInt.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/ArrayUtil.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfPoint3f.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point3d.h", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/x86_64-apple-ios-simulator.swiftinterface", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios-simulator.abi.json", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/x86_64-apple-ios-simulator.swiftdoc", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios-simulator.swiftinterface", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios-simulator.swiftdoc", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/x86_64-apple-ios-simulator.abi.json", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/module.modulemap", - "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/opencv2", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Resources/Info.plist", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Moments.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfRect2d.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfFloat4.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfPoint2i.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/tracking.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/legacy/constants_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/background_segm.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/detail/tracking.detail.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video/video.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Double3.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfByte.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Range.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Core.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Size2f.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/world.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/fast_math.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda_types.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/check.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cv_cpu_dispatch.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/parallel/backend/parallel_for.tbb.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/parallel/backend/parallel_for.openmp.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/parallel/parallel_backend.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utility.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/softfloat.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cv_cpu_helper.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cvstd.inl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/msa_macros.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_rvv.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_rvv071.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/simd_utils.impl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_wasm.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_neon.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_avx.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_avx512.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_vsx.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/interface.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_msa.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_cpp.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_forward.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_sse.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/intrin_sse_em.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/hal/hal.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/dualquaternion.inl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/async.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/bufferpool.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/ovx.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/optim.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/va_intel.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cvdef.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/warp.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/filters.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/dynamic_smem.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/reduce.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/utility.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/warp_shuffle.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/border_interpolate.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/transform.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/saturate_cast.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/vec_math.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/functional.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/limits.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/type_traits.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/vec_distance.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/block.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/reduce.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/reduce_key_val.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/color_detail.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/type_traits_detail.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/vec_distance_detail.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/detail/transform_detail.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/emulation.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/color.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/datamov_utils.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/funcattrib.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/common.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/vec_traits.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/simd_functions.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/warp_reduce.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda/scan.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/traits.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opengl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cvstd_wrapper.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda.inl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/eigen.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda_stream_accessor.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/ocl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cuda.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/affine.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/mat.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/logger.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/allocator_stats.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/allocator_stats.impl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/logtag.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/filesystem.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/tls.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/trace.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/instrumentation.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/utils/logger.defines.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/quaternion.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/neon_utils.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/sse_utils.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/version.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/opencl_info.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_gl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_definitions.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_hsa_extension.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_clblas.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_clfft.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_core.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_20.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_core_wrappers.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_gl_wrappers.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_gl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_clblas.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_clfft.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_core.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/ocl_defs.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/opencl/opencl_svm.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/ocl_genbase.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/dualquaternion.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/detail/async_promise.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/detail/exception_ptr.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/simd_intrinsics.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/matx.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/directx.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/base.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/operations.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/vsx_utils.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/persistence.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/mat.inl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/types_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/cvstd.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/types.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/bindings_utils.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/quaternion.inl.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/saturate.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/core_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core/core.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Converters.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Mat.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Algorithm.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/opencv.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Mat+Converters.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/ByteVector.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/imgproc.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/imgproc_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/bindings.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/hal/interface.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/hal/hal.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/segmentation.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/detail/gcgraph.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgproc/types_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/highgui.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/features2d.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point2f.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/KeyPoint.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Rect2f.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Float6.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfKeyPoint.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfRect2i.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/FloatVector.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/TermCriteria.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/opencv2.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Int4.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfDMatch.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Scalar.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point3f.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfDouble.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/IntVector.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/RotatedRect.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfFloat6.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/cvconfig.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/DoubleVector.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Size2d.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MinMaxLocResult.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfInt4.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Rect2i.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point2i.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfPoint3.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfRotatedRect.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/DMatch.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/TickMeter.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point3i.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/video.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/ios.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/legacy/constants_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/macosx.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/imgcodecs.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs/imgcodecs_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/CvType.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/CVObjcUtil.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Size2i.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/imgcodecs.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Float4.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/registry.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/cap_ios.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/legacy/constants_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/videoio.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio/videoio_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfFloat.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Rect2d.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfPoint2f.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point2d.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/highgui/highgui.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/highgui/highgui_c.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Double2.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/CvCamera2.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/features2d/hal/interface.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/features2d/features2d.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/videoio.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/opencv_modules.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/core.hpp", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfInt.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/ArrayUtil.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/MatOfPoint3f.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers/Point3d.h", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Modules/module.modulemap", +"opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/opencv2", ] OPENCV_XCFRAMEWORK_IOS_DEVICE_FILE_PATHS = [ - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Resources/Info.plist", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Moments.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfRect2d.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfFloat4.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfPoint2i.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/tracking.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/legacy/constants_c.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/background_segm.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/video.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Double3.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfByte.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Range.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Core.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Size2f.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/world.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/opencv2-Swift.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/fast_math.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda_types.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/check.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cv_cpu_dispatch.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utility.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/softfloat.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cv_cpu_helper.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cvstd.inl.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/msa_macros.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_rvv.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/simd_utils.impl.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_wasm.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_neon.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_avx.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_avx512.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_vsx.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/interface.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_msa.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_cpp.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_forward.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_sse.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_sse_em.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/hal.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/async.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/bufferpool.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/ovx.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/optim.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/va_intel.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cvdef.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/warp.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/filters.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/dynamic_smem.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/reduce.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/utility.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/warp_shuffle.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/border_interpolate.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/transform.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/saturate_cast.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/vec_math.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/functional.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/limits.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/type_traits.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/vec_distance.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/block.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/reduce.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/reduce_key_val.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/color_detail.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/type_traits_detail.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/vec_distance_detail.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/transform_detail.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/emulation.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/color.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/datamov_utils.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/funcattrib.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/common.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/vec_traits.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/simd_functions.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/warp_reduce.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/scan.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/traits.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opengl.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cvstd_wrapper.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda.inl.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/eigen.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda_stream_accessor.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/ocl.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/affine.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/mat.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/logger.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/allocator_stats.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/allocator_stats.impl.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/logtag.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/filesystem.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/tls.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/trace.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/instrumentation.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/logger.defines.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/quaternion.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/neon_utils.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/sse_utils.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/version.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/opencl_info.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_gl.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_definitions.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_hsa_extension.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_clamdblas.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_core.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_20.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_core_wrappers.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_gl_wrappers.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_clamdfft.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_gl.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_core.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/ocl_defs.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/opencl_svm.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/ocl_genbase.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/detail/async_promise.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/detail/exception_ptr.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/simd_intrinsics.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/matx.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/directx.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/base.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/operations.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/vsx_utils.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/persistence.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/mat.inl.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/types_c.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cvstd.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/types.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/bindings_utils.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/quaternion.inl.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/saturate.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/core_c.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/core.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Converters.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Mat.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Algorithm.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/opencv.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Mat+Converters.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/ByteVector.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/imgproc.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/imgproc_c.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/hal/interface.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/hal/hal.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/detail/gcgraph.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/types_c.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/highgui.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/features2d.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point2f.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/KeyPoint.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Rect2f.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Float6.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfKeyPoint.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfRect2i.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/FloatVector.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/TermCriteria.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/opencv2.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Int4.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfDMatch.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Scalar.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point3f.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfDouble.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/IntVector.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/RotatedRect.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfFloat6.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/cvconfig.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/DoubleVector.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Size2d.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MinMaxLocResult.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfInt4.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Rect2i.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point2i.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfPoint3.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfRotatedRect.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/DMatch.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/TickMeter.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point3i.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/ios.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/legacy/constants_c.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/macosx.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/imgcodecs.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/imgcodecs_c.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/CvType.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/CVObjcUtil.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Size2i.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Float4.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/registry.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/cap_ios.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/legacy/constants_c.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/videoio.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/videoio_c.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfFloat.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Rect2d.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfPoint2f.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point2d.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/highgui/highgui.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/highgui/highgui_c.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Double2.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/CvCamera2.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/features2d/hal/interface.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/features2d/features2d.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/opencv_modules.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core.hpp", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfInt.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/ArrayUtil.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfPoint3f.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point3d.h", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios.swiftinterface", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios.swiftdoc", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios.abi.json", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/opencv2.swiftmodule/arm64-apple-ios.private.swiftinterface", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/module.modulemap", - "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/opencv2", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Resources/Info.plist", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Moments.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfRect2d.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfFloat4.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfPoint2i.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/tracking.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/legacy/constants_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/background_segm.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/detail/tracking.detail.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video/video.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Double3.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfByte.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Range.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Core.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Size2f.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/world.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/fast_math.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda_types.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/check.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cv_cpu_dispatch.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/parallel/backend/parallel_for.tbb.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/parallel/backend/parallel_for.openmp.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/parallel/parallel_backend.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utility.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/softfloat.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cv_cpu_helper.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cvstd.inl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/msa_macros.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_rvv.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_rvv071.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/simd_utils.impl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_wasm.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_neon.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_avx.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_avx512.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_vsx.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/interface.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_msa.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_cpp.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_forward.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_sse.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/intrin_sse_em.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/hal/hal.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/dualquaternion.inl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/async.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/bufferpool.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/ovx.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/optim.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/va_intel.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cvdef.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/warp.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/filters.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/dynamic_smem.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/reduce.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/utility.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/warp_shuffle.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/border_interpolate.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/transform.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/saturate_cast.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/vec_math.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/functional.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/limits.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/type_traits.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/vec_distance.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/block.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/reduce.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/reduce_key_val.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/color_detail.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/type_traits_detail.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/vec_distance_detail.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/detail/transform_detail.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/emulation.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/color.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/datamov_utils.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/funcattrib.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/common.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/vec_traits.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/simd_functions.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/warp_reduce.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda/scan.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/traits.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opengl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cvstd_wrapper.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda.inl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/eigen.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda_stream_accessor.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/ocl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cuda.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/affine.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/mat.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/logger.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/allocator_stats.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/allocator_stats.impl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/logtag.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/filesystem.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/tls.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/trace.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/instrumentation.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/utils/logger.defines.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/quaternion.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/neon_utils.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/sse_utils.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/version.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/opencl_info.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_gl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_definitions.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_hsa_extension.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_clblas.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_clfft.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_core.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_svm_20.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_core_wrappers.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/opencl_gl_wrappers.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_gl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_clblas.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_clfft.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_core.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/ocl_defs.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/opencl/opencl_svm.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/ocl_genbase.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/dualquaternion.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/detail/async_promise.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/detail/exception_ptr.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/simd_intrinsics.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/matx.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/directx.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/base.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/operations.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/vsx_utils.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/persistence.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/mat.inl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/types_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/cvstd.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/types.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/bindings_utils.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/quaternion.inl.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/saturate.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/core_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core/core.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Converters.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Mat.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Algorithm.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/opencv.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Mat+Converters.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/ByteVector.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/imgproc.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/imgproc_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/bindings.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/hal/interface.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/hal/hal.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/segmentation.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/detail/gcgraph.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgproc/types_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/highgui.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/features2d.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point2f.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/KeyPoint.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Rect2f.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Float6.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfKeyPoint.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfRect2i.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/FloatVector.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/TermCriteria.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/opencv2.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Int4.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfDMatch.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Scalar.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point3f.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfDouble.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/IntVector.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/RotatedRect.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfFloat6.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/cvconfig.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/DoubleVector.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Size2d.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MinMaxLocResult.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfInt4.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Rect2i.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point2i.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfPoint3.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfRotatedRect.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/DMatch.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/TickMeter.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point3i.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/video.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/ios.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/legacy/constants_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/macosx.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/imgcodecs.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs/imgcodecs_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/CvType.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/CVObjcUtil.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Size2i.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/imgcodecs.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Float4.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/registry.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/cap_ios.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/legacy/constants_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/videoio.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio/videoio_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfFloat.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Rect2d.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfPoint2f.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point2d.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/highgui/highgui.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/highgui/highgui_c.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Double2.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/CvCamera2.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/features2d/hal/interface.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/features2d/features2d.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/videoio.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/opencv_modules.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/core.hpp", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfInt.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/ArrayUtil.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/MatOfPoint3f.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers/Point3d.h", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Modules/module.modulemap", +"opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/opencv2", ] From 648a24a97bc3c97d394e2b1945ac96fde29383e9 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Sat, 6 May 2023 04:58:59 +0530 Subject: [PATCH 221/753] Added conditional building of opencv xc framework to test targets --- mediapipe/tasks/ios/test/vision/image_classifier/BUILD | 7 ++++++- mediapipe/tasks/ios/test/vision/object_detector/BUILD | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/ios/test/vision/image_classifier/BUILD b/mediapipe/tasks/ios/test/vision/image_classifier/BUILD index b84fb6a7e..6b038b453 100644 --- a/mediapipe/tasks/ios/test/vision/image_classifier/BUILD +++ b/mediapipe/tasks/ios/test/vision/image_classifier/BUILD @@ -41,7 +41,12 @@ objc_library( "//mediapipe/tasks/ios/common:MPPCommon", "//mediapipe/tasks/ios/test/vision/utils:MPPImageTestUtils", "//mediapipe/tasks/ios/vision/image_classifier:MPPImageClassifier", - ], + ] + select({ + ":opencv_ios_sim_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + ":opencv_ios_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + ":opencv_ios_x86_64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + "//conditions:default": ["@ios_opencv//:OpencvFramework"], + }), ) ios_unit_test( diff --git a/mediapipe/tasks/ios/test/vision/object_detector/BUILD b/mediapipe/tasks/ios/test/vision/object_detector/BUILD index 569fab4de..700deb560 100644 --- a/mediapipe/tasks/ios/test/vision/object_detector/BUILD +++ b/mediapipe/tasks/ios/test/vision/object_detector/BUILD @@ -41,7 +41,12 @@ objc_library( "//mediapipe/tasks/ios/common:MPPCommon", "//mediapipe/tasks/ios/test/vision/utils:MPPImageTestUtils", "//mediapipe/tasks/ios/vision/object_detector:MPPObjectDetector", - ], + ] + select({ + ":opencv_ios_sim_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + ":opencv_ios_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + ":opencv_ios_x86_64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + "//conditions:default": ["@ios_opencv//:OpencvFramework"], + }), ) ios_unit_test( From 72d6081263cc3164d94cbd82e33bd6a2b1614ce3 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Sat, 6 May 2023 04:59:19 +0530 Subject: [PATCH 222/753] Declared arrays for duplicate depepndencies --- mediapipe/tasks/ios/BUILD | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index 84cfeaa47..e2828b9cf 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -37,7 +37,7 @@ licenses(["notice"]) # Instead of linking options and containers, we link their helpers to # `MPPTasksCommon` to avoid duplicated method warnings in categories when text # and vision frameworks are installed in the same Xcode project. -OBJC_COMMON_DEPS = [ +OBJC_TASK_COMMON_DEPS = [ "//mediapipe/tasks/ios/core/utils:MPPBaseOptionsHelpers", "//mediapipe/tasks/ios/core:MPPTaskInfo", "//mediapipe/tasks/ios/core:MPPTaskOptions", @@ -46,12 +46,14 @@ OBJC_COMMON_DEPS = [ "//mediapipe/tasks/ios/components/containers/utils:MPPClassificationResultHelpers", "//mediapipe/tasks/ios/components/containers/utils:MPPCategoryHelpers", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", +] + +CALCULATORS_AND_GRAPHS = [ "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", "//mediapipe/calculators/core:flow_limiter_calculator", - "//mediapipe/gpu:metal_shared_resources", ] strip_api_include_path_prefix( @@ -88,7 +90,9 @@ apple_static_xcframework( # Avoid dependencies of ":MediaPipeTasksCommon_framework" and # ":MediaPipeTaskGraphs_library in order to prevent duplicate symbols error # when the frameworks are imported in iOS projects. - avoid_deps = OBJC_COMMON_DEPS, + avoid_deps = OBJC_TASK_COMMON_DEPS + CALCULATORS_AND_GRAPHS + [ + "//mediapipe/gpu:metal_shared_resources", + ], bundle_name = "MediaPipeTasksText", ios = { "simulator": [ @@ -129,7 +133,9 @@ apple_static_xcframework( # when the frameworks are imported in iOS projects. # Also avoids opencv since it will be built with # ":MediaPipeTaskGraphs_library". - avoid_deps = OBJC_COMMON_DEPS, + avoid_deps = OBJC_TASK_COMMON_DEPS + CALCULATORS_AND_GRAPHS + [ + "//mediapipe/gpu:metal_shared_resources", + ], bundle_name = "MediaPipeTasksVision", ios = { "simulator": [ @@ -174,12 +180,7 @@ apple_static_library( ], minimum_os_version = MPP_TASK_MINIMUM_OS_VERSION, platform_type = "ios", - deps = [ - "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", - "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", - "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", - "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", - "//mediapipe/calculators/core:flow_limiter_calculator", + deps = CALCULATORS_AND_GRAPHS + [ "@org_tensorflow//third_party/icu/data:conversion_data", ] + select({ "//third_party:opencv_ios_sim_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], @@ -209,14 +210,5 @@ apple_static_xcframework( minimum_os_versions = { "ios": MPP_TASK_MINIMUM_OS_VERSION, }, - deps = [ - "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", - "//mediapipe/tasks/ios/components/containers/utils:MPPCategoryHelpers", - "//mediapipe/tasks/ios/components/containers/utils:MPPClassificationResultHelpers", - "//mediapipe/tasks/ios/core/utils:MPPBaseOptionsHelpers", - "//mediapipe/tasks/ios/core:MPPTaskInfo", - "//mediapipe/tasks/ios/core:MPPTaskOptions", - "//mediapipe/tasks/ios/core:MPPTaskResult", - "//mediapipe/tasks/ios/core:MPPTaskRunner", - ], + deps = OBJC_TASK_COMMON_DEPS, ) From d79c0bbd3968be0a4c275b9ac228fb35774fe80a Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Sat, 6 May 2023 05:10:05 +0530 Subject: [PATCH 223/753] Updated formatting --- mediapipe/tasks/ios/build_ios_framework.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/mediapipe/tasks/ios/build_ios_framework.sh b/mediapipe/tasks/ios/build_ios_framework.sh index 64f3f5fc3..4e949daf4 100755 --- a/mediapipe/tasks/ios/build_ios_framework.sh +++ b/mediapipe/tasks/ios/build_ios_framework.sh @@ -79,6 +79,7 @@ def format(target): EOF local OUTPUT_PATH=$(bazel cquery $1 --output=starlark --starlark:file="${STARLARK_FILE}" 2> /dev/null) + rm -rf "${STARLARK_OUTPUT_TMPDIR}" echo ${OUTPUT_PATH} From 9f0dd03851ade673f14301d11543cd0f86f79328 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Sat, 6 May 2023 05:15:23 +0530 Subject: [PATCH 224/753] Updated comments --- third_party/opencv_ios_source.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/opencv_ios_source.bzl b/third_party/opencv_ios_source.bzl index ddf2e4136..3be3f6e02 100644 --- a/third_party/opencv_ios_source.bzl +++ b/third_party/opencv_ios_source.bzl @@ -27,7 +27,7 @@ _OPENCV_SIMULATOR_PLATFORM_DIR_NAME = "ios-arm64_x86_64-simulator" _OPENCV_DEVICE_PLATFORM_DIR_NAME = "ios-arm64" def _select_headers_impl(ctx): - # Should match with `/`. Othewise `ios-arm64` matches to `ios-arm64_x86-64` + # Should match with `/`. Othewise `ios-arm64` matches with `ios-arm64_x86-64` _files = [f for f in ctx.files.srcs if (f.basename.endswith(".h") or f.basename.endswith(".hpp")) and f.dirname.find(ctx.attr.platform + "/") != -1] From 3562a7f7dca888b35d99a3d7ab1cd0b02529858f Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Fri, 5 May 2023 17:29:52 -0700 Subject: [PATCH 225/753] Update one-class segmentation category mask behavior on GPU to match latest API PiperOrigin-RevId: 529853658 --- .../calculators/segmentation_postprocessor_gl.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mediapipe/tasks/cc/vision/image_segmenter/calculators/segmentation_postprocessor_gl.cc b/mediapipe/tasks/cc/vision/image_segmenter/calculators/segmentation_postprocessor_gl.cc index 5b212069f..311f8d6aa 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/calculators/segmentation_postprocessor_gl.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/calculators/segmentation_postprocessor_gl.cc @@ -188,7 +188,7 @@ void main() { // Special argmax shader for N=1 classes. We don't need to worry about softmax // activation (it is assumed softmax requires N > 1 classes), but this should // occur after SIGMOID activation if specified. Instead of a true argmax, we -// simply use 0.5 as the cutoff, assigning 1 (foreground) or 0 (background) +// simply use 0.5 as the cutoff, assigning 0 (foreground) or 255 (background) // based on whether the confidence value reaches this cutoff or not, // respectively. static constexpr char kArgmaxOneClassShader[] = R"( @@ -199,12 +199,12 @@ uniform sampler2D input_texture; void main() { float input_val = texture2D(input_texture, sample_coordinate).x; // Category is just value rounded to nearest integer; then we map to either - // 0 or 1/255 accordingly. If the input has been activated properly, then the + // 0 or 1 accordingly. If the input has been activated properly, then the // values should always be in the range [0, 1]. But just in case it hasn't, to // avoid category overflow issues when the activation function is not properly // chosen, we add an extra clamp here, as performance hit is minimal. - float category = clamp(floor(input_val + 0.5), 0.0, 1.0); - gl_FragColor = vec4(category / 255.0, 0.0, 0.0, 1.0); + float category = clamp(floor(1.5 - input_val), 0.0, 1.0); + gl_FragColor = vec4(category, 0.0, 0.0, 1.0); })"; // Softmax is in 3 steps: From f713be7b6d1f8b51995ed106198c6aa577c391da Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Sat, 6 May 2023 06:13:51 +0530 Subject: [PATCH 226/753] Updated deps names in iOS test targets --- mediapipe/tasks/ios/test/vision/image_classifier/BUILD | 6 +++--- mediapipe/tasks/ios/test/vision/object_detector/BUILD | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mediapipe/tasks/ios/test/vision/image_classifier/BUILD b/mediapipe/tasks/ios/test/vision/image_classifier/BUILD index 6b038b453..233dfd4c2 100644 --- a/mediapipe/tasks/ios/test/vision/image_classifier/BUILD +++ b/mediapipe/tasks/ios/test/vision/image_classifier/BUILD @@ -42,9 +42,9 @@ objc_library( "//mediapipe/tasks/ios/test/vision/utils:MPPImageTestUtils", "//mediapipe/tasks/ios/vision/image_classifier:MPPImageClassifier", ] + select({ - ":opencv_ios_sim_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], - ":opencv_ios_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], - ":opencv_ios_x86_64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + "//third_party:opencv_ios_sim_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + "//third_party:opencv_ios_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + "//third_party:opencv_ios_x86_64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], "//conditions:default": ["@ios_opencv//:OpencvFramework"], }), ) diff --git a/mediapipe/tasks/ios/test/vision/object_detector/BUILD b/mediapipe/tasks/ios/test/vision/object_detector/BUILD index 700deb560..13a4e9a8f 100644 --- a/mediapipe/tasks/ios/test/vision/object_detector/BUILD +++ b/mediapipe/tasks/ios/test/vision/object_detector/BUILD @@ -42,9 +42,9 @@ objc_library( "//mediapipe/tasks/ios/test/vision/utils:MPPImageTestUtils", "//mediapipe/tasks/ios/vision/object_detector:MPPObjectDetector", ] + select({ - ":opencv_ios_sim_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], - ":opencv_ios_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], - ":opencv_ios_x86_64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + "//third_party:opencv_ios_sim_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + "//third_party:opencv_ios_arm64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], + "//third_party:opencv_ios_x86_64_source_build" : ["@ios_opencv_source//:opencv_xcframework"], "//conditions:default": ["@ios_opencv//:OpencvFramework"], }), ) From e707c84a3de20bf50cddbaa5a8a402192c404d87 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 5 May 2023 19:21:50 -0700 Subject: [PATCH 227/753] Create a MediaPipe Mask Type PiperOrigin-RevId: 529868427 --- mediapipe/tasks/web/vision/BUILD | 1 + mediapipe/tasks/web/vision/core/BUILD | 21 ++ mediapipe/tasks/web/vision/core/mask.test.ts | 268 ++++++++++++++++ mediapipe/tasks/web/vision/core/mask.ts | 320 +++++++++++++++++++ mediapipe/tasks/web/vision/index.ts | 5 + mediapipe/tasks/web/vision/types.ts | 1 + 6 files changed, 616 insertions(+) create mode 100644 mediapipe/tasks/web/vision/core/mask.test.ts create mode 100644 mediapipe/tasks/web/vision/core/mask.ts diff --git a/mediapipe/tasks/web/vision/BUILD b/mediapipe/tasks/web/vision/BUILD index 503db3252..10e98de8b 100644 --- a/mediapipe/tasks/web/vision/BUILD +++ b/mediapipe/tasks/web/vision/BUILD @@ -21,6 +21,7 @@ VISION_LIBS = [ "//mediapipe/tasks/web/core:fileset_resolver", "//mediapipe/tasks/web/vision/core:drawing_utils", "//mediapipe/tasks/web/vision/core:image", + "//mediapipe/tasks/web/vision/core:mask", "//mediapipe/tasks/web/vision/face_detector", "//mediapipe/tasks/web/vision/face_landmarker", "//mediapipe/tasks/web/vision/face_stylizer", diff --git a/mediapipe/tasks/web/vision/core/BUILD b/mediapipe/tasks/web/vision/core/BUILD index 05a5b3b83..f6490d2ab 100644 --- a/mediapipe/tasks/web/vision/core/BUILD +++ b/mediapipe/tasks/web/vision/core/BUILD @@ -60,6 +60,27 @@ jasmine_node_test( deps = [":image_test_lib"], ) +mediapipe_ts_library( + name = "mask", + srcs = ["mask.ts"], + deps = [":image"], +) + +mediapipe_ts_library( + name = "mask_test_lib", + testonly = True, + srcs = ["mask.test.ts"], + deps = [ + ":image", + ":mask", + ], +) + +jasmine_node_test( + name = "mask_test", + deps = [":mask_test_lib"], +) + mediapipe_ts_library( name = "vision_task_runner", srcs = ["vision_task_runner.ts"], diff --git a/mediapipe/tasks/web/vision/core/mask.test.ts b/mediapipe/tasks/web/vision/core/mask.test.ts new file mode 100644 index 000000000..310a59ef3 --- /dev/null +++ b/mediapipe/tasks/web/vision/core/mask.test.ts @@ -0,0 +1,268 @@ +/** + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'jasmine'; + +import {MPImageShaderContext} from './image_shader_context'; +import {MPMask, MPMaskType} from './mask'; + +const WIDTH = 2; +const HEIGHT = 2; + +const skip = typeof document === 'undefined'; +if (skip) { + console.log('These tests must be run in a browser.'); +} + +/** The mask types supported by MPMask. */ +type MaskType = Uint8Array|Float32Array|WebGLTexture; + +const MASK_2_1 = [1, 2]; +const MASK_2_2 = [1, 2, 3, 4]; +const MASK_2_3 = [1, 2, 3, 4, 5, 6]; + +/** The test images and data to use for the unit tests below. */ +class MPMaskTestContext { + canvas!: OffscreenCanvas; + gl!: WebGL2RenderingContext; + uint8Array!: Uint8Array; + float32Array!: Float32Array; + webGLTexture!: WebGLTexture; + + async init(pixels = MASK_2_2, width = WIDTH, height = HEIGHT): Promise { + // Initialize a canvas with default dimensions. Note that the canvas size + // can be different from the mask size. + this.canvas = new OffscreenCanvas(WIDTH, HEIGHT); + this.gl = this.canvas.getContext('webgl2') as WebGL2RenderingContext; + + const gl = this.gl; + if (!gl.getExtension('EXT_color_buffer_float')) { + throw new Error('Missing required EXT_color_buffer_float extension'); + } + + this.uint8Array = new Uint8Array(pixels); + this.float32Array = new Float32Array(pixels.length); + for (let i = 0; i < this.uint8Array.length; ++i) { + this.float32Array[i] = pixels[i] / 255; + } + + this.webGLTexture = gl.createTexture()!; + + gl.bindTexture(gl.TEXTURE_2D, this.webGLTexture); + gl.texImage2D( + gl.TEXTURE_2D, 0, gl.R32F, width, height, 0, gl.RED, gl.FLOAT, + new Float32Array(pixels).map(v => v / 255)); + gl.bindTexture(gl.TEXTURE_2D, null); + } + + get(type: unknown) { + switch (type) { + case Uint8Array: + return this.uint8Array; + case Float32Array: + return this.float32Array; + case WebGLTexture: + return this.webGLTexture; + default: + throw new Error(`Unsupported type: ${type}`); + } + } + + close(): void { + this.gl.deleteTexture(this.webGLTexture); + } +} + +(skip ? xdescribe : describe)('MPMask', () => { + const context = new MPMaskTestContext(); + + afterEach(() => { + context.close(); + }); + + function readPixelsFromWebGLTexture(texture: WebGLTexture): Float32Array { + const pixels = new Float32Array(WIDTH * HEIGHT); + + const gl = context.gl; + gl.bindTexture(gl.TEXTURE_2D, texture); + + const framebuffer = gl.createFramebuffer()!; + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + gl.readPixels(0, 0, WIDTH, HEIGHT, gl.RED, gl.FLOAT, pixels); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteFramebuffer(framebuffer); + + gl.bindTexture(gl.TEXTURE_2D, null); + + // Sanity check values + expect(pixels[0]).not.toBe(0); + + return pixels; + } + + function assertEquality(mask: MPMask, expected: MaskType): void { + if (expected instanceof Uint8Array) { + const result = mask.get(MPMaskType.UINT8_ARRAY); + expect(result).toEqual(expected); + } else if (expected instanceof Float32Array) { + const result = mask.get(MPMaskType.FLOAT32_ARRAY); + expect(result).toEqual(expected); + } else { // WebGLTexture + const result = mask.get(MPMaskType.WEBGL_TEXTURE); + expect(readPixelsFromWebGLTexture(result)) + .toEqual(readPixelsFromWebGLTexture(expected)); + } + } + + function createImage( + shaderContext: MPImageShaderContext, input: MaskType, width: number, + height: number): MPMask { + return new MPMask( + [input], + /* ownsWebGLTexture= */ false, context.canvas, shaderContext, width, + height); + } + + function runConversionTest( + input: MaskType, output: MaskType, width = WIDTH, height = HEIGHT): void { + const shaderContext = new MPImageShaderContext(); + const mask = createImage(shaderContext, input, width, height); + assertEquality(mask, output); + mask.close(); + shaderContext.close(); + } + + function runCloneTest(input: MaskType): void { + const shaderContext = new MPImageShaderContext(); + const mask = createImage(shaderContext, input, WIDTH, HEIGHT); + const clone = mask.clone(); + assertEquality(clone, input); + clone.close(); + shaderContext.close(); + } + + const sources = skip ? [] : [Uint8Array, Float32Array, WebGLTexture]; + + for (let i = 0; i < sources.length; i++) { + for (let j = 0; j < sources.length; j++) { + it(`converts from ${sources[i].name} to ${sources[j].name}`, async () => { + await context.init(); + runConversionTest(context.get(sources[i]), context.get(sources[j])); + }); + } + } + + for (let i = 0; i < sources.length; i++) { + it(`clones ${sources[i].name}`, async () => { + await context.init(); + runCloneTest(context.get(sources[i])); + }); + } + + it(`does not flip textures twice`, async () => { + await context.init(); + + const shaderContext = new MPImageShaderContext(); + const mask = new MPMask( + [context.webGLTexture], + /* ownsWebGLTexture= */ false, context.canvas, shaderContext, WIDTH, + HEIGHT); + + const result = mask.clone().get(MPMaskType.UINT8_ARRAY); + expect(result).toEqual(context.uint8Array); + shaderContext.close(); + }); + + it(`can clone and get mask`, async () => { + await context.init(); + + const shaderContext = new MPImageShaderContext(); + const mask = new MPMask( + [context.webGLTexture], + /* ownsWebGLTexture= */ false, context.canvas, shaderContext, WIDTH, + HEIGHT); + + // Verify that we can mix the different shader modes by running them out of + // order. + let result = mask.get(MPMaskType.UINT8_ARRAY); + expect(result).toEqual(context.uint8Array); + + result = mask.clone().get(MPMaskType.UINT8_ARRAY); + expect(result).toEqual(context.uint8Array); + + result = mask.get(MPMaskType.UINT8_ARRAY); + expect(result).toEqual(context.uint8Array); + + shaderContext.close(); + }); + + it('supports has()', async () => { + await context.init(); + + const shaderContext = new MPImageShaderContext(); + const mask = createImage(shaderContext, context.uint8Array, WIDTH, HEIGHT); + + expect(mask.has(MPMaskType.UINT8_ARRAY)).toBe(true); + expect(mask.has(MPMaskType.FLOAT32_ARRAY)).toBe(false); + expect(mask.has(MPMaskType.WEBGL_TEXTURE)).toBe(false); + + mask.get(MPMaskType.FLOAT32_ARRAY); + + expect(mask.has(MPMaskType.UINT8_ARRAY)).toBe(true); + expect(mask.has(MPMaskType.FLOAT32_ARRAY)).toBe(true); + + mask.get(MPMaskType.WEBGL_TEXTURE); + + expect(mask.has(MPMaskType.UINT8_ARRAY)).toBe(true); + expect(mask.has(MPMaskType.FLOAT32_ARRAY)).toBe(true); + expect(mask.has(MPMaskType.WEBGL_TEXTURE)).toBe(true); + + mask.close(); + shaderContext.close(); + }); + + it('supports mask that is smaller than the canvas', async () => { + await context.init(MASK_2_1, /* width= */ 2, /* height= */ 1); + + runConversionTest( + context.uint8Array, context.webGLTexture, /* width= */ 2, + /* height= */ 1); + runConversionTest( + context.webGLTexture, context.float32Array, /* width= */ 2, + /* height= */ 1); + runConversionTest( + context.float32Array, context.uint8Array, /* width= */ 2, + /* height= */ 1); + + context.close(); + }); + + it('supports mask that is larger than the canvas', async () => { + await context.init(MASK_2_3, /* width= */ 2, /* height= */ 3); + + runConversionTest( + context.uint8Array, context.webGLTexture, /* width= */ 2, + /* height= */ 3); + runConversionTest( + context.webGLTexture, context.float32Array, /* width= */ 2, + /* height= */ 3); + runConversionTest( + context.float32Array, context.uint8Array, /* width= */ 2, + /* height= */ 3); + }); +}); diff --git a/mediapipe/tasks/web/vision/core/mask.ts b/mediapipe/tasks/web/vision/core/mask.ts new file mode 100644 index 000000000..a3dedf63a --- /dev/null +++ b/mediapipe/tasks/web/vision/core/mask.ts @@ -0,0 +1,320 @@ +/** + * Copyright 2023 The MediaPipe Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {assertNotNull, MPImageShaderContext} from '../../../../tasks/web/vision/core/image_shader_context'; + +/** The underlying type of the image. */ +export enum MPMaskType { + /** Represents the native `UInt8Array` type. */ + UINT8_ARRAY, + /** Represents the native `Float32Array` type. */ + FLOAT32_ARRAY, + /** Represents the native `WebGLTexture` type. */ + WEBGL_TEXTURE +} + +/** The supported mask formats. For internal usage. */ +export type MPMaskContainer = Uint8Array|Float32Array|WebGLTexture; + +/** + * The wrapper class for MediaPipe segmentation masks. + * + * Masks are stored as `Uint8Array`, `Float32Array` or `WebGLTexture` objects. + * You can convert the underlying type to any other type by passing the desired + * type to `get()`. As type conversions can be expensive, it is recommended to + * limit these conversions. You can verify what underlying types are already + * available by invoking `has()`. + * + * Masks that are returned from a MediaPipe Tasks are owned by by the + * underlying C++ Task. If you need to extend the lifetime of these objects, + * you can invoke the `clone()` method. To free up the resources obtained + * during any clone or type conversion operation, it is important to invoke + * `close()` on the `MPMask` instance. + */ +export class MPMask { + private gl?: WebGL2RenderingContext; + + /** The underlying type of the mask. */ + static TYPE = MPMaskType; + + /** @hideconstructor */ + constructor( + private readonly containers: MPMaskContainer[], + private ownsWebGLTexture: boolean, + /** Returns the canvas element that the mask is bound to. */ + readonly canvas: HTMLCanvasElement|OffscreenCanvas|undefined, + private shaderContext: MPImageShaderContext|undefined, + /** Returns the width of the mask. */ + readonly width: number, + /** Returns the height of the mask. */ + readonly height: number, + ) {} + + /** + * Returns whether this `MPMask` stores the mask in the desired + * format. This method can be called to reduce expensive conversion before + * invoking `get()`. + */ + has(type: MPMaskType): boolean { + return !!this.getContainer(type); + } + + /** + * Returns the underlying mask as a Uint8Array`. Note that this involves an + * expensive GPU to CPU transfer if the current mask is only available as a + * `WebGLTexture`. + * + * @param type The type of mask to return. + * @return The current data as a Uint8Array. + */ + get(type: MPMaskType.UINT8_ARRAY): Uint8Array; + /** + * Returns the underlying mask as a single channel `Float32Array`. Note that + * this involves an expensive GPU to CPU transfer if the current mask is only + * available as a `WebGLTexture`. + * + * @param type The type of mask to return. + * @return The current mask as a Float32Array. + */ + get(type: MPMaskType.FLOAT32_ARRAY): Float32Array; + /** + * Returns the underlying mask as a `WebGLTexture` object. Note that this + * involves a CPU to GPU transfer if the current mask is only available as + * a CPU array. The returned texture is bound to the current canvas (see + * `.canvas`). + * + * @param type The type of mask to return. + * @return The current mask as a WebGLTexture. + */ + get(type: MPMaskType.WEBGL_TEXTURE): WebGLTexture; + get(type?: MPMaskType): MPMaskContainer { + switch (type) { + case MPMaskType.UINT8_ARRAY: + return this.convertToUint8Array(); + case MPMaskType.FLOAT32_ARRAY: + return this.convertToFloat32Array(); + case MPMaskType.WEBGL_TEXTURE: + return this.convertToWebGLTexture(); + default: + throw new Error(`Type is not supported: ${type}`); + } + } + + + private getContainer(type: MPMaskType.UINT8_ARRAY): Uint8Array|undefined; + private getContainer(type: MPMaskType.FLOAT32_ARRAY): Float32Array|undefined; + private getContainer(type: MPMaskType.WEBGL_TEXTURE): WebGLTexture|undefined; + private getContainer(type: MPMaskType): MPMaskContainer|undefined; + /** Returns the container for the requested storage type iff it exists. */ + private getContainer(type: MPMaskType): MPMaskContainer|undefined { + switch (type) { + case MPMaskType.UINT8_ARRAY: + return this.containers.find(img => img instanceof Uint8Array); + case MPMaskType.FLOAT32_ARRAY: + return this.containers.find(img => img instanceof Float32Array); + case MPMaskType.WEBGL_TEXTURE: + return this.containers.find( + img => typeof WebGLTexture !== 'undefined' && + img instanceof WebGLTexture); + default: + throw new Error(`Type is not supported: ${type}`); + } + } + + /** + * Creates a copy of the resources stored in this `MPMask`. You can + * invoke this method to extend the lifetime of a mask returned by a + * MediaPipe Task. Note that performance critical applications should aim to + * only use the `MPMask` within the MediaPipe Task callback so that + * copies can be avoided. + */ + clone(): MPMask { + const destinationContainers: MPMaskContainer[] = []; + + // TODO: We might only want to clone one backing datastructure + // even if multiple are defined; + for (const container of this.containers) { + let destinationContainer: MPMaskContainer; + + if (container instanceof Uint8Array) { + destinationContainer = new Uint8Array(container); + } else if (container instanceof Float32Array) { + destinationContainer = new Float32Array(container); + } else if (container instanceof WebGLTexture) { + const gl = this.getGL(); + const shaderContext = this.getShaderContext(); + + // Create a new texture and use it to back a framebuffer + gl.activeTexture(gl.TEXTURE1); + destinationContainer = + assertNotNull(gl.createTexture(), 'Failed to create texture'); + gl.bindTexture(gl.TEXTURE_2D, destinationContainer); + gl.texImage2D( + gl.TEXTURE_2D, 0, gl.R32F, this.width, this.height, 0, gl.RED, + gl.FLOAT, null); + gl.bindTexture(gl.TEXTURE_2D, null); + + shaderContext.bindFramebuffer(gl, destinationContainer); + shaderContext.run(gl, /* flipVertically= */ false, () => { + this.bindTexture(); // This activates gl.TEXTURE0 + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + gl.drawArrays(gl.TRIANGLE_FAN, 0, 4); + this.unbindTexture(); + }); + shaderContext.unbindFramebuffer(); + + this.unbindTexture(); + } else { + throw new Error(`Type is not supported: ${container}`); + } + + destinationContainers.push(destinationContainer); + } + + return new MPMask( + destinationContainers, this.has(MPMaskType.WEBGL_TEXTURE), this.canvas, + this.shaderContext, this.width, this.height); + } + + private getGL(): WebGL2RenderingContext { + if (!this.canvas) { + throw new Error( + 'Conversion to different image formats require that a canvas ' + + 'is passed when iniitializing the image.'); + } + if (!this.gl) { + this.gl = assertNotNull( + this.canvas.getContext('webgl2') as WebGL2RenderingContext | null, + 'You cannot use a canvas that is already bound to a different ' + + 'type of rendering context.'); + } + const ext = this.gl.getExtension('EXT_color_buffer_float'); + if (!ext) { + // TODO: Ensure this works on iOS + throw new Error('Missing required EXT_color_buffer_float extension'); + } + return this.gl; + } + + private getShaderContext(): MPImageShaderContext { + if (!this.shaderContext) { + this.shaderContext = new MPImageShaderContext(); + } + return this.shaderContext; + } + + private convertToFloat32Array(): Float32Array { + let float32Array = this.getContainer(MPMaskType.FLOAT32_ARRAY); + if (!float32Array) { + if (this.has(MPMaskType.UINT8_ARRAY)) { + const source = this.getContainer(MPMaskType.UINT8_ARRAY)!; + float32Array = new Float32Array(source).map(v => v / 255); + } else { + const gl = this.getGL(); + const shaderContext = this.getShaderContext(); + float32Array = new Float32Array(this.width * this.height); + + // Create texture if needed + const webGlTexture = this.convertToWebGLTexture(); + + // Create a framebuffer from the texture and read back pixels + shaderContext.bindFramebuffer(gl, webGlTexture); + gl.readPixels( + 0, 0, this.width, this.height, gl.RED, gl.FLOAT, float32Array); + shaderContext.unbindFramebuffer(); + } + this.containers.push(float32Array); + } + + return float32Array; + } + + private convertToUint8Array(): Uint8Array { + let uint8Array = this.getContainer(MPMaskType.UINT8_ARRAY); + if (!uint8Array) { + const floatArray = this.convertToFloat32Array(); + uint8Array = new Uint8Array(floatArray.map(v => 255 * v)); + this.containers.push(uint8Array); + } + return uint8Array; + } + + private convertToWebGLTexture(): WebGLTexture { + let webGLTexture = this.getContainer(MPMaskType.WEBGL_TEXTURE); + if (!webGLTexture) { + const gl = this.getGL(); + webGLTexture = this.bindTexture(); + + const data = this.convertToFloat32Array(); + // TODO: Add support for R16F to support iOS + gl.texImage2D( + gl.TEXTURE_2D, 0, gl.R32F, this.width, this.height, 0, gl.RED, + gl.FLOAT, data); + this.unbindTexture(); + } + + return webGLTexture; + } + + /** + * Binds the backing texture to the canvas. If the texture does not yet + * exist, creates it first. + */ + private bindTexture(): WebGLTexture { + const gl = this.getGL(); + + gl.viewport(0, 0, this.width, this.height); + gl.activeTexture(gl.TEXTURE0); + + let webGLTexture = this.getContainer(MPMaskType.WEBGL_TEXTURE); + if (!webGLTexture) { + webGLTexture = + assertNotNull(gl.createTexture(), 'Failed to create texture'); + this.containers.push(webGLTexture); + this.ownsWebGLTexture = true; + } + + gl.bindTexture(gl.TEXTURE_2D, webGLTexture); + // TODO: Ideally, we would only set these once per texture and + // not once every frame. + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + + return webGLTexture; + } + + private unbindTexture(): void { + this.gl!.bindTexture(this.gl!.TEXTURE_2D, null); + } + + /** + * Frees up any resources owned by this `MPMask` instance. + * + * Note that this method does not free masks that are owned by the C++ + * Task, as these are freed automatically once you leave the MediaPipe + * callback. Additionally, some shared state is freed only once you invoke + * the Task's `close()` method. + */ + close(): void { + if (this.ownsWebGLTexture) { + const gl = this.getGL(); + gl.deleteTexture(this.getContainer(MPMaskType.WEBGL_TEXTURE)!); + } + } +} diff --git a/mediapipe/tasks/web/vision/index.ts b/mediapipe/tasks/web/vision/index.ts index 34c1206cc..4908f71f6 100644 --- a/mediapipe/tasks/web/vision/index.ts +++ b/mediapipe/tasks/web/vision/index.ts @@ -17,6 +17,7 @@ import {FilesetResolver as FilesetResolverImpl} from '../../../tasks/web/core/fileset_resolver'; import {DrawingUtils as DrawingUtilsImpl} from '../../../tasks/web/vision/core/drawing_utils'; import {MPImage as MPImageImpl, MPImageType as MPImageTypeImpl} from '../../../tasks/web/vision/core/image'; +import {MPMask as MPMaskImpl, MPMaskType as MPMaskTypeImpl} from '../../../tasks/web/vision/core/mask'; import {FaceDetector as FaceDetectorImpl} from '../../../tasks/web/vision/face_detector/face_detector'; import {FaceLandmarker as FaceLandmarkerImpl, FaceLandmarksConnections as FaceLandmarksConnectionsImpl} from '../../../tasks/web/vision/face_landmarker/face_landmarker'; import {FaceStylizer as FaceStylizerImpl} from '../../../tasks/web/vision/face_stylizer/face_stylizer'; @@ -35,6 +36,8 @@ const DrawingUtils = DrawingUtilsImpl; const FilesetResolver = FilesetResolverImpl; const MPImage = MPImageImpl; const MPImageType = MPImageTypeImpl; +const MPMask = MPMaskImpl; +const MPMaskType = MPMaskTypeImpl; const FaceDetector = FaceDetectorImpl; const FaceLandmarker = FaceLandmarkerImpl; const FaceLandmarksConnections = FaceLandmarksConnectionsImpl; @@ -53,6 +56,8 @@ export { FilesetResolver, MPImage, MPImageType, + MPMask, + MPMaskType, FaceDetector, FaceLandmarker, FaceLandmarksConnections, diff --git a/mediapipe/tasks/web/vision/types.ts b/mediapipe/tasks/web/vision/types.ts index 164276bab..ec3b88d68 100644 --- a/mediapipe/tasks/web/vision/types.ts +++ b/mediapipe/tasks/web/vision/types.ts @@ -17,6 +17,7 @@ export * from '../../../tasks/web/core/fileset_resolver'; export * from '../../../tasks/web/vision/core/drawing_utils'; export {MPImage, MPImageChannelConverter, MPImageType} from '../../../tasks/web/vision/core/image'; +export {MPMask, MPMaskType} from '../../../tasks/web/vision/core/mask'; export * from '../../../tasks/web/vision/face_detector/face_detector'; export * from '../../../tasks/web/vision/face_landmarker/face_landmarker'; export * from '../../../tasks/web/vision/face_stylizer/face_stylizer'; From 6aad5742c3fe6fddba6514018c8f8b87a0bffab3 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 5 May 2023 21:49:52 -0700 Subject: [PATCH 228/753] Internal PiperOrigin-RevId: 529890599 --- mediapipe/tasks/web/vision/core/BUILD | 1 + .../tasks/web/vision/core/render_utils.ts | 41 ++++++++++++--- .../web/vision/core/vision_task_runner.ts | 51 +++++++++++++------ .../face_stylizer/face_stylizer_test.ts | 4 +- .../tasks/web/vision/image_segmenter/BUILD | 4 +- .../vision/image_segmenter/image_segmenter.ts | 4 +- .../image_segmenter_result.d.ts | 6 +-- .../image_segmenter/image_segmenter_test.ts | 22 ++++---- .../web/vision/interactive_segmenter/BUILD | 4 +- .../interactive_segmenter.ts | 4 +- .../interactive_segmenter_result.d.ts | 6 +-- .../interactive_segmenter_test.ts | 22 ++++---- .../tasks/web/vision/pose_landmarker/BUILD | 4 +- .../vision/pose_landmarker/pose_landmarker.ts | 2 +- .../pose_landmarker_result.d.ts | 4 +- .../pose_landmarker/pose_landmarker_test.ts | 4 +- .../graph_runner/graph_runner_image_lib.ts | 2 +- 17 files changed, 117 insertions(+), 68 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/BUILD b/mediapipe/tasks/web/vision/core/BUILD index f6490d2ab..4bda4218a 100644 --- a/mediapipe/tasks/web/vision/core/BUILD +++ b/mediapipe/tasks/web/vision/core/BUILD @@ -87,6 +87,7 @@ mediapipe_ts_library( deps = [ ":image", ":image_processing_options", + ":mask", ":vision_task_options", "//mediapipe/framework/formats:rect_jspb_proto", "//mediapipe/tasks/web/core", diff --git a/mediapipe/tasks/web/vision/core/render_utils.ts b/mediapipe/tasks/web/vision/core/render_utils.ts index 05f2a4df1..ebb3be16a 100644 --- a/mediapipe/tasks/web/vision/core/render_utils.ts +++ b/mediapipe/tasks/web/vision/core/render_utils.ts @@ -16,8 +16,6 @@ * limitations under the License. */ -import {MPImageChannelConverter} from '../../../../tasks/web/vision/core/image'; - // Pre-baked color table for a maximum of 12 classes. const CM_ALPHA = 128; const COLOR_MAP: Array<[number, number, number, number]> = [ @@ -35,8 +33,37 @@ const COLOR_MAP: Array<[number, number, number, number]> = [ [255, 255, 255, CM_ALPHA] // class 11 is white; could do black instead? ]; -/** The color converter we use in our demos. */ -export const RENDER_UTIL_CONVERTER: MPImageChannelConverter = { - floatToRGBAConverter: v => [128, 0, 0, v * 255], - uint8ToRGBAConverter: v => COLOR_MAP[v % COLOR_MAP.length], -}; + +/** Helper function to draw a confidence mask */ +export function drawConfidenceMask( + ctx: CanvasRenderingContext2D, image: Float32Array, width: number, + height: number): void { + const uint8Array = new Uint8ClampedArray(width * height * 4); + for (let i = 0; i < image.length; i++) { + uint8Array[4 * i] = 128; + uint8Array[4 * i + 1] = 0; + uint8Array[4 * i + 2] = 0; + uint8Array[4 * i + 3] = image[i] * 255; + } + ctx.putImageData(new ImageData(uint8Array, width, height), 0, 0); +} + +/** + * Helper function to draw a category mask. For GPU, we only have F32Arrays + * for now. + */ +export function drawCategoryMask( + ctx: CanvasRenderingContext2D, image: Uint8Array|Float32Array, + width: number, height: number): void { + const rgbaArray = new Uint8ClampedArray(width * height * 4); + const isFloatArray = image instanceof Float32Array; + for (let i = 0; i < image.length; i++) { + const colorIndex = isFloatArray ? Math.round(image[i] * 255) : image[i]; + const color = COLOR_MAP[colorIndex % COLOR_MAP.length]; + rgbaArray[4 * i] = color[0]; + rgbaArray[4 * i + 1] = color[1]; + rgbaArray[4 * i + 2] = color[2]; + rgbaArray[4 * i + 3] = color[3]; + } + ctx.putImageData(new ImageData(rgbaArray, width, height), 0, 0); +} diff --git a/mediapipe/tasks/web/vision/core/vision_task_runner.ts b/mediapipe/tasks/web/vision/core/vision_task_runner.ts index c31195508..0dc380e2a 100644 --- a/mediapipe/tasks/web/vision/core/vision_task_runner.ts +++ b/mediapipe/tasks/web/vision/core/vision_task_runner.ts @@ -20,6 +20,7 @@ import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; import {MPImage} from '../../../../tasks/web/vision/core/image'; import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; import {MPImageShaderContext} from '../../../../tasks/web/vision/core/image_shader_context'; +import {MPMask} from '../../../../tasks/web/vision/core/mask'; import {GraphRunner, ImageSource, WasmMediaPipeConstructor} from '../../../../web/graph_runner/graph_runner'; import {SupportImage, WasmImage} from '../../../../web/graph_runner/graph_runner_image_lib'; import {isWebKit} from '../../../../web/graph_runner/platform_utils'; @@ -226,7 +227,7 @@ export abstract class VisionTaskRunner extends TaskRunner { /** * Converts a WasmImage to an MPImage. * - * Converts the underlying Uint8ClampedArray-backed images to ImageData + * Converts the underlying Uint8Array-backed images to ImageData * (adding an alpha channel if necessary), passes through WebGLTextures and * throws for Float32Array-backed images. */ @@ -235,11 +236,9 @@ export abstract class VisionTaskRunner extends TaskRunner { const {data, width, height} = wasmImage; const pixels = width * height; - let container: ImageData|WebGLTexture|Uint8ClampedArray; - if (data instanceof Uint8ClampedArray) { - if (data.length === pixels) { - container = data; // Mask - } else if (data.length === pixels * 3) { + let container: ImageData|WebGLTexture; + if (data instanceof Uint8Array) { + if (data.length === pixels * 3) { // TODO: Convert in C++ const rgba = new Uint8ClampedArray(pixels * 4); for (let i = 0; i < pixels; ++i) { @@ -249,19 +248,17 @@ export abstract class VisionTaskRunner extends TaskRunner { rgba[4 * i + 3] = 255; } container = new ImageData(rgba, width, height); - } else if (data.length ===pixels * 4) { - container = new ImageData(data, width, height); + } else if (data.length === pixels * 4) { + container = new ImageData( + new Uint8ClampedArray(data.buffer, data.byteOffset, data.length), + width, height); } else { throw new Error(`Unsupported channel count: ${data.length/pixels}`); } - } else if (data instanceof Float32Array) { - if (data.length === pixels) { - container = data; // Mask - } else { - throw new Error(`Unsupported channel count: ${data.length/pixels}`); - } - } else { // WebGLTexture + } else if (data instanceof WebGLTexture) { container = data; + } else { + throw new Error(`Unsupported format: ${data.constructor.name}`); } const image = new MPImage( @@ -271,6 +268,30 @@ export abstract class VisionTaskRunner extends TaskRunner { return shouldCopyData ? image.clone() : image; } + /** Converts a WasmImage to an MPMask. */ + protected convertToMPMask(wasmImage: WasmImage, shouldCopyData: boolean): + MPMask { + const {data, width, height} = wasmImage; + const pixels = width * height; + + let container: WebGLTexture|Uint8Array|Float32Array; + if (data instanceof Uint8Array || data instanceof Float32Array) { + if (data.length === pixels) { + container = data; + } else { + throw new Error(`Unsupported channel count: ${data.length / pixels}`); + } + } else { + container = data; + } + + const mask = new MPMask( + [container], + /* ownsWebGLTexture= */ false, this.graphRunner.wasmModule.canvas!, + this.shaderContext, width, height); + return shouldCopyData ? mask.clone() : mask; + } + /** Closes and cleans up the resources held by this task. */ override close(): void { this.shaderContext.close(); diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts index 8ea8e0f94..704feef69 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts @@ -109,7 +109,7 @@ describe('FaceStylizer', () => { faceStylizer.fakeWasmModule._waitUntilIdle.and.callFake(() => { verifyListenersRegistered(faceStylizer); faceStylizer.imageListener! - ({data: new Uint8ClampedArray([1, 1, 1, 1]), width: 1, height: 1}, + ({data: new Uint8Array([1, 1, 1, 1]), width: 1, height: 1}, /* timestamp= */ 1337); }); @@ -134,7 +134,7 @@ describe('FaceStylizer', () => { faceStylizer.fakeWasmModule._waitUntilIdle.and.callFake(() => { verifyListenersRegistered(faceStylizer); faceStylizer.imageListener! - ({data: new Uint8ClampedArray([1, 1, 1, 1]), width: 1, height: 1}, + ({data: new Uint8Array([1, 1, 1, 1]), width: 1, height: 1}, /* timestamp= */ 1337); }); diff --git a/mediapipe/tasks/web/vision/image_segmenter/BUILD b/mediapipe/tasks/web/vision/image_segmenter/BUILD index 6c1829bd3..1a008cc95 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/BUILD +++ b/mediapipe/tasks/web/vision/image_segmenter/BUILD @@ -35,7 +35,7 @@ mediapipe_ts_declaration( deps = [ "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:classifier_options", - "//mediapipe/tasks/web/vision/core:image", + "//mediapipe/tasks/web/vision/core:mask", "//mediapipe/tasks/web/vision/core:vision_task_options", ], ) @@ -52,7 +52,7 @@ mediapipe_ts_library( "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", - "//mediapipe/tasks/web/vision/core:image", + "//mediapipe/tasks/web/vision/core:mask", "//mediapipe/web/graph_runner:graph_runner_image_lib_ts", ], ) diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts index b4e9f804d..39e57d94e 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts @@ -412,7 +412,7 @@ export class ImageSegmenter extends VisionTaskRunner { this.graphRunner.attachImageVectorListener( CONFIDENCE_MASKS_STREAM, (masks, timestamp) => { this.result.confidenceMasks = masks.map( - wasmImage => this.convertToMPImage( + wasmImage => this.convertToMPMask( wasmImage, /* shouldCopyData= */ !this.userCallback)); this.setLatestOutputTimestamp(timestamp); this.maybeInvokeCallback(); @@ -431,7 +431,7 @@ export class ImageSegmenter extends VisionTaskRunner { this.graphRunner.attachImageListener( CATEGORY_MASK_STREAM, (mask, timestamp) => { - this.result.categoryMask = this.convertToMPImage( + this.result.categoryMask = this.convertToMPMask( mask, /* shouldCopyData= */ !this.userCallback); this.setLatestOutputTimestamp(timestamp); this.maybeInvokeCallback(); diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts index 454ec27ea..25962d57e 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import {MPImage} from '../../../../tasks/web/vision/core/image'; +import {MPMask} from '../../../../tasks/web/vision/core/mask'; /** The output result of ImageSegmenter. */ export declare interface ImageSegmenterResult { @@ -23,12 +23,12 @@ export declare interface ImageSegmenterResult { * `MPImage`s where, for each mask, each pixel represents the prediction * confidence, usually in the [0, 1] range. */ - confidenceMasks?: MPImage[]; + confidenceMasks?: MPMask[]; /** * A category mask represented as a `Uint8ClampedArray` or * `WebGLTexture`-backed `MPImage` where each pixel represents the class which * the pixel in the original image was predicted to belong to. */ - categoryMask?: MPImage; + categoryMask?: MPMask; } diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts index f9a4fe8a6..f9172ecd3 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts @@ -19,8 +19,8 @@ import 'jasmine'; // Placeholder for internal dependency on encodeByteArray import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; import {addJasmineCustomFloatEqualityTester, createSpyWasmModule, MediapipeTasksFake, SpyWasmModule, verifyGraph} from '../../../../tasks/web/core/task_runner_test_utils'; +import {MPMask} from '../../../../tasks/web/vision/core/mask'; import {WasmImage} from '../../../../web/graph_runner/graph_runner_image_lib'; -import {MPImage} from '../../../../tasks/web/vision/core/image'; import {ImageSegmenter} from './image_segmenter'; import {ImageSegmenterOptions} from './image_segmenter_options'; @@ -165,7 +165,7 @@ describe('ImageSegmenter', () => { }); it('supports category mask', async () => { - const mask = new Uint8ClampedArray([1, 2, 3, 4]); + const mask = new Uint8Array([1, 2, 3, 4]); await imageSegmenter.setOptions( {outputCategoryMask: true, outputConfidenceMasks: false}); @@ -183,7 +183,7 @@ describe('ImageSegmenter', () => { return new Promise(resolve => { imageSegmenter.segment({} as HTMLImageElement, result => { expect(imageSegmenter.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); - expect(result.categoryMask).toBeInstanceOf(MPImage); + expect(result.categoryMask).toBeInstanceOf(MPMask); expect(result.confidenceMasks).not.toBeDefined(); expect(result.categoryMask!.width).toEqual(2); expect(result.categoryMask!.height).toEqual(2); @@ -216,18 +216,18 @@ describe('ImageSegmenter', () => { expect(imageSegmenter.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); expect(result.categoryMask).not.toBeDefined(); - expect(result.confidenceMasks![0]).toBeInstanceOf(MPImage); + expect(result.confidenceMasks![0]).toBeInstanceOf(MPMask); expect(result.confidenceMasks![0].width).toEqual(2); expect(result.confidenceMasks![0].height).toEqual(2); - expect(result.confidenceMasks![1]).toBeInstanceOf(MPImage); + expect(result.confidenceMasks![1]).toBeInstanceOf(MPMask); resolve(); }); }); }); it('supports combined category and confidence masks', async () => { - const categoryMask = new Uint8ClampedArray([1]); + const categoryMask = new Uint8Array([1]); const confidenceMask1 = new Float32Array([0.0]); const confidenceMask2 = new Float32Array([1.0]); @@ -252,19 +252,19 @@ describe('ImageSegmenter', () => { // Invoke the image segmenter imageSegmenter.segment({} as HTMLImageElement, result => { expect(imageSegmenter.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); - expect(result.categoryMask).toBeInstanceOf(MPImage); + expect(result.categoryMask).toBeInstanceOf(MPMask); expect(result.categoryMask!.width).toEqual(1); expect(result.categoryMask!.height).toEqual(1); - expect(result.confidenceMasks![0]).toBeInstanceOf(MPImage); - expect(result.confidenceMasks![1]).toBeInstanceOf(MPImage); + expect(result.confidenceMasks![0]).toBeInstanceOf(MPMask); + expect(result.confidenceMasks![1]).toBeInstanceOf(MPMask); resolve(); }); }); }); it('invokes listener once masks are available', async () => { - const categoryMask = new Uint8ClampedArray([1]); + const categoryMask = new Uint8Array([1]); const confidenceMask = new Float32Array([0.0]); let listenerCalled = false; @@ -306,7 +306,7 @@ describe('ImageSegmenter', () => { }); const result = imageSegmenter.segment({} as HTMLImageElement); - expect(result.confidenceMasks![0]).toBeInstanceOf(MPImage); + expect(result.confidenceMasks![0]).toBeInstanceOf(MPMask); result.confidenceMasks![0].close(); }); }); diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/BUILD b/mediapipe/tasks/web/vision/interactive_segmenter/BUILD index c3be79ebf..57b0946a2 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/BUILD +++ b/mediapipe/tasks/web/vision/interactive_segmenter/BUILD @@ -37,7 +37,7 @@ mediapipe_ts_declaration( deps = [ "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:classifier_options", - "//mediapipe/tasks/web/vision/core:image", + "//mediapipe/tasks/web/vision/core:mask", "//mediapipe/tasks/web/vision/core:vision_task_options", ], ) @@ -54,7 +54,7 @@ mediapipe_ts_library( "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", - "//mediapipe/tasks/web/vision/core:image", + "//mediapipe/tasks/web/vision/core:mask", "//mediapipe/util:render_data_jspb_proto", "//mediapipe/web/graph_runner:graph_runner_image_lib_ts", ], diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts index 72dfd3834..2a51a5fcf 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts @@ -328,7 +328,7 @@ export class InteractiveSegmenter extends VisionTaskRunner { this.graphRunner.attachImageVectorListener( CONFIDENCE_MASKS_STREAM, (masks, timestamp) => { this.result.confidenceMasks = masks.map( - wasmImage => this.convertToMPImage( + wasmImage => this.convertToMPMask( wasmImage, /* shouldCopyData= */ !this.userCallback)); this.setLatestOutputTimestamp(timestamp); this.maybeInvokeCallback(); @@ -347,7 +347,7 @@ export class InteractiveSegmenter extends VisionTaskRunner { this.graphRunner.attachImageListener( CATEGORY_MASK_STREAM, (mask, timestamp) => { - this.result.categoryMask = this.convertToMPImage( + this.result.categoryMask = this.convertToMPMask( mask, /* shouldCopyData= */ !this.userCallback); this.setLatestOutputTimestamp(timestamp); this.maybeInvokeCallback(); diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts index bc2962936..e773b5e64 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import {MPImage} from '../../../../tasks/web/vision/core/image'; +import {MPMask} from '../../../../tasks/web/vision/core/mask'; /** The output result of InteractiveSegmenter. */ export declare interface InteractiveSegmenterResult { @@ -23,12 +23,12 @@ export declare interface InteractiveSegmenterResult { * `MPImage`s where, for each mask, each pixel represents the prediction * confidence, usually in the [0, 1] range. */ - confidenceMasks?: MPImage[]; + confidenceMasks?: MPMask[]; /** * A category mask represented as a `Uint8ClampedArray` or * `WebGLTexture`-backed `MPImage` where each pixel represents the class which * the pixel in the original image was predicted to belong to. */ - categoryMask?: MPImage; + categoryMask?: MPMask; } diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts index 52742e371..c5603c5c6 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts @@ -19,7 +19,7 @@ import 'jasmine'; // Placeholder for internal dependency on encodeByteArray import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; import {addJasmineCustomFloatEqualityTester, createSpyWasmModule, MediapipeTasksFake, SpyWasmModule, verifyGraph} from '../../../../tasks/web/core/task_runner_test_utils'; -import {MPImage} from '../../../../tasks/web/vision/core/image'; +import {MPMask} from '../../../../tasks/web/vision/core/mask'; import {RenderData as RenderDataProto} from '../../../../util/render_data_pb'; import {WasmImage} from '../../../../web/graph_runner/graph_runner_image_lib'; @@ -177,7 +177,7 @@ describe('InteractiveSegmenter', () => { }); it('supports category mask', async () => { - const mask = new Uint8ClampedArray([1, 2, 3, 4]); + const mask = new Uint8Array([1, 2, 3, 4]); await interactiveSegmenter.setOptions( {outputCategoryMask: true, outputConfidenceMasks: false}); @@ -195,7 +195,7 @@ describe('InteractiveSegmenter', () => { interactiveSegmenter.segment({} as HTMLImageElement, KEYPOINT, result => { expect(interactiveSegmenter.fakeWasmModule._waitUntilIdle) .toHaveBeenCalled(); - expect(result.categoryMask).toBeInstanceOf(MPImage); + expect(result.categoryMask).toBeInstanceOf(MPMask); expect(result.categoryMask!.width).toEqual(2); expect(result.categoryMask!.height).toEqual(2); expect(result.confidenceMasks).not.toBeDefined(); @@ -228,18 +228,18 @@ describe('InteractiveSegmenter', () => { .toHaveBeenCalled(); expect(result.categoryMask).not.toBeDefined(); - expect(result.confidenceMasks![0]).toBeInstanceOf(MPImage); + expect(result.confidenceMasks![0]).toBeInstanceOf(MPMask); expect(result.confidenceMasks![0].width).toEqual(2); expect(result.confidenceMasks![0].height).toEqual(2); - expect(result.confidenceMasks![1]).toBeInstanceOf(MPImage); + expect(result.confidenceMasks![1]).toBeInstanceOf(MPMask); resolve(); }); }); }); it('supports combined category and confidence masks', async () => { - const categoryMask = new Uint8ClampedArray([1]); + const categoryMask = new Uint8Array([1]); const confidenceMask1 = new Float32Array([0.0]); const confidenceMask2 = new Float32Array([1.0]); @@ -266,19 +266,19 @@ describe('InteractiveSegmenter', () => { {} as HTMLImageElement, KEYPOINT, result => { expect(interactiveSegmenter.fakeWasmModule._waitUntilIdle) .toHaveBeenCalled(); - expect(result.categoryMask).toBeInstanceOf(MPImage); + expect(result.categoryMask).toBeInstanceOf(MPMask); expect(result.categoryMask!.width).toEqual(1); expect(result.categoryMask!.height).toEqual(1); - expect(result.confidenceMasks![0]).toBeInstanceOf(MPImage); - expect(result.confidenceMasks![1]).toBeInstanceOf(MPImage); + expect(result.confidenceMasks![0]).toBeInstanceOf(MPMask); + expect(result.confidenceMasks![1]).toBeInstanceOf(MPMask); resolve(); }); }); }); it('invokes listener once masks are avaiblae', async () => { - const categoryMask = new Uint8ClampedArray([1]); + const categoryMask = new Uint8Array([1]); const confidenceMask = new Float32Array([0.0]); let listenerCalled = false; @@ -321,7 +321,7 @@ describe('InteractiveSegmenter', () => { const result = interactiveSegmenter.segment({} as HTMLImageElement, KEYPOINT); - expect(result.confidenceMasks![0]).toBeInstanceOf(MPImage); + expect(result.confidenceMasks![0]).toBeInstanceOf(MPMask); result.confidenceMasks![0].close(); }); }); diff --git a/mediapipe/tasks/web/vision/pose_landmarker/BUILD b/mediapipe/tasks/web/vision/pose_landmarker/BUILD index 8d128ac1a..566513b40 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/BUILD +++ b/mediapipe/tasks/web/vision/pose_landmarker/BUILD @@ -45,7 +45,7 @@ mediapipe_ts_declaration( "//mediapipe/tasks/web/components/containers:category", "//mediapipe/tasks/web/components/containers:landmark", "//mediapipe/tasks/web/core", - "//mediapipe/tasks/web/vision/core:image", + "//mediapipe/tasks/web/vision/core:mask", "//mediapipe/tasks/web/vision/core:vision_task_options", ], ) @@ -63,7 +63,7 @@ mediapipe_ts_library( "//mediapipe/tasks/web/components/processors:landmark_result", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", - "//mediapipe/tasks/web/vision/core:image", + "//mediapipe/tasks/web/vision/core:mask", "//mediapipe/tasks/web/vision/core:vision_task_runner", ], ) diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts index 7cb37d5e2..cecf16225 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts @@ -504,7 +504,7 @@ export class PoseLandmarker extends VisionTaskRunner { this.graphRunner.attachImageVectorListener( SEGMENTATION_MASK_STREAM, (masks, timestamp) => { this.result.segmentationMasks = masks.map( - wasmImage => this.convertToMPImage( + wasmImage => this.convertToMPMask( wasmImage, /* shouldCopyData= */ !this.userCallback)); this.setLatestOutputTimestamp(timestamp); this.maybeInvokeCallback(); diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts index d4d3d3bec..980408069 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts @@ -16,7 +16,7 @@ import {Category} from '../../../../tasks/web/components/containers/category'; import {Landmark, NormalizedLandmark} from '../../../../tasks/web/components/containers/landmark'; -import {MPImage} from '../../../../tasks/web/vision/core/image'; +import {MPMask} from '../../../../tasks/web/vision/core/mask'; export {Category, Landmark, NormalizedLandmark}; @@ -35,5 +35,5 @@ export declare interface PoseLandmarkerResult { auxilaryLandmarks: NormalizedLandmark[][]; /** Segmentation mask for the detected pose. */ - segmentationMasks?: MPImage[]; + segmentationMasks?: MPMask[]; } diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts index 62efa5a3c..bb04ce683 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts @@ -18,7 +18,7 @@ import 'jasmine'; import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; import {createLandmarks, createWorldLandmarks} from '../../../../tasks/web/components/processors/landmark_result_test_lib'; import {addJasmineCustomFloatEqualityTester, createSpyWasmModule, MediapipeTasksFake, SpyWasmModule, verifyGraph} from '../../../../tasks/web/core/task_runner_test_utils'; -import {MPImage} from '../../../../tasks/web/vision/core/image'; +import {MPMask} from '../../../../tasks/web/vision/core/mask'; import {VisionGraphRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; import {PoseLandmarker} from './pose_landmarker'; @@ -225,7 +225,7 @@ describe('PoseLandmarker', () => { expect(result.landmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); expect(result.worldLandmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); expect(result.auxilaryLandmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); - expect(result.segmentationMasks![0]).toBeInstanceOf(MPImage); + expect(result.segmentationMasks![0]).toBeInstanceOf(MPMask); done(); }); }); diff --git a/mediapipe/web/graph_runner/graph_runner_image_lib.ts b/mediapipe/web/graph_runner/graph_runner_image_lib.ts index 8b491d891..d2d6e52a8 100644 --- a/mediapipe/web/graph_runner/graph_runner_image_lib.ts +++ b/mediapipe/web/graph_runner/graph_runner_image_lib.ts @@ -10,7 +10,7 @@ type LibConstructor = new (...args: any[]) => GraphRunner; /** An image returned from a MediaPipe graph. */ export interface WasmImage { - data: Uint8ClampedArray|Float32Array|WebGLTexture; + data: Uint8Array|Float32Array|WebGLTexture; width: number; height: number; } From fb7f06b509f9c33bc2b86870e4293db6bf6d00af Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 5 May 2023 23:20:22 -0700 Subject: [PATCH 229/753] Remove error check that canvas must be defined PiperOrigin-RevId: 529906685 --- mediapipe/tasks/web/vision/core/vision_task_runner.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/vision_task_runner.ts b/mediapipe/tasks/web/vision/core/vision_task_runner.ts index 0dc380e2a..f8f7826d0 100644 --- a/mediapipe/tasks/web/vision/core/vision_task_runner.ts +++ b/mediapipe/tasks/web/vision/core/vision_task_runner.ts @@ -59,11 +59,6 @@ export abstract class VisionTaskRunner extends TaskRunner { protected static async createVisionInstance( type: WasmMediaPipeConstructor, fileset: WasmFileset, options: VisionTaskOptions): Promise { - if (options.baseOptions?.delegate === 'GPU') { - if (!options.canvas) { - throw new Error('You must specify a canvas for GPU processing.'); - } - } const canvas = options.canvas ?? createCanvas(); return TaskRunner.createInstance(type, canvas, fileset, options); } From cc8847def5c13263d361340a354d3987c0dd276e Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Sat, 6 May 2023 00:53:36 -0700 Subject: [PATCH 230/753] Update one-class segmentation category mask behavior on CPU to match latest API PiperOrigin-RevId: 529917830 --- .../tensors_to_segmentation_calculator.cc | 10 ++++-- .../image_segmenter/image_segmenter_test.cc | 33 +++++++++++++++++-- third_party/external_files.bzl | 16 ++++----- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.cc b/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.cc index c2d1520dd..660dc59b7 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.cc @@ -61,6 +61,8 @@ using ::mediapipe::tasks::vision::GetImageLikeTensorShape; using ::mediapipe::tasks::vision::Shape; using ::mediapipe::tasks::vision::image_segmenter::proto::SegmenterOptions; +constexpr uint8_t kUnLabeledPixelValue = 255; + void StableSoftmax(absl::Span values, absl::Span activated_values) { float max_value = *std::max_element(values.begin(), values.end()); @@ -153,9 +155,11 @@ Image ProcessForCategoryMaskCpu(const Shape& input_shape, } if (input_channels == 1) { // if the input tensor is a single mask, it is assumed to be a binary - // foreground segmentation mask. For such a mask, we make foreground - // category 1, and background category 0. - pixel = static_cast(confidence_scores[0] > 0.5f); + // foreground segmentation mask. For such a mask, instead of a true + // argmax, we simply use 0.5 as the cutoff, assigning 0 (foreground) or + // 255 (background) based on whether the confidence value reaches this + // cutoff or not, respectively. + pixel = confidence_scores[0] > 0.5f ? 0 : kUnLabeledPixelValue; } else { const int maximum_category_idx = std::max_element(confidence_scores.begin(), confidence_scores.end()) - diff --git a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_test.cc b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_test.cc index 339ec1424..656ed0715 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_test.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_test.cc @@ -30,6 +30,7 @@ limitations under the License. #include "mediapipe/framework/port/opencv_imgcodecs_inc.h" #include "mediapipe/framework/port/opencv_imgproc_inc.h" #include "mediapipe/framework/port/status_matchers.h" +#include "mediapipe/framework/tool/test_util.h" #include "mediapipe/tasks/cc/components/containers/rect.h" #include "mediapipe/tasks/cc/core/base_options.h" #include "mediapipe/tasks/cc/core/proto/base_options.pb.h" @@ -425,6 +426,28 @@ TEST_F(ImageModeTest, SucceedsSelfie144x256Segmentations) { SimilarToFloatMask(expected_mask_float, kGoldenMaskSimilarity)); } +TEST_F(ImageModeTest, SucceedsSelfieSegmentationSingleLabel) { + auto options = std::make_unique(); + options->base_options.model_asset_path = + JoinPath("./", kTestDataDirectory, kSelfieSegmentation); + MP_ASSERT_OK_AND_ASSIGN(std::unique_ptr segmenter, + ImageSegmenter::Create(std::move(options))); + ASSERT_EQ(segmenter->GetLabels().size(), 1); + EXPECT_EQ(segmenter->GetLabels()[0], "selfie"); + MP_ASSERT_OK(segmenter->Close()); +} + +TEST_F(ImageModeTest, SucceedsSelfieSegmentationLandscapeSingleLabel) { + auto options = std::make_unique(); + options->base_options.model_asset_path = + JoinPath("./", kTestDataDirectory, kSelfieSegmentationLandscape); + MP_ASSERT_OK_AND_ASSIGN(std::unique_ptr segmenter, + ImageSegmenter::Create(std::move(options))); + ASSERT_EQ(segmenter->GetLabels().size(), 1); + EXPECT_EQ(segmenter->GetLabels()[0], "selfie"); + MP_ASSERT_OK(segmenter->Close()); +} + TEST_F(ImageModeTest, SucceedsPortraitSelfieSegmentationConfidenceMask) { Image image = GetSRGBImage(JoinPath("./", kTestDataDirectory, "portrait.jpg")); @@ -464,6 +487,9 @@ TEST_F(ImageModeTest, SucceedsPortraitSelfieSegmentationCategoryMask) { EXPECT_TRUE(result.category_mask.has_value()); MP_ASSERT_OK(segmenter->Close()); + MP_EXPECT_OK( + SavePngTestOutput(*result.category_mask->GetImageFrameSharedPtr(), + "portrait_selfie_segmentation_expected_category_mask")); cv::Mat selfie_mask = mediapipe::formats::MatView( result.category_mask->GetImageFrameSharedPtr().get()); cv::Mat expected_mask = cv::imread( @@ -471,7 +497,7 @@ TEST_F(ImageModeTest, SucceedsPortraitSelfieSegmentationCategoryMask) { "portrait_selfie_segmentation_expected_category_mask.jpg"), cv::IMREAD_GRAYSCALE); EXPECT_THAT(selfie_mask, - SimilarToUint8Mask(expected_mask, kGoldenMaskSimilarity, 255)); + SimilarToUint8Mask(expected_mask, kGoldenMaskSimilarity, 1)); } TEST_F(ImageModeTest, SucceedsPortraitSelfieSegmentationLandscapeCategoryMask) { @@ -487,6 +513,9 @@ TEST_F(ImageModeTest, SucceedsPortraitSelfieSegmentationLandscapeCategoryMask) { EXPECT_TRUE(result.category_mask.has_value()); MP_ASSERT_OK(segmenter->Close()); + MP_EXPECT_OK(SavePngTestOutput( + *result.category_mask->GetImageFrameSharedPtr(), + "portrait_selfie_segmentation_landscape_expected_category_mask")); cv::Mat selfie_mask = mediapipe::formats::MatView( result.category_mask->GetImageFrameSharedPtr().get()); cv::Mat expected_mask = cv::imread( @@ -495,7 +524,7 @@ TEST_F(ImageModeTest, SucceedsPortraitSelfieSegmentationLandscapeCategoryMask) { "portrait_selfie_segmentation_landscape_expected_category_mask.jpg"), cv::IMREAD_GRAYSCALE); EXPECT_THAT(selfie_mask, - SimilarToUint8Mask(expected_mask, kGoldenMaskSimilarity, 255)); + SimilarToUint8Mask(expected_mask, kGoldenMaskSimilarity, 1)); } TEST_F(ImageModeTest, SucceedsHairSegmentation) { diff --git a/third_party/external_files.bzl b/third_party/external_files.bzl index 599248f48..652a2947f 100644 --- a/third_party/external_files.bzl +++ b/third_party/external_files.bzl @@ -960,8 +960,8 @@ def external_files(): http_file( name = "com_google_mediapipe_portrait_selfie_segmentation_expected_category_mask_jpg", - sha256 = "d8f20fa746e14067f668dd293f21bbc50ec81196d186386a6ded1278c3ec8f46", - urls = ["https://storage.googleapis.com/mediapipe-assets/portrait_selfie_segmentation_expected_category_mask.jpg?generation=1678606935088873"], + sha256 = "1400c6fccf3805bfd1644d7ed9be98dfa4f900e1720838c566963f8d9f10f5d0", + urls = ["https://storage.googleapis.com/mediapipe-assets/portrait_selfie_segmentation_expected_category_mask.jpg?generation=1683332555306471"], ) http_file( @@ -972,8 +972,8 @@ def external_files(): http_file( name = "com_google_mediapipe_portrait_selfie_segmentation_landscape_expected_category_mask_jpg", - sha256 = "f5c3fa3d93f8e7289b69b8a89c2519276dfa5014dcc50ed6e86e8cd4d4ae7f27", - urls = ["https://storage.googleapis.com/mediapipe-assets/portrait_selfie_segmentation_landscape_expected_category_mask.jpg?generation=1678606939469429"], + sha256 = "a208aeeeb615fd40046d883e2c7982458e1b12edd6526e88c305c4053b0a9399", + urls = ["https://storage.googleapis.com/mediapipe-assets/portrait_selfie_segmentation_landscape_expected_category_mask.jpg?generation=1683332557473435"], ) http_file( @@ -1158,14 +1158,14 @@ def external_files(): http_file( name = "com_google_mediapipe_selfie_segmentation_landscape_tflite", - sha256 = "28fb4c287d6295a2dba6c1f43b43315a37f927ddcd6693d635d625d176eef162", - urls = ["https://storage.googleapis.com/mediapipe-assets/selfie_segmentation_landscape.tflite?generation=1678775102234495"], + sha256 = "a77d03f4659b9f6b6c1f5106947bf40e99d7655094b6527f214ea7d451106edd", + urls = ["https://storage.googleapis.com/mediapipe-assets/selfie_segmentation_landscape.tflite?generation=1683332561312022"], ) http_file( name = "com_google_mediapipe_selfie_segmentation_tflite", - sha256 = "b0e2ec6f95107795b952b27f3d92806b45f0bc069dac76dcd264cd1b90d61c6c", - urls = ["https://storage.googleapis.com/mediapipe-assets/selfie_segmentation.tflite?generation=1678775104900954"], + sha256 = "9ee168ec7c8f2a16c56fe8e1cfbc514974cbbb7e434051b455635f1bd1462f5c", + urls = ["https://storage.googleapis.com/mediapipe-assets/selfie_segmentation.tflite?generation=1683332563830600"], ) http_file( From 800a7b4a27495dc2c3b052874e913c4ad993e660 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Sat, 6 May 2023 01:08:50 -0700 Subject: [PATCH 231/753] Object detector handle empty packet when no object is detected. PiperOrigin-RevId: 529919638 --- .../cc/vision/object_detector/object_detector.cc | 16 +++++++++++++++- .../object_detector/object_detector_test.cc | 16 ++++++++++++++++ .../vision/objectdetector/ObjectDetector.java | 8 ++++++++ .../objectdetector/ObjectDetectorTest.java | 15 +++++++++++++++ .../python/test/vision/object_detector_test.py | 15 ++++++++++++++- mediapipe/tasks/python/vision/object_detector.py | 14 +++++++++++++- 6 files changed, 81 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/cc/vision/object_detector/object_detector.cc b/mediapipe/tasks/cc/vision/object_detector/object_detector.cc index 01fd3eb7b..152ee3273 100644 --- a/mediapipe/tasks/cc/vision/object_detector/object_detector.cc +++ b/mediapipe/tasks/cc/vision/object_detector/object_detector.cc @@ -129,9 +129,17 @@ absl::StatusOr> ObjectDetector::Create( if (status_or_packets.value()[kImageOutStreamName].IsEmpty()) { return; } + Packet image_packet = status_or_packets.value()[kImageOutStreamName]; Packet detections_packet = status_or_packets.value()[kDetectionsOutStreamName]; - Packet image_packet = status_or_packets.value()[kImageOutStreamName]; + if (detections_packet.IsEmpty()) { + Packet empty_packet = + status_or_packets.value()[kDetectionsOutStreamName]; + result_callback( + {ConvertToDetectionResult({})}, image_packet.Get(), + empty_packet.Timestamp().Value() / kMicroSecondsPerMilliSecond); + return; + } result_callback(ConvertToDetectionResult( detections_packet.Get>()), image_packet.Get(), @@ -165,6 +173,9 @@ absl::StatusOr ObjectDetector::Detect( ProcessImageData( {{kImageInStreamName, MakePacket(std::move(image))}, {kNormRectName, MakePacket(std::move(norm_rect))}})); + if (output_packets[kDetectionsOutStreamName].IsEmpty()) { + return {ConvertToDetectionResult({})}; + } return ConvertToDetectionResult( output_packets[kDetectionsOutStreamName].Get>()); } @@ -190,6 +201,9 @@ absl::StatusOr ObjectDetector::DetectForVideo( {kNormRectName, MakePacket(std::move(norm_rect)) .At(Timestamp(timestamp_ms * kMicroSecondsPerMilliSecond))}})); + if (output_packets[kDetectionsOutStreamName].IsEmpty()) { + return {ConvertToDetectionResult({})}; + } return ConvertToDetectionResult( output_packets[kDetectionsOutStreamName].Get>()); } diff --git a/mediapipe/tasks/cc/vision/object_detector/object_detector_test.cc b/mediapipe/tasks/cc/vision/object_detector/object_detector_test.cc index 8642af7c4..e66fc19bb 100644 --- a/mediapipe/tasks/cc/vision/object_detector/object_detector_test.cc +++ b/mediapipe/tasks/cc/vision/object_detector/object_detector_test.cc @@ -499,6 +499,22 @@ TEST_F(ImageModeTest, SucceedsEfficientDetNoNmsModel) { })pb")})); } +TEST_F(ImageModeTest, SucceedsNoObjectDetected) { + MP_ASSERT_OK_AND_ASSIGN(Image image, + DecodeImageFromFile(JoinPath("./", kTestDataDirectory, + "cats_and_dogs.jpg"))); + auto options = std::make_unique(); + options->max_results = 4; + options->score_threshold = 1.0f; + options->base_options.model_asset_path = + JoinPath("./", kTestDataDirectory, kEfficientDetWithoutNms); + MP_ASSERT_OK_AND_ASSIGN(std::unique_ptr object_detector, + ObjectDetector::Create(std::move(options))); + MP_ASSERT_OK_AND_ASSIGN(auto results, object_detector->Detect(image)); + MP_ASSERT_OK(object_detector->Close()); + EXPECT_THAT(results.detections, testing::IsEmpty()); +} + TEST_F(ImageModeTest, SucceedsWithoutImageResizing) { MP_ASSERT_OK_AND_ASSIGN(Image image, DecodeImageFromFile(JoinPath( "./", kTestDataDirectory, diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetector.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetector.java index 5287ba325..d9a36cce7 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetector.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetector.java @@ -39,6 +39,7 @@ import com.google.mediapipe.formats.proto.DetectionProto.Detection; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -170,6 +171,13 @@ public final class ObjectDetector extends BaseVisionTaskApi { new OutputHandler.OutputPacketConverter() { @Override public ObjectDetectionResult convertToTaskResult(List packets) { + // If there is no object detected in the image, just returns empty lists. + if (packets.get(DETECTIONS_OUT_STREAM_INDEX).isEmpty()) { + return ObjectDetectionResult.create( + new ArrayList<>(), + BaseVisionTaskApi.generateResultTimestampMs( + detectorOptions.runningMode(), packets.get(DETECTIONS_OUT_STREAM_INDEX))); + } return ObjectDetectionResult.create( PacketGetter.getProtoVector( packets.get(DETECTIONS_OUT_STREAM_INDEX), Detection.parser()), diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorTest.java index 33aa025d2..20ddfcef6 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorTest.java @@ -45,6 +45,7 @@ import org.junit.runners.Suite.SuiteClasses; @SuiteClasses({ObjectDetectorTest.General.class, ObjectDetectorTest.RunningModeTest.class}) public class ObjectDetectorTest { private static final String MODEL_FILE = "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.tflite"; + private static final String NO_NMS_MODEL_FILE = "efficientdet_lite0_fp16_no_nms.tflite"; private static final String CAT_AND_DOG_IMAGE = "cats_and_dogs.jpg"; private static final String CAT_AND_DOG_ROTATED_IMAGE = "cats_and_dogs_rotated.jpg"; private static final int IMAGE_WIDTH = 1200; @@ -109,6 +110,20 @@ public class ObjectDetectorTest { assertContainsOnlyCat(results, CAT_BOUNDING_BOX, CAT_SCORE); } + @Test + public void detect_succeedsWithNoObjectDetected() throws Exception { + ObjectDetectorOptions options = + ObjectDetectorOptions.builder() + .setBaseOptions(BaseOptions.builder().setModelAssetPath(NO_NMS_MODEL_FILE).build()) + .setScoreThreshold(1.0f) + .build(); + ObjectDetector objectDetector = + ObjectDetector.createFromOptions(ApplicationProvider.getApplicationContext(), options); + ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + // The score threshold should block objects. + assertThat(results.detections()).isEmpty(); + } + @Test public void detect_succeedsWithAllowListOption() throws Exception { ObjectDetectorOptions options = diff --git a/mediapipe/tasks/python/test/vision/object_detector_test.py b/mediapipe/tasks/python/test/vision/object_detector_test.py index 7878e7f52..adeddafd7 100644 --- a/mediapipe/tasks/python/test/vision/object_detector_test.py +++ b/mediapipe/tasks/python/test/vision/object_detector_test.py @@ -44,6 +44,7 @@ _ObjectDetectorOptions = object_detector.ObjectDetectorOptions _RUNNING_MODE = running_mode_module.VisionTaskRunningMode _MODEL_FILE = 'coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.tflite' +_NO_NMS_MODEL_FILE = 'efficientdet_lite0_fp16_no_nms.tflite' _IMAGE_FILE = 'cats_and_dogs.jpg' _EXPECTED_DETECTION_RESULT = _DetectionResult( detections=[ @@ -304,7 +305,7 @@ class ObjectDetectorTest(parameterized.TestCase): with _ObjectDetector.create_from_options(options) as unused_detector: pass - def test_empty_detection_outputs(self): + def test_empty_detection_outputs_with_in_model_nms(self): options = _ObjectDetectorOptions( base_options=_BaseOptions(model_asset_path=self.model_path), score_threshold=1, @@ -314,6 +315,18 @@ class ObjectDetectorTest(parameterized.TestCase): detection_result = detector.detect(self.test_image) self.assertEmpty(detection_result.detections) + def test_empty_detection_outputs_without_in_model_nms(self): + options = _ObjectDetectorOptions( + base_options=_BaseOptions( + model_asset_path=test_utils.get_test_data_path( + os.path.join(_TEST_DATA_DIR, _NO_NMS_MODEL_FILE))), + score_threshold=1, + ) + with _ObjectDetector.create_from_options(options) as detector: + # Performs object detection on the input. + detection_result = detector.detect(self.test_image) + self.assertEmpty(detection_result.detections) + def test_missing_result_callback(self): options = _ObjectDetectorOptions( base_options=_BaseOptions(model_asset_path=self.model_path), diff --git a/mediapipe/tasks/python/vision/object_detector.py b/mediapipe/tasks/python/vision/object_detector.py index 3bdd1b5de..380d57c22 100644 --- a/mediapipe/tasks/python/vision/object_detector.py +++ b/mediapipe/tasks/python/vision/object_detector.py @@ -198,6 +198,15 @@ class ObjectDetector(base_vision_task_api.BaseVisionTaskApi): def packets_callback(output_packets: Mapping[str, packet_module.Packet]): if output_packets[_IMAGE_OUT_STREAM_NAME].is_empty(): return + image = packet_getter.get_image(output_packets[_IMAGE_OUT_STREAM_NAME]) + if output_packets[_DETECTIONS_OUT_STREAM_NAME].is_empty(): + empty_packet = output_packets[_DETECTIONS_OUT_STREAM_NAME] + options.result_callback( + ObjectDetectorResult([]), + image, + empty_packet.timestamp.value // _MICRO_SECONDS_PER_MILLISECOND, + ) + return detection_proto_list = packet_getter.get_proto_list( output_packets[_DETECTIONS_OUT_STREAM_NAME] ) @@ -207,7 +216,6 @@ class ObjectDetector(base_vision_task_api.BaseVisionTaskApi): for result in detection_proto_list ] ) - image = packet_getter.get_image(output_packets[_IMAGE_OUT_STREAM_NAME]) timestamp = output_packets[_IMAGE_OUT_STREAM_NAME].timestamp options.result_callback(detection_result, image, timestamp) @@ -266,6 +274,8 @@ class ObjectDetector(base_vision_task_api.BaseVisionTaskApi): normalized_rect.to_pb2() ), }) + if output_packets[_DETECTIONS_OUT_STREAM_NAME].is_empty(): + return ObjectDetectorResult([]) detection_proto_list = packet_getter.get_proto_list( output_packets[_DETECTIONS_OUT_STREAM_NAME] ) @@ -315,6 +325,8 @@ class ObjectDetector(base_vision_task_api.BaseVisionTaskApi): normalized_rect.to_pb2() ).at(timestamp_ms * _MICRO_SECONDS_PER_MILLISECOND), }) + if output_packets[_DETECTIONS_OUT_STREAM_NAME].is_empty(): + return ObjectDetectorResult([]) detection_proto_list = packet_getter.get_proto_list( output_packets[_DETECTIONS_OUT_STREAM_NAME] ) From 8a6fe9075957c4174a57c22dea57a60475ea42c9 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Sat, 6 May 2023 07:02:35 -0700 Subject: [PATCH 232/753] Remove single-channel types from MPImage PiperOrigin-RevId: 529956549 --- mediapipe/tasks/web/vision/core/BUILD | 2 - mediapipe/tasks/web/vision/core/image.test.ts | 66 +---- mediapipe/tasks/web/vision/core/image.ts | 257 ++---------------- .../tasks/web/vision/core/image_converter.ts | 83 ------ mediapipe/tasks/web/vision/types.ts | 2 +- 5 files changed, 33 insertions(+), 377 deletions(-) delete mode 100644 mediapipe/tasks/web/vision/core/image_converter.ts diff --git a/mediapipe/tasks/web/vision/core/BUILD b/mediapipe/tasks/web/vision/core/BUILD index 4bda4218a..325603353 100644 --- a/mediapipe/tasks/web/vision/core/BUILD +++ b/mediapipe/tasks/web/vision/core/BUILD @@ -43,7 +43,6 @@ mediapipe_ts_library( name = "image", srcs = [ "image.ts", - "image_converter.ts", "image_shader_context.ts", ], ) @@ -117,7 +116,6 @@ mediapipe_ts_library( mediapipe_ts_library( name = "render_utils", srcs = ["render_utils.ts"], - deps = [":image"], ) jasmine_node_test( diff --git a/mediapipe/tasks/web/vision/core/image.test.ts b/mediapipe/tasks/web/vision/core/image.test.ts index da3bd76b2..0ad0ff88b 100644 --- a/mediapipe/tasks/web/vision/core/image.test.ts +++ b/mediapipe/tasks/web/vision/core/image.test.ts @@ -41,8 +41,6 @@ const IMAGE_2_3 = [ class MPImageTestContext { canvas!: OffscreenCanvas; gl!: WebGL2RenderingContext; - uint8ClampedArray!: Uint8ClampedArray; - float32Array!: Float32Array; imageData!: ImageData; imageBitmap!: ImageBitmap; webGLTexture!: WebGLTexture; @@ -56,17 +54,11 @@ class MPImageTestContext { const gl = this.gl; - this.uint8ClampedArray = new Uint8ClampedArray(pixels.length / 4); - this.float32Array = new Float32Array(pixels.length / 4); - for (let i = 0; i < this.uint8ClampedArray.length; ++i) { - this.uint8ClampedArray[i] = pixels[i * 4]; - this.float32Array[i] = pixels[i * 4] / 255; - } this.imageData = new ImageData(new Uint8ClampedArray(pixels), width, height); this.imageBitmap = await createImageBitmap(this.imageData); - this.webGLTexture = gl.createTexture()!; + this.webGLTexture = gl.createTexture()!; gl.bindTexture(gl.TEXTURE_2D, this.webGLTexture); gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.imageBitmap); @@ -75,10 +67,6 @@ class MPImageTestContext { get(type: unknown) { switch (type) { - case Uint8ClampedArray: - return this.uint8ClampedArray; - case Float32Array: - return this.float32Array; case ImageData: return this.imageData; case ImageBitmap: @@ -126,17 +114,14 @@ class MPImageTestContext { gl.bindTexture(gl.TEXTURE_2D, null); + // Sanity check + expect(pixels.find(v => !!v)).toBeDefined(); + return pixels; } function assertEquality(image: MPImage, expected: ImageType): void { - if (expected instanceof Uint8ClampedArray) { - const result = image.get(MPImageType.UINT8_CLAMPED_ARRAY); - expect(result).toEqual(expected); - } else if (expected instanceof Float32Array) { - const result = image.get(MPImageType.FLOAT32_ARRAY); - expect(result).toEqual(expected); - } else if (expected instanceof ImageData) { + if (expected instanceof ImageData) { const result = image.get(MPImageType.IMAGE_DATA); expect(result).toEqual(expected); } else if (expected instanceof ImageBitmap) { @@ -154,8 +139,7 @@ class MPImageTestContext { shaderContext: MPImageShaderContext, input: ImageType, width: number, height: number): MPImage { return new MPImage( - [input], - /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, + [input], /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, context.canvas, shaderContext, width, height); } @@ -178,9 +162,7 @@ class MPImageTestContext { shaderContext.close(); } - const sources = skip ? - [] : - [Uint8ClampedArray, Float32Array, ImageData, ImageBitmap, WebGLTexture]; + const sources = skip ? [] : [ImageData, ImageBitmap, WebGLTexture]; for (let i = 0; i < sources.length; i++) { for (let j = 0; j < sources.length; j++) { @@ -203,9 +185,9 @@ class MPImageTestContext { const shaderContext = new MPImageShaderContext(); const image = new MPImage( - [context.webGLTexture], - /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, - context.canvas, shaderContext, WIDTH, HEIGHT); + [context.webGLTexture], /* ownsImageBitmap= */ false, + /* ownsWebGLTexture= */ false, context.canvas, shaderContext, WIDTH, + HEIGHT); const result = image.clone().get(MPImageType.IMAGE_DATA); expect(result).toEqual(context.imageData); @@ -218,9 +200,9 @@ class MPImageTestContext { const shaderContext = new MPImageShaderContext(); const image = new MPImage( - [context.webGLTexture], - /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, - context.canvas, shaderContext, WIDTH, HEIGHT); + [context.webGLTexture], /* ownsImageBitmap= */ false, + /* ownsWebGLTexture= */ false, context.canvas, shaderContext, WIDTH, + HEIGHT); // Verify that we can mix the different shader modes by running them out of // order. @@ -243,40 +225,18 @@ class MPImageTestContext { const image = createImage(shaderContext, context.imageData, WIDTH, HEIGHT); expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); - expect(image.has(MPImageType.UINT8_CLAMPED_ARRAY)).toBe(false); - expect(image.has(MPImageType.FLOAT32_ARRAY)).toBe(false); - expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(false); - expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(false); - - image.get(MPImageType.UINT8_CLAMPED_ARRAY); - - expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); - expect(image.has(MPImageType.UINT8_CLAMPED_ARRAY)).toBe(true); - expect(image.has(MPImageType.FLOAT32_ARRAY)).toBe(false); - expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(false); - expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(false); - - image.get(MPImageType.FLOAT32_ARRAY); - - expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); - expect(image.has(MPImageType.UINT8_CLAMPED_ARRAY)).toBe(true); - expect(image.has(MPImageType.FLOAT32_ARRAY)).toBe(true); expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(false); expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(false); image.get(MPImageType.WEBGL_TEXTURE); expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); - expect(image.has(MPImageType.UINT8_CLAMPED_ARRAY)).toBe(true); - expect(image.has(MPImageType.FLOAT32_ARRAY)).toBe(true); expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(true); expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(false); image.get(MPImageType.IMAGE_BITMAP); expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); - expect(image.has(MPImageType.UINT8_CLAMPED_ARRAY)).toBe(true); - expect(image.has(MPImageType.FLOAT32_ARRAY)).toBe(true); expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(true); expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(true); diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index df7586ded..14271c087 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -14,17 +14,10 @@ * limitations under the License. */ -import {DefaultColorConverter} from '../../../../tasks/web/vision/core/image_converter'; import {assertNotNull, MPImageShaderContext} from '../../../../tasks/web/vision/core/image_shader_context'; /** The underlying type of the image. */ export enum MPImageType { - /** Represents the native `UInt8ClampedArray` type. */ - UINT8_CLAMPED_ARRAY, - /** - * Represents the native `Float32Array` type. Values range from [0.0, 1.0]. - */ - FLOAT32_ARRAY, /** Represents the native `ImageData` type. */ IMAGE_DATA, /** Represents the native `ImageBitmap` type. */ @@ -34,75 +27,7 @@ export enum MPImageType { } /** The supported image formats. For internal usage. */ -export type MPImageContainer = - Uint8ClampedArray|Float32Array|ImageData|ImageBitmap|WebGLTexture; - -/** A four channel color with a red, green, blue and alpha values. */ -export type RGBAColor = [number, number, number, number]; - -/** - * An interface that can be used to provide custom conversion functions. These - * functions are invoked to convert pixel values between different channel - * counts and value ranges. Any conversion function that is not specified will - * result in a default conversion. - */ -export interface MPImageChannelConverter { - /** - * A conversion function to convert a number in the [0.0, 1.0] range to RGBA. - * The output is an array with four elemeents whose values range from 0 to 255 - * inclusive. - * - * The default conversion function is `[v * 255, v * 255, v * 255, 255]` - * and will log a warning if invoked. - */ - floatToRGBAConverter?: (value: number) => RGBAColor; - - /* - * A conversion function to convert a number in the [0, 255] range to RGBA. - * The output is an array with four elemeents whose values range from 0 to 255 - * inclusive. - * - * The default conversion function is `[v, v , v , 255]` and will log a - * warning if invoked. - */ - uint8ToRGBAConverter?: (value: number) => RGBAColor; - - /** - * A conversion function to convert an RGBA value in the range of 0 to 255 to - * a single value in the [0.0, 1.0] range. - * - * The default conversion function is `(r / 3 + g / 3 + b / 3) / 255` and will - * log a warning if invoked. - */ - rgbaToFloatConverter?: (r: number, g: number, b: number, a: number) => number; - - /** - * A conversion function to convert an RGBA value in the range of 0 to 255 to - * a single value in the [0, 255] range. - * - * The default conversion function is `r / 3 + g / 3 + b / 3` and will log a - * warning if invoked. - */ - rgbaToUint8Converter?: (r: number, g: number, b: number, a: number) => number; - - /** - * A conversion function to convert a single value in the 0.0 to 1.0 range to - * [0, 255]. - * - * The default conversion function is `r * 255` and will log a warning if - * invoked. - */ - floatToUint8Converter?: (value: number) => number; - - /** - * A conversion function to convert a single value in the 0 to 255 range to - * [0.0, 1.0] . - * - * The default conversion function is `r / 255` and will log a warning if - * invoked. - */ - uint8ToFloatConverter?: (value: number) => number; -} +export type MPImageContainer = ImageData|ImageBitmap|WebGLTexture; /** * The wrapper class for MediaPipe Image objects. @@ -123,14 +48,6 @@ export interface MPImageChannelConverter { * initialized with an `OffscreenCanvas`. As we require WebGL2 support, this * places some limitations on Browser support as outlined here: * https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas/getContext - * - * Some MediaPipe tasks return single channel masks. These masks are stored - * using an underlying `Uint8ClampedArray` an `Float32Array` (represented as - * single-channel arrays). To convert these type to other formats a conversion - * function is invoked to convert pixel values between single channel and four - * channel RGBA values. To customize this conversion, you can specify these - * conversion functions when you invoke `get()`. If you use the default - * conversion function a warning will be logged to the console. */ export class MPImage { private gl?: WebGL2RenderingContext; @@ -161,53 +78,18 @@ export class MPImage { return !!this.getContainer(type); } - /** - * Returns the underlying image as a single channel `Uint8ClampedArray`. Note - * that this involves an expensive GPU to CPU transfer if the current image is - * only available as an `ImageBitmap` or `WebGLTexture`. If necessary, this - * function converts RGBA data pixel-by-pixel to a single channel value by - * invoking a conversion function (see class comment for detail). - * - * @param type The type of image to return. - * @param converter A set of conversion functions that will be invoked to - * convert the underlying pixel data if necessary. You may omit this - * function if the requested conversion does not change the pixel format. - * @return The current data as a Uint8ClampedArray. - */ - get(type: MPImageType.UINT8_CLAMPED_ARRAY, - converter?: MPImageChannelConverter): Uint8ClampedArray; - /** - * Returns the underlying image as a single channel `Float32Array`. Note - * that this involves an expensive GPU to CPU transfer if the current image is - * only available as an `ImageBitmap` or `WebGLTexture`. If necessary, this - * function converts RGBA data pixel-by-pixel to a single channel value by - * invoking a conversion function (see class comment for detail). - * - * @param type The type of image to return. - * @param converter A set of conversion functions that will be invoked to - * convert the underlying pixel data if necessary. You may omit this - * function if the requested conversion does not change the pixel format. - * @return The current image as a Float32Array. - */ - get(type: MPImageType.FLOAT32_ARRAY, - converter?: MPImageChannelConverter): Float32Array; /** * Returns the underlying image as an `ImageData` object. Note that this * involves an expensive GPU to CPU transfer if the current image is only - * available as an `ImageBitmap` or `WebGLTexture`. If necessary, this - * function converts single channel pixel values to RGBA by invoking a - * conversion function (see class comment for detail). + * available as an `ImageBitmap` or `WebGLTexture`. * * @return The current image as an ImageData object. */ - get(type: MPImageType.IMAGE_DATA, - converter?: MPImageChannelConverter): ImageData; + get(type: MPImageType.IMAGE_DATA): ImageData; /** * Returns the underlying image as an `ImageBitmap`. Note that * conversions to `ImageBitmap` are expensive, especially if the data - * currently resides on CPU. If necessary, this function first converts single - * channel pixel values to RGBA by invoking a conversion function (see class - * comment for detail). + * currently resides on CPU. * * Processing with `ImageBitmap`s requires that the MediaPipe Task was * initialized with an `OffscreenCanvas` with WebGL2 support. See @@ -215,13 +97,9 @@ export class MPImage { * for a list of supported platforms. * * @param type The type of image to return. - * @param converter A set of conversion functions that will be invoked to - * convert the underlying pixel data if necessary. You may omit this - * function if the requested conversion does not change the pixel format. * @return The current image as an ImageBitmap object. */ - get(type: MPImageType.IMAGE_BITMAP, - converter?: MPImageChannelConverter): ImageBitmap; + get(type: MPImageType.IMAGE_BITMAP): ImageBitmap; /** * Returns the underlying image as a `WebGLTexture` object. Note that this * involves a CPU to GPU transfer if the current image is only available as @@ -229,36 +107,21 @@ export class MPImage { * canvas (see `.canvas`). * * @param type The type of image to return. - * @param converter A set of conversion functions that will be invoked to - * convert the underlying pixel data if necessary. You may omit this - * function if the requested conversion does not change the pixel format. * @return The current image as a WebGLTexture. */ - get(type: MPImageType.WEBGL_TEXTURE, - converter?: MPImageChannelConverter): WebGLTexture; - get(type?: MPImageType, - converter?: MPImageChannelConverter): MPImageContainer { - const internalConverter = new DefaultColorConverter(converter ?? {}); + get(type: MPImageType.WEBGL_TEXTURE): WebGLTexture; + get(type?: MPImageType): MPImageContainer { switch (type) { - case MPImageType.UINT8_CLAMPED_ARRAY: - return this.convertToUint8ClampedArray(internalConverter); - case MPImageType.FLOAT32_ARRAY: - return this.convertToFloat32Array(internalConverter); case MPImageType.IMAGE_DATA: - return this.convertToImageData(internalConverter); + return this.convertToImageData(); case MPImageType.IMAGE_BITMAP: - return this.convertToImageBitmap(internalConverter); + return this.convertToImageBitmap(); case MPImageType.WEBGL_TEXTURE: - return this.convertToWebGLTexture(internalConverter); + return this.convertToWebGLTexture(); default: throw new Error(`Type is not supported: ${type}`); } } - - - private getContainer(type: MPImageType.UINT8_CLAMPED_ARRAY): Uint8ClampedArray - |undefined; - private getContainer(type: MPImageType.FLOAT32_ARRAY): Float32Array|undefined; private getContainer(type: MPImageType.IMAGE_DATA): ImageData|undefined; private getContainer(type: MPImageType.IMAGE_BITMAP): ImageBitmap|undefined; private getContainer(type: MPImageType.WEBGL_TEXTURE): WebGLTexture|undefined; @@ -266,10 +129,6 @@ export class MPImage { /** Returns the container for the requested storage type iff it exists. */ private getContainer(type: MPImageType): MPImageContainer|undefined { switch (type) { - case MPImageType.UINT8_CLAMPED_ARRAY: - return this.containers.find(img => img instanceof Uint8ClampedArray); - case MPImageType.FLOAT32_ARRAY: - return this.containers.find(img => img instanceof Float32Array); case MPImageType.IMAGE_DATA: return this.containers.find(img => img instanceof ImageData); case MPImageType.IMAGE_BITMAP: @@ -300,11 +159,7 @@ export class MPImage { for (const container of this.containers) { let destinationContainer: MPImageContainer; - if (container instanceof Uint8ClampedArray) { - destinationContainer = new Uint8ClampedArray(container); - } else if (container instanceof Float32Array) { - destinationContainer = new Float32Array(container); - } else if (container instanceof ImageData) { + if (container instanceof ImageData) { destinationContainer = new ImageData(container.data, this.width, this.height); } else if (container instanceof WebGLTexture) { @@ -333,7 +188,7 @@ export class MPImage { this.unbindTexture(); } else if (container instanceof ImageBitmap) { - this.convertToWebGLTexture(new DefaultColorConverter({})); + this.convertToWebGLTexture(); this.bindTexture(); destinationContainer = this.copyTextureToBitmap(); this.unbindTexture(); @@ -381,11 +236,10 @@ export class MPImage { return this.shaderContext; } - private convertToImageBitmap(converter: Required): - ImageBitmap { + private convertToImageBitmap(): ImageBitmap { let imageBitmap = this.getContainer(MPImageType.IMAGE_BITMAP); if (!imageBitmap) { - this.convertToWebGLTexture(converter); + this.convertToWebGLTexture(); imageBitmap = this.convertWebGLTextureToImageBitmap(); this.containers.push(imageBitmap); this.ownsImageBitmap = true; @@ -394,43 +248,17 @@ export class MPImage { return imageBitmap; } - private convertToImageData(converter: Required): - ImageData { + private convertToImageData(): ImageData { let imageData = this.getContainer(MPImageType.IMAGE_DATA); if (!imageData) { - if (this.has(MPImageType.UINT8_CLAMPED_ARRAY)) { - const source = this.getContainer(MPImageType.UINT8_CLAMPED_ARRAY)!; - const destination = new Uint8ClampedArray(this.width * this.height * 4); - for (let i = 0; i < this.width * this.height; i++) { - const rgba = converter.uint8ToRGBAConverter(source[i]); - destination[i * 4] = rgba[0]; - destination[i * 4 + 1] = rgba[1]; - destination[i * 4 + 2] = rgba[2]; - destination[i * 4 + 3] = rgba[3]; - } - imageData = new ImageData(destination, this.width, this.height); - this.containers.push(imageData); - } else if (this.has(MPImageType.FLOAT32_ARRAY)) { - const source = this.getContainer(MPImageType.FLOAT32_ARRAY)!; - const destination = new Uint8ClampedArray(this.width * this.height * 4); - for (let i = 0; i < this.width * this.height; i++) { - const rgba = converter.floatToRGBAConverter(source[i]); - destination[i * 4] = rgba[0]; - destination[i * 4 + 1] = rgba[1]; - destination[i * 4 + 2] = rgba[2]; - destination[i * 4 + 3] = rgba[3]; - } - imageData = new ImageData(destination, this.width, this.height); - this.containers.push(imageData); - } else if ( - this.has(MPImageType.IMAGE_BITMAP) || + if (this.has(MPImageType.IMAGE_BITMAP) || this.has(MPImageType.WEBGL_TEXTURE)) { const gl = this.getGL(); const shaderContext = this.getShaderContext(); const pixels = new Uint8Array(this.width * this.height * 4); // Create texture if needed - const webGlTexture = this.convertToWebGLTexture(converter); + const webGlTexture = this.convertToWebGLTexture(); // Create a framebuffer from the texture and read back pixels shaderContext.bindFramebuffer(gl, webGlTexture); @@ -449,60 +277,13 @@ export class MPImage { return imageData; } - private convertToUint8ClampedArray( - converter: Required): Uint8ClampedArray { - let uint8ClampedArray = this.getContainer(MPImageType.UINT8_CLAMPED_ARRAY); - if (!uint8ClampedArray) { - if (this.has(MPImageType.FLOAT32_ARRAY)) { - const source = this.getContainer(MPImageType.FLOAT32_ARRAY)!; - uint8ClampedArray = new Uint8ClampedArray( - source.map(v => converter.floatToUint8Converter(v))); - } else { - const source = this.convertToImageData(converter).data; - uint8ClampedArray = new Uint8ClampedArray(this.width * this.height); - for (let i = 0; i < this.width * this.height; i++) { - uint8ClampedArray[i] = converter.rgbaToUint8Converter( - source[i * 4], source[i * 4 + 1], source[i * 4 + 2], - source[i * 4 + 3]); - } - } - this.containers.push(uint8ClampedArray); - } - - return uint8ClampedArray; - } - - private convertToFloat32Array(converter: Required): - Float32Array { - let float32Array = this.getContainer(MPImageType.FLOAT32_ARRAY); - if (!float32Array) { - if (this.has(MPImageType.UINT8_CLAMPED_ARRAY)) { - const source = this.getContainer(MPImageType.UINT8_CLAMPED_ARRAY)!; - float32Array = new Float32Array(source).map( - v => converter.uint8ToFloatConverter(v)); - } else { - const source = this.convertToImageData(converter).data; - float32Array = new Float32Array(this.width * this.height); - for (let i = 0; i < this.width * this.height; i++) { - float32Array[i] = converter.rgbaToFloatConverter( - source[i * 4], source[i * 4 + 1], source[i * 4 + 2], - source[i * 4 + 3]); - } - } - this.containers.push(float32Array); - } - - return float32Array; - } - - private convertToWebGLTexture(converter: Required): - WebGLTexture { + private convertToWebGLTexture(): WebGLTexture { let webGLTexture = this.getContainer(MPImageType.WEBGL_TEXTURE); if (!webGLTexture) { const gl = this.getGL(); webGLTexture = this.bindTexture(); const source = this.getContainer(MPImageType.IMAGE_BITMAP) || - this.convertToImageData(converter); + this.convertToImageData(); gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source); this.unbindTexture(); diff --git a/mediapipe/tasks/web/vision/core/image_converter.ts b/mediapipe/tasks/web/vision/core/image_converter.ts deleted file mode 100644 index 348b89b82..000000000 --- a/mediapipe/tasks/web/vision/core/image_converter.ts +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Copyright 2023 The MediaPipe Authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {MPImageChannelConverter, RGBAColor} from '../../../../tasks/web/vision/core/image'; - -/** - * Color converter that falls back to a default implementation if the - * user-provided converter does not specify a conversion. - */ -export class DefaultColorConverter implements - Required { - private static readonly WARNINGS_LOGGED = new Set(); - - constructor(private readonly customConverter: MPImageChannelConverter) {} - - floatToRGBAConverter(v: number): RGBAColor { - if (this.customConverter.floatToRGBAConverter) { - return this.customConverter.floatToRGBAConverter(v); - } - this.logWarningOnce('floatToRGBAConverter'); - return [v * 255, v * 255, v * 255, 255]; - } - - uint8ToRGBAConverter(v: number): RGBAColor { - if (this.customConverter.uint8ToRGBAConverter) { - return this.customConverter.uint8ToRGBAConverter(v); - } - this.logWarningOnce('uint8ToRGBAConverter'); - return [v, v, v, 255]; - } - - rgbaToFloatConverter(r: number, g: number, b: number, a: number): number { - if (this.customConverter.rgbaToFloatConverter) { - return this.customConverter.rgbaToFloatConverter(r, g, b, a); - } - this.logWarningOnce('rgbaToFloatConverter'); - return (r / 3 + g / 3 + b / 3) / 255; - } - - rgbaToUint8Converter(r: number, g: number, b: number, a: number): number { - if (this.customConverter.rgbaToUint8Converter) { - return this.customConverter.rgbaToUint8Converter(r, g, b, a); - } - this.logWarningOnce('rgbaToUint8Converter'); - return r / 3 + g / 3 + b / 3; - } - - floatToUint8Converter(v: number): number { - if (this.customConverter.floatToUint8Converter) { - return this.customConverter.floatToUint8Converter(v); - } - this.logWarningOnce('floatToUint8Converter'); - return v * 255; - } - - uint8ToFloatConverter(v: number): number { - if (this.customConverter.uint8ToFloatConverter) { - return this.customConverter.uint8ToFloatConverter(v); - } - this.logWarningOnce('uint8ToFloatConverter'); - return v / 255; - } - - private logWarningOnce(methodName: string): void { - if (!DefaultColorConverter.WARNINGS_LOGGED.has(methodName)) { - console.log(`Using default ${methodName}`); - DefaultColorConverter.WARNINGS_LOGGED.add(methodName); - } - } -} diff --git a/mediapipe/tasks/web/vision/types.ts b/mediapipe/tasks/web/vision/types.ts index ec3b88d68..e901d43bc 100644 --- a/mediapipe/tasks/web/vision/types.ts +++ b/mediapipe/tasks/web/vision/types.ts @@ -16,7 +16,7 @@ export * from '../../../tasks/web/core/fileset_resolver'; export * from '../../../tasks/web/vision/core/drawing_utils'; -export {MPImage, MPImageChannelConverter, MPImageType} from '../../../tasks/web/vision/core/image'; +export {MPImage, MPImageType} from '../../../tasks/web/vision/core/image'; export {MPMask, MPMaskType} from '../../../tasks/web/vision/core/mask'; export * from '../../../tasks/web/vision/face_detector/face_detector'; export * from '../../../tasks/web/vision/face_landmarker/face_landmarker'; From e9fc66277acc29e0866277dd9eb8bc1db66f8e5d Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Sat, 6 May 2023 07:47:37 -0700 Subject: [PATCH 233/753] Simplify MPImage API by removing the Type Enums from the public API PiperOrigin-RevId: 529960399 --- mediapipe/tasks/web/vision/core/image.test.ts | 41 +++++---- mediapipe/tasks/web/vision/core/image.ts | 92 +++++++++---------- .../tasks/web/vision/face_stylizer/BUILD | 1 - .../face_stylizer/face_stylizer_test.ts | 5 +- mediapipe/tasks/web/vision/index.ts | 4 +- mediapipe/tasks/web/vision/types.ts | 2 +- 6 files changed, 67 insertions(+), 78 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/image.test.ts b/mediapipe/tasks/web/vision/core/image.test.ts index 0ad0ff88b..e92debc2e 100644 --- a/mediapipe/tasks/web/vision/core/image.test.ts +++ b/mediapipe/tasks/web/vision/core/image.test.ts @@ -16,7 +16,7 @@ import 'jasmine'; -import {MPImage, MPImageType} from './image'; +import {MPImage} from './image'; import {MPImageShaderContext} from './image_shader_context'; const WIDTH = 2; @@ -122,14 +122,14 @@ class MPImageTestContext { function assertEquality(image: MPImage, expected: ImageType): void { if (expected instanceof ImageData) { - const result = image.get(MPImageType.IMAGE_DATA); + const result = image.getAsImageData(); expect(result).toEqual(expected); } else if (expected instanceof ImageBitmap) { - const result = image.get(MPImageType.IMAGE_BITMAP); + const result = image.getAsImageBitmap(); expect(readPixelsFromImageBitmap(result)) .toEqual(readPixelsFromImageBitmap(expected)); } else { // WebGLTexture - const result = image.get(MPImageType.WEBGL_TEXTURE); + const result = image.getAsWebGLTexture(); expect(readPixelsFromWebGLTexture(result)) .toEqual(readPixelsFromWebGLTexture(expected)); } @@ -139,7 +139,8 @@ class MPImageTestContext { shaderContext: MPImageShaderContext, input: ImageType, width: number, height: number): MPImage { return new MPImage( - [input], /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, + [input], + /* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, context.canvas, shaderContext, width, height); } @@ -189,7 +190,7 @@ class MPImageTestContext { /* ownsWebGLTexture= */ false, context.canvas, shaderContext, WIDTH, HEIGHT); - const result = image.clone().get(MPImageType.IMAGE_DATA); + const result = image.clone().getAsImageData(); expect(result).toEqual(context.imageData); shaderContext.close(); @@ -206,13 +207,13 @@ class MPImageTestContext { // Verify that we can mix the different shader modes by running them out of // order. - let result = image.get(MPImageType.IMAGE_DATA); + let result = image.getAsImageData(); expect(result).toEqual(context.imageData); - result = image.clone().get(MPImageType.IMAGE_DATA); + result = image.clone().getAsImageData(); expect(result).toEqual(context.imageData); - result = image.get(MPImageType.IMAGE_DATA); + result = image.getAsImageData(); expect(result).toEqual(context.imageData); shaderContext.close(); @@ -224,21 +225,21 @@ class MPImageTestContext { const shaderContext = new MPImageShaderContext(); const image = createImage(shaderContext, context.imageData, WIDTH, HEIGHT); - expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); - expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(false); - expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(false); + expect(image.hasImageData()).toBe(true); + expect(image.hasWebGLTexture()).toBe(false); + expect(image.hasImageBitmap()).toBe(false); - image.get(MPImageType.WEBGL_TEXTURE); + image.getAsWebGLTexture(); - expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); - expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(true); - expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(false); + expect(image.hasImageData()).toBe(true); + expect(image.hasWebGLTexture()).toBe(true); + expect(image.hasImageBitmap()).toBe(false); - image.get(MPImageType.IMAGE_BITMAP); + image.getAsImageBitmap(); - expect(image.has(MPImageType.IMAGE_DATA)).toBe(true); - expect(image.has(MPImageType.WEBGL_TEXTURE)).toBe(true); - expect(image.has(MPImageType.IMAGE_BITMAP)).toBe(true); + expect(image.hasImageData()).toBe(true); + expect(image.hasWebGLTexture()).toBe(true); + expect(image.hasImageBitmap()).toBe(true); image.close(); shaderContext.close(); diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index 14271c087..bcc6b7ca1 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -17,7 +17,7 @@ import {assertNotNull, MPImageShaderContext} from '../../../../tasks/web/vision/core/image_shader_context'; /** The underlying type of the image. */ -export enum MPImageType { +enum MPImageType { /** Represents the native `ImageData` type. */ IMAGE_DATA, /** Represents the native `ImageBitmap` type. */ @@ -34,9 +34,9 @@ export type MPImageContainer = ImageData|ImageBitmap|WebGLTexture; * * Images are stored as `ImageData`, `ImageBitmap` or `WebGLTexture` objects. * You can convert the underlying type to any other type by passing the - * desired type to `get()`. As type conversions can be expensive, it is + * desired type to `getAs...()`. As type conversions can be expensive, it is * recommended to limit these conversions. You can verify what underlying - * types are already available by invoking `has()`. + * types are already available by invoking `has...()`. * * Images that are returned from a MediaPipe Tasks are owned by by the * underlying C++ Task. If you need to extend the lifetime of these objects, @@ -52,9 +52,6 @@ export type MPImageContainer = ImageData|ImageBitmap|WebGLTexture; export class MPImage { private gl?: WebGL2RenderingContext; - /** The underlying type of the image. */ - static TYPE = MPImageType; - /** @hideconstructor */ constructor( private readonly containers: MPImageContainer[], @@ -69,13 +66,19 @@ export class MPImage { readonly height: number, ) {} - /** - * Returns whether this `MPImage` stores the image in the desired format. - * This method can be called to reduce expensive conversion before invoking - * `get()`. - */ - has(type: MPImageType): boolean { - return !!this.getContainer(type); + /** Returns whether this `MPImage` contains a mask of type `ImageData`. */ + hasImageData(): boolean { + return !!this.getContainer(MPImageType.IMAGE_DATA); + } + + /** Returns whether this `MPImage` contains a mask of type `ImageBitmap`. */ + hasImageBitmap(): boolean { + return !!this.getContainer(MPImageType.IMAGE_BITMAP); + } + + /** Returns whether this `MPImage` contains a mask of type `WebGLTexture`. */ + hasWebGLTexture(): boolean { + return !!this.getContainer(MPImageType.WEBGL_TEXTURE); } /** @@ -85,7 +88,10 @@ export class MPImage { * * @return The current image as an ImageData object. */ - get(type: MPImageType.IMAGE_DATA): ImageData; + getAsImageData(): ImageData { + return this.convertToImageData(); + } + /** * Returns the underlying image as an `ImageBitmap`. Note that * conversions to `ImageBitmap` are expensive, especially if the data @@ -96,32 +102,24 @@ export class MPImage { * https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas/getContext * for a list of supported platforms. * - * @param type The type of image to return. * @return The current image as an ImageBitmap object. */ - get(type: MPImageType.IMAGE_BITMAP): ImageBitmap; + getAsImageBitmap(): ImageBitmap { + return this.convertToImageBitmap(); + } + /** * Returns the underlying image as a `WebGLTexture` object. Note that this * involves a CPU to GPU transfer if the current image is only available as * an `ImageData` object. The returned texture is bound to the current * canvas (see `.canvas`). * - * @param type The type of image to return. * @return The current image as a WebGLTexture. */ - get(type: MPImageType.WEBGL_TEXTURE): WebGLTexture; - get(type?: MPImageType): MPImageContainer { - switch (type) { - case MPImageType.IMAGE_DATA: - return this.convertToImageData(); - case MPImageType.IMAGE_BITMAP: - return this.convertToImageBitmap(); - case MPImageType.WEBGL_TEXTURE: - return this.convertToWebGLTexture(); - default: - throw new Error(`Type is not supported: ${type}`); - } + getAsWebGLTexture(): WebGLTexture { + return this.convertToWebGLTexture(); } + private getContainer(type: MPImageType.IMAGE_DATA): ImageData|undefined; private getContainer(type: MPImageType.IMAGE_BITMAP): ImageBitmap|undefined; private getContainer(type: MPImageType.WEBGL_TEXTURE): WebGLTexture|undefined; @@ -200,9 +198,8 @@ export class MPImage { } return new MPImage( - destinationContainers, this.has(MPImageType.IMAGE_BITMAP), - this.has(MPImageType.WEBGL_TEXTURE), this.canvas, this.shaderContext, - this.width, this.height); + destinationContainers, this.hasImageBitmap(), this.hasWebGLTexture(), + this.canvas, this.shaderContext, this.width, this.height); } private getOffscreenCanvas(): OffscreenCanvas { @@ -251,27 +248,22 @@ export class MPImage { private convertToImageData(): ImageData { let imageData = this.getContainer(MPImageType.IMAGE_DATA); if (!imageData) { - if (this.has(MPImageType.IMAGE_BITMAP) || - this.has(MPImageType.WEBGL_TEXTURE)) { - const gl = this.getGL(); - const shaderContext = this.getShaderContext(); - const pixels = new Uint8Array(this.width * this.height * 4); + const gl = this.getGL(); + const shaderContext = this.getShaderContext(); + const pixels = new Uint8Array(this.width * this.height * 4); - // Create texture if needed - const webGlTexture = this.convertToWebGLTexture(); + // Create texture if needed + const webGlTexture = this.convertToWebGLTexture(); - // Create a framebuffer from the texture and read back pixels - shaderContext.bindFramebuffer(gl, webGlTexture); - gl.readPixels( - 0, 0, this.width, this.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); - shaderContext.unbindFramebuffer(); + // Create a framebuffer from the texture and read back pixels + shaderContext.bindFramebuffer(gl, webGlTexture); + gl.readPixels( + 0, 0, this.width, this.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + shaderContext.unbindFramebuffer(); - imageData = new ImageData( - new Uint8ClampedArray(pixels.buffer), this.width, this.height); - this.containers.push(imageData); - } else { - throw new Error('Couldn\t find backing image for ImageData conversion'); - } + imageData = new ImageData( + new Uint8ClampedArray(pixels.buffer), this.width, this.height); + this.containers.push(imageData); } return imageData; diff --git a/mediapipe/tasks/web/vision/face_stylizer/BUILD b/mediapipe/tasks/web/vision/face_stylizer/BUILD index 0c0167dbd..fe9146987 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/BUILD +++ b/mediapipe/tasks/web/vision/face_stylizer/BUILD @@ -47,7 +47,6 @@ mediapipe_ts_library( "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", - "//mediapipe/tasks/web/vision/core:image", "//mediapipe/web/graph_runner:graph_runner_image_lib_ts", ], ) diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts index 704feef69..c092bf0f8 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_test.ts @@ -19,7 +19,6 @@ import 'jasmine'; // Placeholder for internal dependency on encodeByteArray import {CalculatorGraphConfig} from '../../../../framework/calculator_pb'; import {addJasmineCustomFloatEqualityTester, createSpyWasmModule, MediapipeTasksFake, SpyWasmModule, verifyGraph, verifyListenersRegistered} from '../../../../tasks/web/core/task_runner_test_utils'; -import {MPImage} from '../../../../tasks/web/vision/core/image'; import {WasmImage} from '../../../../web/graph_runner/graph_runner_image_lib'; import {FaceStylizer} from './face_stylizer'; @@ -117,7 +116,7 @@ describe('FaceStylizer', () => { const image = faceStylizer.stylize({} as HTMLImageElement); expect(faceStylizer.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); expect(image).not.toBeNull(); - expect(image!.has(MPImage.TYPE.IMAGE_DATA)).toBeTrue(); + expect(image!.hasImageData()).toBeTrue(); expect(image!.width).toEqual(1); expect(image!.height).toEqual(1); image!.close(); @@ -142,7 +141,7 @@ describe('FaceStylizer', () => { faceStylizer.stylize({} as HTMLImageElement, image => { expect(faceStylizer.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); expect(image).not.toBeNull(); - expect(image!.has(MPImage.TYPE.IMAGE_DATA)).toBeTrue(); + expect(image!.hasImageData()).toBeTrue(); expect(image!.width).toEqual(1); expect(image!.height).toEqual(1); done(); diff --git a/mediapipe/tasks/web/vision/index.ts b/mediapipe/tasks/web/vision/index.ts index 4908f71f6..ea385fdfc 100644 --- a/mediapipe/tasks/web/vision/index.ts +++ b/mediapipe/tasks/web/vision/index.ts @@ -16,7 +16,7 @@ import {FilesetResolver as FilesetResolverImpl} from '../../../tasks/web/core/fileset_resolver'; import {DrawingUtils as DrawingUtilsImpl} from '../../../tasks/web/vision/core/drawing_utils'; -import {MPImage as MPImageImpl, MPImageType as MPImageTypeImpl} from '../../../tasks/web/vision/core/image'; +import {MPImage as MPImageImpl} from '../../../tasks/web/vision/core/image'; import {MPMask as MPMaskImpl, MPMaskType as MPMaskTypeImpl} from '../../../tasks/web/vision/core/mask'; import {FaceDetector as FaceDetectorImpl} from '../../../tasks/web/vision/face_detector/face_detector'; import {FaceLandmarker as FaceLandmarkerImpl, FaceLandmarksConnections as FaceLandmarksConnectionsImpl} from '../../../tasks/web/vision/face_landmarker/face_landmarker'; @@ -35,7 +35,6 @@ import {PoseLandmarker as PoseLandmarkerImpl} from '../../../tasks/web/vision/po const DrawingUtils = DrawingUtilsImpl; const FilesetResolver = FilesetResolverImpl; const MPImage = MPImageImpl; -const MPImageType = MPImageTypeImpl; const MPMask = MPMaskImpl; const MPMaskType = MPMaskTypeImpl; const FaceDetector = FaceDetectorImpl; @@ -55,7 +54,6 @@ export { DrawingUtils, FilesetResolver, MPImage, - MPImageType, MPMask, MPMaskType, FaceDetector, diff --git a/mediapipe/tasks/web/vision/types.ts b/mediapipe/tasks/web/vision/types.ts index e901d43bc..203983fa1 100644 --- a/mediapipe/tasks/web/vision/types.ts +++ b/mediapipe/tasks/web/vision/types.ts @@ -16,7 +16,7 @@ export * from '../../../tasks/web/core/fileset_resolver'; export * from '../../../tasks/web/vision/core/drawing_utils'; -export {MPImage, MPImageType} from '../../../tasks/web/vision/core/image'; +export {MPImage} from '../../../tasks/web/vision/core/image'; export {MPMask, MPMaskType} from '../../../tasks/web/vision/core/mask'; export * from '../../../tasks/web/vision/face_detector/face_detector'; export * from '../../../tasks/web/vision/face_landmarker/face_landmarker'; From ddb84702f649a0037300a4bebf6c0be54d80844c Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Sat, 6 May 2023 10:23:58 -0700 Subject: [PATCH 234/753] Simplify MPMask by removing the Type Enums from the public API PiperOrigin-RevId: 529975377 --- mediapipe/tasks/web/vision/core/mask.test.ts | 37 +++++------ mediapipe/tasks/web/vision/core/mask.ts | 67 +++++++++----------- mediapipe/tasks/web/vision/index.ts | 4 +- mediapipe/tasks/web/vision/types.ts | 2 +- 4 files changed, 52 insertions(+), 58 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/mask.test.ts b/mediapipe/tasks/web/vision/core/mask.test.ts index 310a59ef3..b632f2dc5 100644 --- a/mediapipe/tasks/web/vision/core/mask.test.ts +++ b/mediapipe/tasks/web/vision/core/mask.test.ts @@ -17,7 +17,7 @@ import 'jasmine'; import {MPImageShaderContext} from './image_shader_context'; -import {MPMask, MPMaskType} from './mask'; +import {MPMask} from './mask'; const WIDTH = 2; const HEIGHT = 2; @@ -117,13 +117,13 @@ class MPMaskTestContext { function assertEquality(mask: MPMask, expected: MaskType): void { if (expected instanceof Uint8Array) { - const result = mask.get(MPMaskType.UINT8_ARRAY); + const result = mask.getAsUint8Array(); expect(result).toEqual(expected); } else if (expected instanceof Float32Array) { - const result = mask.get(MPMaskType.FLOAT32_ARRAY); + const result = mask.getAsFloat32Array(); expect(result).toEqual(expected); } else { // WebGLTexture - const result = mask.get(MPMaskType.WEBGL_TEXTURE); + const result = mask.getAsWebGLTexture(); expect(readPixelsFromWebGLTexture(result)) .toEqual(readPixelsFromWebGLTexture(expected)); } @@ -183,7 +183,7 @@ class MPMaskTestContext { /* ownsWebGLTexture= */ false, context.canvas, shaderContext, WIDTH, HEIGHT); - const result = mask.clone().get(MPMaskType.UINT8_ARRAY); + const result = mask.clone().getAsUint8Array(); expect(result).toEqual(context.uint8Array); shaderContext.close(); }); @@ -199,13 +199,13 @@ class MPMaskTestContext { // Verify that we can mix the different shader modes by running them out of // order. - let result = mask.get(MPMaskType.UINT8_ARRAY); + let result = mask.getAsUint8Array(); expect(result).toEqual(context.uint8Array); - result = mask.clone().get(MPMaskType.UINT8_ARRAY); + result = mask.clone().getAsUint8Array(); expect(result).toEqual(context.uint8Array); - result = mask.get(MPMaskType.UINT8_ARRAY); + result = mask.getAsUint8Array(); expect(result).toEqual(context.uint8Array); shaderContext.close(); @@ -217,20 +217,21 @@ class MPMaskTestContext { const shaderContext = new MPImageShaderContext(); const mask = createImage(shaderContext, context.uint8Array, WIDTH, HEIGHT); - expect(mask.has(MPMaskType.UINT8_ARRAY)).toBe(true); - expect(mask.has(MPMaskType.FLOAT32_ARRAY)).toBe(false); - expect(mask.has(MPMaskType.WEBGL_TEXTURE)).toBe(false); + expect(mask.hasUint8Array()).toBe(true); + expect(mask.hasFloat32Array()).toBe(false); + expect(mask.hasWebGLTexture()).toBe(false); - mask.get(MPMaskType.FLOAT32_ARRAY); + mask.getAsFloat32Array(); - expect(mask.has(MPMaskType.UINT8_ARRAY)).toBe(true); - expect(mask.has(MPMaskType.FLOAT32_ARRAY)).toBe(true); + expect(mask.hasUint8Array()).toBe(true); + expect(mask.hasFloat32Array()).toBe(true); + expect(mask.hasWebGLTexture()).toBe(false); - mask.get(MPMaskType.WEBGL_TEXTURE); + mask.getAsWebGLTexture(); - expect(mask.has(MPMaskType.UINT8_ARRAY)).toBe(true); - expect(mask.has(MPMaskType.FLOAT32_ARRAY)).toBe(true); - expect(mask.has(MPMaskType.WEBGL_TEXTURE)).toBe(true); + expect(mask.hasUint8Array()).toBe(true); + expect(mask.hasFloat32Array()).toBe(true); + expect(mask.hasWebGLTexture()).toBe(true); mask.close(); shaderContext.close(); diff --git a/mediapipe/tasks/web/vision/core/mask.ts b/mediapipe/tasks/web/vision/core/mask.ts index a3dedf63a..da14f104f 100644 --- a/mediapipe/tasks/web/vision/core/mask.ts +++ b/mediapipe/tasks/web/vision/core/mask.ts @@ -17,7 +17,7 @@ import {assertNotNull, MPImageShaderContext} from '../../../../tasks/web/vision/core/image_shader_context'; /** The underlying type of the image. */ -export enum MPMaskType { +enum MPMaskType { /** Represents the native `UInt8Array` type. */ UINT8_ARRAY, /** Represents the native `Float32Array` type. */ @@ -34,9 +34,9 @@ export type MPMaskContainer = Uint8Array|Float32Array|WebGLTexture; * * Masks are stored as `Uint8Array`, `Float32Array` or `WebGLTexture` objects. * You can convert the underlying type to any other type by passing the desired - * type to `get()`. As type conversions can be expensive, it is recommended to - * limit these conversions. You can verify what underlying types are already - * available by invoking `has()`. + * type to `getAs...()`. As type conversions can be expensive, it is recommended + * to limit these conversions. You can verify what underlying types are already + * available by invoking `has...()`. * * Masks that are returned from a MediaPipe Tasks are owned by by the * underlying C++ Task. If you need to extend the lifetime of these objects, @@ -47,9 +47,6 @@ export type MPMaskContainer = Uint8Array|Float32Array|WebGLTexture; export class MPMask { private gl?: WebGL2RenderingContext; - /** The underlying type of the mask. */ - static TYPE = MPMaskType; - /** @hideconstructor */ constructor( private readonly containers: MPMaskContainer[], @@ -63,13 +60,19 @@ export class MPMask { readonly height: number, ) {} - /** - * Returns whether this `MPMask` stores the mask in the desired - * format. This method can be called to reduce expensive conversion before - * invoking `get()`. - */ - has(type: MPMaskType): boolean { - return !!this.getContainer(type); + /** Returns whether this `MPMask` contains a mask of type `Uint8Array`. */ + hasUint8Array(): boolean { + return !!this.getContainer(MPMaskType.UINT8_ARRAY); + } + + /** Returns whether this `MPMask` contains a mask of type `Float32Array`. */ + hasFloat32Array(): boolean { + return !!this.getContainer(MPMaskType.FLOAT32_ARRAY); + } + + /** Returns whether this `MPMask` contains a mask of type `WebGLTexture`. */ + hasWebGLTexture(): boolean { + return !!this.getContainer(MPMaskType.WEBGL_TEXTURE); } /** @@ -77,43 +80,35 @@ export class MPMask { * expensive GPU to CPU transfer if the current mask is only available as a * `WebGLTexture`. * - * @param type The type of mask to return. * @return The current data as a Uint8Array. */ - get(type: MPMaskType.UINT8_ARRAY): Uint8Array; + getAsUint8Array(): Uint8Array { + return this.convertToUint8Array(); + } + /** * Returns the underlying mask as a single channel `Float32Array`. Note that * this involves an expensive GPU to CPU transfer if the current mask is only * available as a `WebGLTexture`. * - * @param type The type of mask to return. * @return The current mask as a Float32Array. */ - get(type: MPMaskType.FLOAT32_ARRAY): Float32Array; + getAsFloat32Array(): Float32Array { + return this.convertToFloat32Array(); + } + /** * Returns the underlying mask as a `WebGLTexture` object. Note that this * involves a CPU to GPU transfer if the current mask is only available as * a CPU array. The returned texture is bound to the current canvas (see * `.canvas`). * - * @param type The type of mask to return. * @return The current mask as a WebGLTexture. */ - get(type: MPMaskType.WEBGL_TEXTURE): WebGLTexture; - get(type?: MPMaskType): MPMaskContainer { - switch (type) { - case MPMaskType.UINT8_ARRAY: - return this.convertToUint8Array(); - case MPMaskType.FLOAT32_ARRAY: - return this.convertToFloat32Array(); - case MPMaskType.WEBGL_TEXTURE: - return this.convertToWebGLTexture(); - default: - throw new Error(`Type is not supported: ${type}`); - } + getAsWebGLTexture(): WebGLTexture { + return this.convertToWebGLTexture(); } - private getContainer(type: MPMaskType.UINT8_ARRAY): Uint8Array|undefined; private getContainer(type: MPMaskType.FLOAT32_ARRAY): Float32Array|undefined; private getContainer(type: MPMaskType.WEBGL_TEXTURE): WebGLTexture|undefined; @@ -186,7 +181,7 @@ export class MPMask { } return new MPMask( - destinationContainers, this.has(MPMaskType.WEBGL_TEXTURE), this.canvas, + destinationContainers, this.hasWebGLTexture(), this.canvas, this.shaderContext, this.width, this.height); } @@ -220,9 +215,9 @@ export class MPMask { private convertToFloat32Array(): Float32Array { let float32Array = this.getContainer(MPMaskType.FLOAT32_ARRAY); if (!float32Array) { - if (this.has(MPMaskType.UINT8_ARRAY)) { - const source = this.getContainer(MPMaskType.UINT8_ARRAY)!; - float32Array = new Float32Array(source).map(v => v / 255); + const uint8Array = this.getContainer(MPMaskType.UINT8_ARRAY); + if (uint8Array) { + float32Array = new Float32Array(uint8Array).map(v => v / 255); } else { const gl = this.getGL(); const shaderContext = this.getShaderContext(); diff --git a/mediapipe/tasks/web/vision/index.ts b/mediapipe/tasks/web/vision/index.ts index ea385fdfc..5b643b84e 100644 --- a/mediapipe/tasks/web/vision/index.ts +++ b/mediapipe/tasks/web/vision/index.ts @@ -17,7 +17,7 @@ import {FilesetResolver as FilesetResolverImpl} from '../../../tasks/web/core/fileset_resolver'; import {DrawingUtils as DrawingUtilsImpl} from '../../../tasks/web/vision/core/drawing_utils'; import {MPImage as MPImageImpl} from '../../../tasks/web/vision/core/image'; -import {MPMask as MPMaskImpl, MPMaskType as MPMaskTypeImpl} from '../../../tasks/web/vision/core/mask'; +import {MPMask as MPMaskImpl} from '../../../tasks/web/vision/core/mask'; import {FaceDetector as FaceDetectorImpl} from '../../../tasks/web/vision/face_detector/face_detector'; import {FaceLandmarker as FaceLandmarkerImpl, FaceLandmarksConnections as FaceLandmarksConnectionsImpl} from '../../../tasks/web/vision/face_landmarker/face_landmarker'; import {FaceStylizer as FaceStylizerImpl} from '../../../tasks/web/vision/face_stylizer/face_stylizer'; @@ -36,7 +36,6 @@ const DrawingUtils = DrawingUtilsImpl; const FilesetResolver = FilesetResolverImpl; const MPImage = MPImageImpl; const MPMask = MPMaskImpl; -const MPMaskType = MPMaskTypeImpl; const FaceDetector = FaceDetectorImpl; const FaceLandmarker = FaceLandmarkerImpl; const FaceLandmarksConnections = FaceLandmarksConnectionsImpl; @@ -55,7 +54,6 @@ export { FilesetResolver, MPImage, MPMask, - MPMaskType, FaceDetector, FaceLandmarker, FaceLandmarksConnections, diff --git a/mediapipe/tasks/web/vision/types.ts b/mediapipe/tasks/web/vision/types.ts index 203983fa1..760b97b77 100644 --- a/mediapipe/tasks/web/vision/types.ts +++ b/mediapipe/tasks/web/vision/types.ts @@ -17,7 +17,7 @@ export * from '../../../tasks/web/core/fileset_resolver'; export * from '../../../tasks/web/vision/core/drawing_utils'; export {MPImage} from '../../../tasks/web/vision/core/image'; -export {MPMask, MPMaskType} from '../../../tasks/web/vision/core/mask'; +export {MPMask} from '../../../tasks/web/vision/core/mask'; export * from '../../../tasks/web/vision/face_detector/face_detector'; export * from '../../../tasks/web/vision/face_landmarker/face_landmarker'; export * from '../../../tasks/web/vision/face_stylizer/face_stylizer'; From 876987b389986f44cbc166ad26373592b0bf30b5 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Sat, 6 May 2023 12:55:55 -0700 Subject: [PATCH 235/753] Remove auxiliary landmarks in PoseLandmarker API results. PiperOrigin-RevId: 529989746 --- .../vision/pose_landmarker/pose_landmarker.cc | 21 ++---------- .../pose_landmarker/pose_landmarker_result.cc | 9 +---- .../pose_landmarker/pose_landmarker_result.h | 7 +--- .../pose_landmarker_result_test.cc | 20 +---------- .../vision/poselandmarker/PoseLandmarker.java | 8 +---- .../poselandmarker/PoseLandmarkerResult.java | 19 ----------- .../poselandmarker/PoseLandmarkerTest.java | 1 - .../test/vision/pose_landmarker_test.py | 6 ++-- .../tasks/python/vision/pose_landmarker.py | 33 +++--------------- .../vision/pose_landmarker/pose_landmarker.ts | 34 ------------------- .../pose_landmarker_result.d.ts | 3 -- .../pose_landmarker/pose_landmarker_test.ts | 28 ++++----------- 12 files changed, 19 insertions(+), 170 deletions(-) diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.cc index f421c7376..797e71488 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker.cc @@ -63,8 +63,6 @@ constexpr char kNormLandmarksTag[] = "NORM_LANDMARKS"; constexpr char kNormLandmarksStreamName[] = "norm_landmarks"; constexpr char kPoseWorldLandmarksTag[] = "WORLD_LANDMARKS"; constexpr char kPoseWorldLandmarksStreamName[] = "world_landmarks"; -constexpr char kPoseAuxiliaryLandmarksTag[] = "AUXILIARY_LANDMARKS"; -constexpr char kPoseAuxiliaryLandmarksStreamName[] = "auxiliary_landmarks"; constexpr int kMicroSecondsPerMilliSecond = 1000; // Creates a MediaPipe graph config that contains a subgraph node of @@ -83,9 +81,6 @@ CalculatorGraphConfig CreateGraphConfig( graph.Out(kNormLandmarksTag); subgraph.Out(kPoseWorldLandmarksTag).SetName(kPoseWorldLandmarksStreamName) >> graph.Out(kPoseWorldLandmarksTag); - subgraph.Out(kPoseAuxiliaryLandmarksTag) - .SetName(kPoseAuxiliaryLandmarksStreamName) >> - graph.Out(kPoseAuxiliaryLandmarksTag); subgraph.Out(kImageTag).SetName(kImageOutStreamName) >> graph.Out(kImageTag); if (output_segmentation_masks) { subgraph.Out(kSegmentationMaskTag).SetName(kSegmentationMaskStreamName) >> @@ -163,8 +158,6 @@ absl::StatusOr> PoseLandmarker::Create( status_or_packets.value()[kNormLandmarksStreamName]; Packet pose_world_landmarks_packet = status_or_packets.value()[kPoseWorldLandmarksStreamName]; - Packet pose_auxiliary_landmarks_packet = - status_or_packets.value()[kPoseAuxiliaryLandmarksStreamName]; std::optional> segmentation_mask = std::nullopt; if (output_segmentation_masks) { segmentation_mask = segmentation_mask_packet.Get>(); @@ -175,9 +168,7 @@ absl::StatusOr> PoseLandmarker::Create( /* pose_landmarks= */ pose_landmarks_packet.Get>(), /* pose_world_landmarks= */ - pose_world_landmarks_packet.Get>(), - pose_auxiliary_landmarks_packet - .Get>()), + pose_world_landmarks_packet.Get>()), image_packet.Get(), pose_landmarks_packet.Timestamp().Value() / kMicroSecondsPerMilliSecond); @@ -234,10 +225,7 @@ absl::StatusOr PoseLandmarker::Detect( .Get>(), /* pose_world_landmarks */ output_packets[kPoseWorldLandmarksStreamName] - .Get>(), - /*pose_auxiliary_landmarks= */ - output_packets[kPoseAuxiliaryLandmarksStreamName] - .Get>()); + .Get>()); } absl::StatusOr PoseLandmarker::DetectForVideo( @@ -277,10 +265,7 @@ absl::StatusOr PoseLandmarker::DetectForVideo( .Get>(), /* pose_world_landmarks */ output_packets[kPoseWorldLandmarksStreamName] - .Get>(), - /* pose_auxiliary_landmarks= */ - output_packets[kPoseAuxiliaryLandmarksStreamName] - .Get>()); + .Get>()); } absl::Status PoseLandmarker::DetectAsync( diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.cc index 77f374d1e..da4c630b3 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.cc @@ -27,15 +27,12 @@ namespace pose_landmarker { PoseLandmarkerResult ConvertToPoseLandmarkerResult( std::optional> segmentation_masks, const std::vector& pose_landmarks_proto, - const std::vector& pose_world_landmarks_proto, - const std::vector& - pose_auxiliary_landmarks_proto) { + const std::vector& pose_world_landmarks_proto) { PoseLandmarkerResult result; result.segmentation_masks = segmentation_masks; result.pose_landmarks.resize(pose_landmarks_proto.size()); result.pose_world_landmarks.resize(pose_world_landmarks_proto.size()); - result.pose_auxiliary_landmarks.resize(pose_auxiliary_landmarks_proto.size()); std::transform(pose_landmarks_proto.begin(), pose_landmarks_proto.end(), result.pose_landmarks.begin(), components::containers::ConvertToNormalizedLandmarks); @@ -43,10 +40,6 @@ PoseLandmarkerResult ConvertToPoseLandmarkerResult( pose_world_landmarks_proto.end(), result.pose_world_landmarks.begin(), components::containers::ConvertToLandmarks); - std::transform(pose_auxiliary_landmarks_proto.begin(), - pose_auxiliary_landmarks_proto.end(), - result.pose_auxiliary_landmarks.begin(), - components::containers::ConvertToNormalizedLandmarks); return result; } diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.h b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.h index f45994837..8978e5147 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.h +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result.h @@ -37,17 +37,12 @@ struct PoseLandmarkerResult { std::vector pose_landmarks; // Detected pose landmarks in world coordinates. std::vector pose_world_landmarks; - // Detected auxiliary landmarks, used for deriving ROI for next frame. - std::vector - pose_auxiliary_landmarks; }; PoseLandmarkerResult ConvertToPoseLandmarkerResult( std::optional> segmentation_mask, const std::vector& pose_landmarks_proto, - const std::vector& pose_world_landmarks_proto, - const std::vector& - pose_auxiliary_landmarks_proto); + const std::vector& pose_world_landmarks_proto); } // namespace pose_landmarker } // namespace vision diff --git a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result_test.cc b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result_test.cc index 14916215c..05e83b655 100644 --- a/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result_test.cc +++ b/mediapipe/tasks/cc/vision/pose_landmarker/pose_landmarker_result_test.cc @@ -47,13 +47,6 @@ TEST(ConvertFromProto, Succeeds) { landmark_proto.set_y(5.2); landmark_proto.set_z(4.3); - mediapipe::NormalizedLandmarkList auxiliary_landmark_list_proto; - mediapipe::NormalizedLandmark& auxiliary_landmark_proto = - *auxiliary_landmark_list_proto.add_landmark(); - auxiliary_landmark_proto.set_x(0.5); - auxiliary_landmark_proto.set_y(0.5); - auxiliary_landmark_proto.set_z(0.5); - std::vector segmentation_masks_lists = {segmentation_mask}; std::vector normalized_landmarks_lists = { @@ -62,12 +55,9 @@ TEST(ConvertFromProto, Succeeds) { std::vector world_landmarks_lists = { world_landmark_list_proto}; - std::vector auxiliary_landmarks_lists = { - auxiliary_landmark_list_proto}; - PoseLandmarkerResult pose_landmarker_result = ConvertToPoseLandmarkerResult( segmentation_masks_lists, normalized_landmarks_lists, - world_landmarks_lists, auxiliary_landmarks_lists); + world_landmarks_lists); EXPECT_EQ(pose_landmarker_result.pose_landmarks.size(), 1); EXPECT_EQ(pose_landmarker_result.pose_landmarks[0].landmarks.size(), 1); @@ -82,14 +72,6 @@ TEST(ConvertFromProto, Succeeds) { testing::FieldsAre(testing::FloatEq(3.1), testing::FloatEq(5.2), testing::FloatEq(4.3), std::nullopt, std::nullopt, std::nullopt)); - - EXPECT_EQ(pose_landmarker_result.pose_auxiliary_landmarks.size(), 1); - EXPECT_EQ(pose_landmarker_result.pose_auxiliary_landmarks[0].landmarks.size(), - 1); - EXPECT_THAT(pose_landmarker_result.pose_auxiliary_landmarks[0].landmarks[0], - testing::FieldsAre(testing::FloatEq(0.5), testing::FloatEq(0.5), - testing::FloatEq(0.5), std::nullopt, - std::nullopt, std::nullopt)); } } // namespace pose_landmarker diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java index 2ebdc0732..fa2d3da17 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java @@ -79,8 +79,7 @@ public final class PoseLandmarker extends BaseVisionTaskApi { private static final int LANDMARKS_OUT_STREAM_INDEX = 0; private static final int WORLD_LANDMARKS_OUT_STREAM_INDEX = 1; - private static final int AUXILIARY_LANDMARKS_OUT_STREAM_INDEX = 2; - private static final int IMAGE_OUT_STREAM_INDEX = 3; + private static final int IMAGE_OUT_STREAM_INDEX = 2; private static int segmentationMasksOutStreamIndex = -1; private static final String TASK_GRAPH_NAME = "mediapipe.tasks.vision.pose_landmarker.PoseLandmarkerGraph"; @@ -145,7 +144,6 @@ public final class PoseLandmarker extends BaseVisionTaskApi { List outputStreams = new ArrayList<>(); outputStreams.add("NORM_LANDMARKS:pose_landmarks"); outputStreams.add("WORLD_LANDMARKS:world_landmarks"); - outputStreams.add("AUXILIARY_LANDMARKS:auxiliary_landmarks"); outputStreams.add("IMAGE:image_out"); if (landmarkerOptions.outputSegmentationMasks()) { outputStreams.add("SEGMENTATION_MASK:segmentation_masks"); @@ -161,7 +159,6 @@ public final class PoseLandmarker extends BaseVisionTaskApi { // If there is no poses detected in the image, just returns empty lists. if (packets.get(LANDMARKS_OUT_STREAM_INDEX).isEmpty()) { return PoseLandmarkerResult.create( - new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), Optional.empty(), @@ -179,9 +176,6 @@ public final class PoseLandmarker extends BaseVisionTaskApi { packets.get(LANDMARKS_OUT_STREAM_INDEX), NormalizedLandmarkList.parser()), PacketGetter.getProtoVector( packets.get(WORLD_LANDMARKS_OUT_STREAM_INDEX), LandmarkList.parser()), - PacketGetter.getProtoVector( - packets.get(AUXILIARY_LANDMARKS_OUT_STREAM_INDEX), - NormalizedLandmarkList.parser()), segmentedMasks, BaseVisionTaskApi.generateResultTimestampMs( landmarkerOptions.runningMode(), packets.get(LANDMARKS_OUT_STREAM_INDEX))); diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerResult.java index 488f2a556..389e78266 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerResult.java @@ -40,7 +40,6 @@ public abstract class PoseLandmarkerResult implements TaskResult { static PoseLandmarkerResult create( List landmarksProto, List worldLandmarksProto, - List auxiliaryLandmarksProto, Optional> segmentationMasksData, long timestampMs) { @@ -52,7 +51,6 @@ public abstract class PoseLandmarkerResult implements TaskResult { List> multiPoseLandmarks = new ArrayList<>(); List> multiPoseWorldLandmarks = new ArrayList<>(); - List> multiPoseAuxiliaryLandmarks = new ArrayList<>(); for (LandmarkProto.NormalizedLandmarkList poseLandmarksProto : landmarksProto) { List poseLandmarks = new ArrayList<>(); multiPoseLandmarks.add(poseLandmarks); @@ -75,24 +73,10 @@ public abstract class PoseLandmarkerResult implements TaskResult { poseWorldLandmarkProto.getZ())); } } - for (LandmarkProto.NormalizedLandmarkList poseAuxiliaryLandmarksProto : - auxiliaryLandmarksProto) { - List poseAuxiliaryLandmarks = new ArrayList<>(); - multiPoseAuxiliaryLandmarks.add(poseAuxiliaryLandmarks); - for (LandmarkProto.NormalizedLandmark poseAuxiliaryLandmarkProto : - poseAuxiliaryLandmarksProto.getLandmarkList()) { - poseAuxiliaryLandmarks.add( - NormalizedLandmark.create( - poseAuxiliaryLandmarkProto.getX(), - poseAuxiliaryLandmarkProto.getY(), - poseAuxiliaryLandmarkProto.getZ())); - } - } return new AutoValue_PoseLandmarkerResult( timestampMs, Collections.unmodifiableList(multiPoseLandmarks), Collections.unmodifiableList(multiPoseWorldLandmarks), - Collections.unmodifiableList(multiPoseAuxiliaryLandmarks), multiPoseSegmentationMasks); } @@ -105,9 +89,6 @@ public abstract class PoseLandmarkerResult implements TaskResult { /** Pose landmarks in world coordniates of detected poses. */ public abstract List> worldLandmarks(); - /** Pose auxiliary landmarks. */ - public abstract List> auxiliaryLandmarks(); - /** Pose segmentation masks. */ public abstract Optional> segmentationMasks(); } diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerTest.java index 1d0b1decd..7adef9e27 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarkerTest.java @@ -330,7 +330,6 @@ public class PoseLandmarkerTest { return PoseLandmarkerResult.create( Arrays.asList(landmarksDetectionResultProto.getLandmarks()), Arrays.asList(landmarksDetectionResultProto.getWorldLandmarks()), - Arrays.asList(), Optional.empty(), /* timestampMs= */ 0); } diff --git a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py index 1b73ecdfb..fff6879cc 100644 --- a/mediapipe/tasks/python/test/vision/pose_landmarker_test.py +++ b/mediapipe/tasks/python/test/vision/pose_landmarker_test.py @@ -74,7 +74,6 @@ def _get_expected_pose_landmarker_result( return PoseLandmarkerResult( pose_landmarks=[landmarks_detection_result.landmarks], pose_world_landmarks=[], - pose_auxiliary_landmarks=[], ) @@ -296,7 +295,6 @@ class PoseLandmarkerTest(parameterized.TestCase): # Comparing results. self.assertEmpty(detection_result.pose_landmarks) self.assertEmpty(detection_result.pose_world_landmarks) - self.assertEmpty(detection_result.pose_auxiliary_landmarks) def test_missing_result_callback(self): options = _PoseLandmarkerOptions( @@ -391,7 +389,7 @@ class PoseLandmarkerTest(parameterized.TestCase): True, _get_expected_pose_landmarker_result(_POSE_LANDMARKS), ), - (_BURGER_IMAGE, 0, False, PoseLandmarkerResult([], [], [])), + (_BURGER_IMAGE, 0, False, PoseLandmarkerResult([], [])), ) def test_detect_for_video( self, image_path, rotation, output_segmentation_masks, expected_result @@ -473,7 +471,7 @@ class PoseLandmarkerTest(parameterized.TestCase): True, _get_expected_pose_landmarker_result(_POSE_LANDMARKS), ), - (_BURGER_IMAGE, 0, False, PoseLandmarkerResult([], [], [])), + (_BURGER_IMAGE, 0, False, PoseLandmarkerResult([], [])), ) def test_detect_async_calls( self, image_path, rotation, output_segmentation_masks, expected_result diff --git a/mediapipe/tasks/python/vision/pose_landmarker.py b/mediapipe/tasks/python/vision/pose_landmarker.py index 3ff7edb0a..8f67e6739 100644 --- a/mediapipe/tasks/python/vision/pose_landmarker.py +++ b/mediapipe/tasks/python/vision/pose_landmarker.py @@ -49,8 +49,6 @@ _NORM_LANDMARKS_STREAM_NAME = 'norm_landmarks' _NORM_LANDMARKS_TAG = 'NORM_LANDMARKS' _POSE_WORLD_LANDMARKS_STREAM_NAME = 'world_landmarks' _POSE_WORLD_LANDMARKS_TAG = 'WORLD_LANDMARKS' -_POSE_AUXILIARY_LANDMARKS_STREAM_NAME = 'auxiliary_landmarks' -_POSE_AUXILIARY_LANDMARKS_TAG = 'AUXILIARY_LANDMARKS' _TASK_GRAPH_NAME = 'mediapipe.tasks.vision.pose_landmarker.PoseLandmarkerGraph' _MICRO_SECONDS_PER_MILLISECOND = 1000 @@ -62,14 +60,11 @@ class PoseLandmarkerResult: Attributes: pose_landmarks: Detected pose landmarks in normalized image coordinates. pose_world_landmarks: Detected pose landmarks in world coordinates. - pose_auxiliary_landmarks: Detected auxiliary landmarks, used for deriving - ROI for next frame. segmentation_masks: Optional segmentation masks for pose. """ pose_landmarks: List[List[landmark_module.NormalizedLandmark]] pose_world_landmarks: List[List[landmark_module.Landmark]] - pose_auxiliary_landmarks: List[List[landmark_module.NormalizedLandmark]] segmentation_masks: Optional[List[image_module.Image]] = None @@ -77,7 +72,7 @@ def _build_landmarker_result( output_packets: Mapping[str, packet_module.Packet] ) -> PoseLandmarkerResult: """Constructs a `PoseLandmarkerResult` from output packets.""" - pose_landmarker_result = PoseLandmarkerResult([], [], []) + pose_landmarker_result = PoseLandmarkerResult([], []) if _SEGMENTATION_MASK_STREAM_NAME in output_packets: pose_landmarker_result.segmentation_masks = packet_getter.get_image_list( @@ -90,9 +85,6 @@ def _build_landmarker_result( pose_world_landmarks_proto_list = packet_getter.get_proto_list( output_packets[_POSE_WORLD_LANDMARKS_STREAM_NAME] ) - pose_auxiliary_landmarks_proto_list = packet_getter.get_proto_list( - output_packets[_POSE_AUXILIARY_LANDMARKS_STREAM_NAME] - ) for proto in pose_landmarks_proto_list: pose_landmarks = landmark_pb2.NormalizedLandmarkList() @@ -116,19 +108,6 @@ def _build_landmarker_result( pose_world_landmarks_list ) - for proto in pose_auxiliary_landmarks_proto_list: - pose_auxiliary_landmarks = landmark_pb2.NormalizedLandmarkList() - pose_auxiliary_landmarks.MergeFrom(proto) - pose_auxiliary_landmarks_list = [] - for pose_auxiliary_landmark in pose_auxiliary_landmarks.landmark: - pose_auxiliary_landmarks_list.append( - landmark_module.NormalizedLandmark.create_from_pb2( - pose_auxiliary_landmark - ) - ) - pose_landmarker_result.pose_auxiliary_landmarks.append( - pose_auxiliary_landmarks_list - ) return pose_landmarker_result @@ -301,7 +280,7 @@ class PoseLandmarker(base_vision_task_api.BaseVisionTaskApi): if output_packets[_NORM_LANDMARKS_STREAM_NAME].is_empty(): empty_packet = output_packets[_NORM_LANDMARKS_STREAM_NAME] options.result_callback( - PoseLandmarkerResult([], [], []), + PoseLandmarkerResult([], []), image, empty_packet.timestamp.value // _MICRO_SECONDS_PER_MILLISECOND, ) @@ -320,10 +299,6 @@ class PoseLandmarker(base_vision_task_api.BaseVisionTaskApi): ':'.join( [_POSE_WORLD_LANDMARKS_TAG, _POSE_WORLD_LANDMARKS_STREAM_NAME] ), - ':'.join([ - _POSE_AUXILIARY_LANDMARKS_TAG, - _POSE_AUXILIARY_LANDMARKS_STREAM_NAME, - ]), ':'.join([_IMAGE_TAG, _IMAGE_OUT_STREAM_NAME]), ] @@ -382,7 +357,7 @@ class PoseLandmarker(base_vision_task_api.BaseVisionTaskApi): }) if output_packets[_NORM_LANDMARKS_STREAM_NAME].is_empty(): - return PoseLandmarkerResult([], [], []) + return PoseLandmarkerResult([], []) return _build_landmarker_result(output_packets) @@ -427,7 +402,7 @@ class PoseLandmarker(base_vision_task_api.BaseVisionTaskApi): }) if output_packets[_NORM_LANDMARKS_STREAM_NAME].is_empty(): - return PoseLandmarkerResult([], [], []) + return PoseLandmarkerResult([], []) return _build_landmarker_result(output_packets) diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts index cecf16225..87fdacbc2 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts @@ -43,7 +43,6 @@ const IMAGE_STREAM = 'image_in'; const NORM_RECT_STREAM = 'norm_rect'; const NORM_LANDMARKS_STREAM = 'normalized_landmarks'; const WORLD_LANDMARKS_STREAM = 'world_landmarks'; -const AUXILIARY_LANDMARKS_STREAM = 'auxiliary_landmarks'; const SEGMENTATION_MASK_STREAM = 'segmentation_masks'; const POSE_LANDMARKER_GRAPH = 'mediapipe.tasks.vision.pose_landmarker.PoseLandmarkerGraph'; @@ -371,9 +370,6 @@ export class PoseLandmarker extends VisionTaskRunner { if (!('worldLandmarks' in this.result)) { return; } - if (!('auxilaryLandmarks' in this.result)) { - return; - } if (this.outputSegmentationMasks && !('segmentationMasks' in this.result)) { return; } @@ -419,20 +415,6 @@ export class PoseLandmarker extends VisionTaskRunner { } } - /** - * Converts raw data into a landmark, and adds it to our auxilary - * landmarks list. - */ - private addJsAuxiliaryLandmarks(data: Uint8Array[]): void { - this.result.auxilaryLandmarks = []; - for (const binaryProto of data) { - const auxiliaryLandmarksProto = - NormalizedLandmarkList.deserializeBinary(binaryProto); - this.result.auxilaryLandmarks.push( - convertToLandmarks(auxiliaryLandmarksProto)); - } - } - /** Updates the MediaPipe graph configuration. */ protected override refreshGraph(): void { const graphConfig = new CalculatorGraphConfig(); @@ -440,7 +422,6 @@ export class PoseLandmarker extends VisionTaskRunner { graphConfig.addInputStream(NORM_RECT_STREAM); graphConfig.addOutputStream(NORM_LANDMARKS_STREAM); graphConfig.addOutputStream(WORLD_LANDMARKS_STREAM); - graphConfig.addOutputStream(AUXILIARY_LANDMARKS_STREAM); graphConfig.addOutputStream(SEGMENTATION_MASK_STREAM); const calculatorOptions = new CalculatorOptions(); @@ -453,8 +434,6 @@ export class PoseLandmarker extends VisionTaskRunner { landmarkerNode.addInputStream('NORM_RECT:' + NORM_RECT_STREAM); landmarkerNode.addOutputStream('NORM_LANDMARKS:' + NORM_LANDMARKS_STREAM); landmarkerNode.addOutputStream('WORLD_LANDMARKS:' + WORLD_LANDMARKS_STREAM); - landmarkerNode.addOutputStream( - 'AUXILIARY_LANDMARKS:' + AUXILIARY_LANDMARKS_STREAM); landmarkerNode.setOptions(calculatorOptions); graphConfig.addNode(landmarkerNode); @@ -485,19 +464,6 @@ export class PoseLandmarker extends VisionTaskRunner { this.maybeInvokeCallback(); }); - this.graphRunner.attachProtoVectorListener( - AUXILIARY_LANDMARKS_STREAM, (binaryProto, timestamp) => { - this.addJsAuxiliaryLandmarks(binaryProto); - this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); - }); - this.graphRunner.attachEmptyPacketListener( - AUXILIARY_LANDMARKS_STREAM, timestamp => { - this.result.auxilaryLandmarks = []; - this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); - }); - if (this.outputSegmentationMasks) { landmarkerNode.addOutputStream( 'SEGMENTATION_MASK:' + SEGMENTATION_MASK_STREAM); diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts index 980408069..96e698a85 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts @@ -31,9 +31,6 @@ export declare interface PoseLandmarkerResult { /** Pose landmarks in world coordinates of detected poses. */ worldLandmarks: Landmark[][]; - /** Detected auxiliary landmarks, used for deriving ROI for next frame. */ - auxilaryLandmarks: NormalizedLandmark[][]; - /** Segmentation mask for the detected pose. */ segmentationMasks?: MPMask[]; } diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts index bb04ce683..d4a49db97 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts @@ -45,8 +45,7 @@ class PoseLandmarkerFake extends PoseLandmarker implements MediapipeTasksFake { this.attachListenerSpies[0] = spyOn(this.graphRunner, 'attachProtoVectorListener') .and.callFake((stream, listener) => { - expect(stream).toMatch( - /(normalized_landmarks|world_landmarks|auxiliary_landmarks)/); + expect(stream).toMatch(/(normalized_landmarks|world_landmarks)/); this.listeners.set(stream, listener as PacketListener); }); this.attachListenerSpies[1] = @@ -80,23 +79,23 @@ describe('PoseLandmarker', () => { it('initializes graph', async () => { verifyGraph(poseLandmarker); - expect(poseLandmarker.listeners).toHaveSize(3); + expect(poseLandmarker.listeners).toHaveSize(2); }); it('reloads graph when settings are changed', async () => { await poseLandmarker.setOptions({numPoses: 1}); verifyGraph(poseLandmarker, [['poseDetectorGraphOptions', 'numPoses'], 1]); - expect(poseLandmarker.listeners).toHaveSize(3); + expect(poseLandmarker.listeners).toHaveSize(2); await poseLandmarker.setOptions({numPoses: 5}); verifyGraph(poseLandmarker, [['poseDetectorGraphOptions', 'numPoses'], 5]); - expect(poseLandmarker.listeners).toHaveSize(3); + expect(poseLandmarker.listeners).toHaveSize(2); }); it('registers listener for segmentation masks', async () => { - expect(poseLandmarker.listeners).toHaveSize(3); + expect(poseLandmarker.listeners).toHaveSize(2); await poseLandmarker.setOptions({outputSegmentationMasks: true}); - expect(poseLandmarker.listeners).toHaveSize(4); + expect(poseLandmarker.listeners).toHaveSize(3); }); it('merges options', async () => { @@ -209,8 +208,6 @@ describe('PoseLandmarker', () => { (landmarksProto, 1337); poseLandmarker.listeners.get('world_landmarks')! (worldLandmarksProto, 1337); - poseLandmarker.listeners.get('auxiliary_landmarks')! - (landmarksProto, 1337); poseLandmarker.listeners.get('segmentation_masks')!(masks, 1337); }); @@ -224,7 +221,6 @@ describe('PoseLandmarker', () => { expect(result.landmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); expect(result.worldLandmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); - expect(result.auxilaryLandmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); expect(result.segmentationMasks![0]).toBeInstanceOf(MPMask); done(); }); @@ -240,8 +236,6 @@ describe('PoseLandmarker', () => { (landmarksProto, 1337); poseLandmarker.listeners.get('world_landmarks')! (worldLandmarksProto, 1337); - poseLandmarker.listeners.get('auxiliary_landmarks')! - (landmarksProto, 1337); }); // Invoke the pose landmarker twice @@ -279,8 +273,6 @@ describe('PoseLandmarker', () => { (landmarksProto, 1337); poseLandmarker.listeners.get('world_landmarks')! (worldLandmarksProto, 1337); - poseLandmarker.listeners.get('auxiliary_landmarks')! - (landmarksProto, 1337); }); // Invoke the pose landmarker @@ -291,9 +283,6 @@ describe('PoseLandmarker', () => { expect(result.worldLandmarks).toEqual([ [{'x': 1, 'y': 2, 'z': 3}], [{'x': 4, 'y': 5, 'z': 6}] ]); - expect(result.auxilaryLandmarks).toEqual([ - [{'x': 0.1, 'y': 0.2, 'z': 0.3}], [{'x': 0.4, 'y': 0.5, 'z': 0.6}] - ]); done(); }); }); @@ -318,8 +307,6 @@ describe('PoseLandmarker', () => { poseLandmarker.listeners.get('world_landmarks')! (worldLandmarksProto, 1337); expect(listenerCalled).toBeFalse(); - poseLandmarker.listeners.get('auxiliary_landmarks')! - (landmarksProto, 1337); expect(listenerCalled).toBeFalse(); poseLandmarker.listeners.get('segmentation_masks')!(masks, 1337); expect(listenerCalled).toBeTrue(); @@ -342,8 +329,6 @@ describe('PoseLandmarker', () => { (landmarksProto, 1337); poseLandmarker.listeners.get('world_landmarks')! (worldLandmarksProto, 1337); - poseLandmarker.listeners.get('auxiliary_landmarks')! - (landmarksProto, 1337); }); // Invoke the pose landmarker @@ -351,6 +336,5 @@ describe('PoseLandmarker', () => { expect(poseLandmarker.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); expect(result.landmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); expect(result.worldLandmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); - expect(result.auxilaryLandmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); }); }); From 613f645c746488943b84c6d55e30dfb7299f55e8 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Sun, 7 May 2023 11:23:53 -0700 Subject: [PATCH 236/753] Update CalculatorOptions to encourage proto3 options PiperOrigin-RevId: 530127533 --- mediapipe/framework/calculator_options.proto | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/mediapipe/framework/calculator_options.proto b/mediapipe/framework/calculator_options.proto index 747e9c4af..3bc9f6615 100644 --- a/mediapipe/framework/calculator_options.proto +++ b/mediapipe/framework/calculator_options.proto @@ -23,15 +23,13 @@ package mediapipe; option java_package = "com.google.mediapipe.proto"; option java_outer_classname = "CalculatorOptionsProto"; -// Options for Calculators. Each Calculator implementation should -// have its own options proto, which should look like this: +// Options for Calculators, DEPRECATED. New calculators are encouraged to use +// proto3 syntax options: // // message MyCalculatorOptions { -// extend CalculatorOptions { -// optional MyCalculatorOptions ext = ; -// } -// optional string field_needed_by_my_calculator = 1; -// optional int32 another_field = 2; +// // proto3 does not expect "optional" +// string field_needed_by_my_calculator = 1; +// int32 another_field = 2; // // etc // } message CalculatorOptions { From 26810b6b84f35d30f90b90065b31668ab770ec8b Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Mon, 8 May 2023 16:30:40 +0530 Subject: [PATCH 237/753] Reverted back to using containers and options in BUILD --- mediapipe/tasks/ios/BUILD | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index 6d18baf3d..65b6507d2 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -34,13 +34,13 @@ licenses(["notice"]) # 2. Task graphs. These will be built with ":MediaPipeTaskGraphs_library". # 3. gpu targets which will be built with the ":MediaPipeTaskGraphs_library". OBJC_COMMON_DEPS = [ - "//mediapipe/tasks/ios/core/utils:MPPBaseOptionsHelpers", + "//mediapipe/tasks/ios/core/utils:MPPBaseOptions", "//mediapipe/tasks/ios/core:MPPTaskInfo", "//mediapipe/tasks/ios/core:MPPTaskOptions", "//mediapipe/tasks/ios/core:MPPTaskResult", "//mediapipe/tasks/ios/core:MPPTaskRunner", - "//mediapipe/tasks/ios/components/containers/utils:MPPClassificationResultHelpers", - "//mediapipe/tasks/ios/components/containers/utils:MPPCategoryHelpers", + "//mediapipe/tasks/ios/components/containers/utils:MPPClassificationResult", + "//mediapipe/tasks/ios/components/containers/utils:MPPCategory", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", "//mediapipe/calculators/core:flow_limiter_calculator", "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", @@ -204,9 +204,9 @@ apple_static_xcframework( }, deps = [ "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", - "//mediapipe/tasks/ios/components/containers/utils:MPPCategoryHelpers", - "//mediapipe/tasks/ios/components/containers/utils:MPPClassificationResultHelpers", - "//mediapipe/tasks/ios/core/utils:MPPBaseOptionsHelpers", + "//mediapipe/tasks/ios/components/containers/utils:MPPCategory", + "//mediapipe/tasks/ios/components/containers/utils:MPPClassificationResult", + "//mediapipe/tasks/ios/core/utils:MPPBaseOptions", "//mediapipe/tasks/ios/core:MPPTaskInfo", "//mediapipe/tasks/ios/core:MPPTaskOptions", "//mediapipe/tasks/ios/core:MPPTaskResult", From 18656434869dee030cd2ea6e1368fa469f14f9d4 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Mon, 8 May 2023 16:32:04 +0530 Subject: [PATCH 238/753] Fixed deps in ios task BUILD file --- mediapipe/tasks/ios/BUILD | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index 65b6507d2..e05f03d61 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -34,13 +34,13 @@ licenses(["notice"]) # 2. Task graphs. These will be built with ":MediaPipeTaskGraphs_library". # 3. gpu targets which will be built with the ":MediaPipeTaskGraphs_library". OBJC_COMMON_DEPS = [ - "//mediapipe/tasks/ios/core/utils:MPPBaseOptions", + "//mediapipe/tasks/ios/core:MPPBaseOptions", "//mediapipe/tasks/ios/core:MPPTaskInfo", "//mediapipe/tasks/ios/core:MPPTaskOptions", "//mediapipe/tasks/ios/core:MPPTaskResult", "//mediapipe/tasks/ios/core:MPPTaskRunner", - "//mediapipe/tasks/ios/components/containers/utils:MPPClassificationResult", - "//mediapipe/tasks/ios/components/containers/utils:MPPCategory", + "//mediapipe/tasks/ios/components/containers:MPPClassificationResult", + "//mediapipe/tasks/ios/components/containers:MPPCategory", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", "//mediapipe/calculators/core:flow_limiter_calculator", "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", @@ -204,9 +204,9 @@ apple_static_xcframework( }, deps = [ "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", - "//mediapipe/tasks/ios/components/containers/utils:MPPCategory", - "//mediapipe/tasks/ios/components/containers/utils:MPPClassificationResult", - "//mediapipe/tasks/ios/core/utils:MPPBaseOptions", + "//mediapipe/tasks/ios/components/containers:MPPCategory", + "//mediapipe/tasks/ios/components/containers:MPPClassificationResult", + "//mediapipe/tasks/ios/core:MPPBaseOptions", "//mediapipe/tasks/ios/core:MPPTaskInfo", "//mediapipe/tasks/ios/core:MPPTaskOptions", "//mediapipe/tasks/ios/core:MPPTaskResult", From 946042aca119c9a0ab321d5e51cf869111f46836 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Mon, 8 May 2023 16:33:09 +0530 Subject: [PATCH 239/753] Reverted addition of flow limiter calculator in image classifier iOS --- mediapipe/tasks/ios/BUILD | 2 -- 1 file changed, 2 deletions(-) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index e05f03d61..c839acd84 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -42,7 +42,6 @@ OBJC_COMMON_DEPS = [ "//mediapipe/tasks/ios/components/containers:MPPClassificationResult", "//mediapipe/tasks/ios/components/containers:MPPCategory", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", - "//mediapipe/calculators/core:flow_limiter_calculator", "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", @@ -173,7 +172,6 @@ apple_static_library( minimum_os_version = MPP_TASK_MINIMUM_OS_VERSION, platform_type = "ios", deps = [ - "//mediapipe/calculators/core:flow_limiter_calculator", "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", From 443418f6d5891039630f2ca32c0e3af0f521d1aa Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Mon, 8 May 2023 16:45:16 +0530 Subject: [PATCH 240/753] Updated formatting --- .../vision/object_detector/sources/MPPObjectDetectorOptions.h | 1 - 1 file changed, 1 deletion(-) diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h index c91e170c9..bf2e02326 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h @@ -52,7 +52,6 @@ NS_SWIFT_NAME(ObjectDetectorLiveStreamDelegate) * image was sent to the object detector. * @param error An optional error parameter populated when there is an error in performing object * detection on the input live stream image data. - * */ - (void)objectDetector:(MPPObjectDetector *)objectDetector didFinishDetectionWithResult:(nullable MPPObjectDetectionResult *)result From db732e2913c2f771aa8409475a6187488bd0e13d Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Mon, 8 May 2023 16:57:17 +0530 Subject: [PATCH 241/753] Updated formatting in MPPImageClassifierOptions --- .../image_classifier/sources/MPPImageClassifierOptions.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifierOptions.h b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifierOptions.h index fc76560c2..058c21aed 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifierOptions.h +++ b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifierOptions.h @@ -24,8 +24,8 @@ NS_ASSUME_NONNULL_BEGIN /** * This protocol defines an interface for the delegates of `MPPImageClassifier` object to receive - * results of asynchronous classification of images - * (i.e, when `runningMode = MPPRunningModeLiveStream`). + * results of asynchronous classification of images (i.e, when `runningMode = + * MPPRunningModeLiveStream`). * * The delegate of `MPPImageClassifier` must adopt `MPPImageClassifierLiveStreamDelegate` protocol. * The methods in this protocol are optional. @@ -48,7 +48,6 @@ NS_SWIFT_NAME(ImageClassifierLiveStreamDelegate) * image was sent to the image classifier. * @param error An optional error parameter populated when there is an error in performing image * classification on the input live stream image data. - * */ - (void)imageClassifier:(MPPImageClassifier *)imageClassifier didFinishClassificationWithResult:(nullable MPPImageClassifierResult *)result From 4a192a6d8770b577e4d0750d4e35b2a46d9bf272 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Mon, 8 May 2023 16:58:00 +0530 Subject: [PATCH 242/753] Updated formatting in MPPImageClassifier --- .../ios/vision/image_classifier/sources/MPPImageClassifier.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.h b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.h index 549fa9fa4..398236bbd 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.h +++ b/mediapipe/tasks/ios/vision/image_classifier/sources/MPPImageClassifier.h @@ -244,7 +244,7 @@ NS_SWIFT_NAME(ImageClassifier) * specified region of interest.. Rotation will be applied according to the `orientation` property * of the provided `MPPImage`. Only use this method when the `MPPImageClassifier` is created with * `MPPRunningModeLiveStream`. - * + * * The object which needs to be continuously notified of the available results of image * classification must confirm to `MPPImageClassifierLiveStreamDelegate` protocol and implement the * `imageClassifier:didFinishClassificationWithResult:timestampInMilliseconds:error:` delegate @@ -252,7 +252,7 @@ NS_SWIFT_NAME(ImageClassifier) * * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent * to the image classifier. The input timestamps must be monotonically increasing. - * + * * This method supports classification of RGBA images. If your `MPPImage` has a source type of * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer * must have one of the following pixel format types: From 0c75c76623cf5b914cdd177d1402faabf40c29bd Mon Sep 17 00:00:00 2001 From: Shuang Liu Date: Mon, 8 May 2023 10:22:05 -0700 Subject: [PATCH 243/753] Fix a typo. PiperOrigin-RevId: 530339315 --- mediapipe/calculators/core/flow_limiter_calculator.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/calculators/core/flow_limiter_calculator.cc b/mediapipe/calculators/core/flow_limiter_calculator.cc index 5b08f3af5..46e5bf6a3 100644 --- a/mediapipe/calculators/core/flow_limiter_calculator.cc +++ b/mediapipe/calculators/core/flow_limiter_calculator.cc @@ -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. // From e3c2f31ddff6e7659d5b67b70573eec375163f71 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Mon, 8 May 2023 10:29:35 -0700 Subject: [PATCH 244/753] Update WASM files for Alpha 14 PiperOrigin-RevId: 530341569 --- third_party/wasm_files.bzl | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/third_party/wasm_files.bzl b/third_party/wasm_files.bzl index b1b357f05..4c76e7bdb 100644 --- a/third_party/wasm_files.bzl +++ b/third_party/wasm_files.bzl @@ -12,72 +12,72 @@ def wasm_files(): http_file( name = "com_google_mediapipe_wasm_audio_wasm_internal_js", - sha256 = "1c555ecdb8faffca703d191626a6830e56fd0ab996d8837d7240d50098cc3109", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.js?generation=1682632113236604"], + sha256 = "b07bf0eda990b19c48f2b51c358bb281f40a7c3002f50f16986fe96f68103ac1", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.js?generation=1683564589395847"], ) http_file( name = "com_google_mediapipe_wasm_audio_wasm_internal_wasm", - sha256 = "aee8e7832b876a32a323f26b9f45002d2cc9d9e25db109ae360ec57fb3ed0c2e", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.wasm?generation=1682632115959200"], + sha256 = "725fa5d13fdce79beaccb287b24d79d32e7bfb40f2cc51ef7f26a8dd8dec993c", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.wasm?generation=1683564592604733"], ) http_file( name = "com_google_mediapipe_wasm_audio_wasm_nosimd_internal_js", - sha256 = "73df132f8d6ba62a406f120c514700e5a65d69a114e86de11dc9759024eedd7c", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.js?generation=1682632118022450"], + sha256 = "f2917690317ae381782c8f4fb17d40f7d0b8e340fb490a604a37959ecee637c8", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.js?generation=1683564595399509"], ) http_file( name = "com_google_mediapipe_wasm_audio_wasm_nosimd_internal_wasm", - sha256 = "7a4400c0b16f768161574b2ce512179e0afc4f8aa313232db7a4b7c572de2abb", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.wasm?generation=1682632120654892"], + sha256 = "908f6ce2420b5e88770b61b20b200cb3cd62a1c727cf0a134aa645351eaa1350", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.wasm?generation=1683564598602444"], ) http_file( name = "com_google_mediapipe_wasm_text_wasm_internal_js", - sha256 = "18ffadd94fa7844a106b2a9197f8258c39e601f99f01945c543fc0d879baad7f", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.js?generation=1682632123000744"], + sha256 = "64c4a3927e732b99473b072228130b922427b2aba16d64863579928df16a7946", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.js?generation=1683564601486513"], ) http_file( name = "com_google_mediapipe_wasm_text_wasm_internal_wasm", - sha256 = "96591ca0b64da9b565554384306663f1067b0c0a823d7e856fa58b28b659405a", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.wasm?generation=1682632125672531"], + sha256 = "c6e3027f4a7b1fd11d5ebbd8254f168636658e7a5d19a293e900f19497e48d5e", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.wasm?generation=1683564604687320"], ) http_file( name = "com_google_mediapipe_wasm_text_wasm_nosimd_internal_js", - sha256 = "668569cd80d6680c6e418ce42109d85151d6ec88ed06940206151585dba895df", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.js?generation=1682632128111024"], + sha256 = "af59aacaddc076ca9e4ea139d4f440b5b114576e72ab69e50f0f501e0e0c07e5", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.js?generation=1683564606939116"], ) http_file( name = "com_google_mediapipe_wasm_text_wasm_nosimd_internal_wasm", - sha256 = "f548cfe74a77aa609b988c212e7a60aa2b078194c3eeda0a3d5802165c2b5fe7", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.wasm?generation=1682632130623184"], + sha256 = "d313497c003b6e00670664463fbbd9f5a2388946fe3d132c2794dd87cb91beb0", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.wasm?generation=1683564609634068"], ) http_file( name = "com_google_mediapipe_wasm_vision_wasm_internal_js", - sha256 = "347d3ae5a947846431b6e8ea15966156b9cbf1a9ae800932954507b6c12c6ecf", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.js?generation=1682632132979491"], + sha256 = "efebf9d676d8828c31e7c0d9718c5c80de8a3de084e97aa3ea5472a5346c518e", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.js?generation=1683564611613681"], ) http_file( name = "com_google_mediapipe_wasm_vision_wasm_internal_wasm", - sha256 = "849092df0b599e00d074f4d8c2d7ef16912061298d27e5748ccf353b0f93b168", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.wasm?generation=1682632135762121"], + sha256 = "0431b3bacfcb26d91d800450216b305b9378f4e063d78c2e85a944aba432e0dd", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.wasm?generation=1683564614567083"], ) http_file( name = "com_google_mediapipe_wasm_vision_wasm_nosimd_internal_js", - sha256 = "7a130f5c20a320157d109a8aa767904df9717c24e77c99c4313a1716c3685e65", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.js?generation=1682632137850608"], + sha256 = "e51fa49f60493d7122d26e6fcb45d4031a3247a05d83b3f62e5155653a89d8f8", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.js?generation=1683564616879456"], ) http_file( name = "com_google_mediapipe_wasm_vision_wasm_nosimd_internal_wasm", - sha256 = "c45e706965e0572b41e1518e6243e6dee0d6834e0ac81f49370951d23e52e387", - urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.wasm?generation=1682632140714614"], + sha256 = "737830aab48e77ff5e6c1826f15801cfb2d68dbb622b3b39c3d7528334b73f94", + urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.wasm?generation=1683564619390853"], ) From ae8bedd352ebbe1dafb3ec1720c0c4f7ca341c53 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Mon, 8 May 2023 12:55:52 -0700 Subject: [PATCH 245/753] Inline constants for FaceLandmarksConnections PiperOrigin-RevId: 530384171 --- .../vision/face_landmarker/face_landmarker.ts | 39 +- .../face_landmarks_connections.ts | 1867 ++++++++--------- mediapipe/tasks/web/vision/index.ts | 4 +- 3 files changed, 972 insertions(+), 938 deletions(-) diff --git a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts index c0122da28..9dc8626c9 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts +++ b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts @@ -33,10 +33,10 @@ import {ImageSource, WasmModule} from '../../../../web/graph_runner/graph_runner import {FaceLandmarkerOptions} from './face_landmarker_options'; import {FaceLandmarkerResult} from './face_landmarker_result'; +import {FACE_LANDMARKS_CONTOURS, FACE_LANDMARKS_FACE_OVAL, FACE_LANDMARKS_LEFT_EYE, FACE_LANDMARKS_LEFT_EYEBROW, FACE_LANDMARKS_LEFT_IRIS, FACE_LANDMARKS_LIPS, FACE_LANDMARKS_RIGHT_EYE, FACE_LANDMARKS_RIGHT_EYEBROW, FACE_LANDMARKS_RIGHT_IRIS, FACE_LANDMARKS_TESSELATION} from './face_landmarks_connections'; export * from './face_landmarker_options'; export * from './face_landmarker_result'; -export * from './face_landmarks_connections'; export {ImageSource}; // The OSS JS API does not support the builder pattern. @@ -112,6 +112,43 @@ export class FaceLandmarker extends VisionTaskRunner { FaceLandmarker, wasmFileset, {baseOptions: {modelAssetPath}}); } + /** Landmark connections to draw the connection between a face's lips. */ + static FACE_LANDMARKS_LIPS = FACE_LANDMARKS_LIPS; + + /** Landmark connections to draw the connection between a face's left eye. */ + static FACE_LANDMARKS_LEFT_EYE = FACE_LANDMARKS_LEFT_EYE; + + /** + * Landmark connections to draw the connection between a face's left eyebrow. + */ + static FACE_LANDMARKS_LEFT_EYEBROW = FACE_LANDMARKS_LEFT_EYEBROW; + + /** Landmark connections to draw the connection between a face's left iris. */ + static FACE_LANDMARKS_LEFT_IRIS = FACE_LANDMARKS_LEFT_IRIS; + + /** Landmark connections to draw the connection between a face's right eye. */ + static FACE_LANDMARKS_RIGHT_EYE = FACE_LANDMARKS_RIGHT_EYE; + + /** + * Landmark connections to draw the connection between a face's right + * eyebrow. + */ + static FACE_LANDMARKS_RIGHT_EYEBROW = FACE_LANDMARKS_RIGHT_EYEBROW; + + /** + * Landmark connections to draw the connection between a face's right iris. + */ + static FACE_LANDMARKS_RIGHT_IRIS = FACE_LANDMARKS_RIGHT_IRIS; + + /** Landmark connections to draw the face's oval. */ + static FACE_LANDMARKS_FACE_OVAL = FACE_LANDMARKS_FACE_OVAL; + + /** Landmark connections to draw the face's contour. */ + static FACE_LANDMARKS_CONTOURS = FACE_LANDMARKS_CONTOURS; + + /** Landmark connections to draw the face's tesselation. */ + static FACE_LANDMARKS_TESSELATION = FACE_LANDMARKS_TESSELATION; + /** @hideconstructor */ constructor( wasmModule: WasmModule, diff --git a/mediapipe/tasks/web/vision/face_landmarker/face_landmarks_connections.ts b/mediapipe/tasks/web/vision/face_landmarker/face_landmarks_connections.ts index 9bd4b1b92..72c010cb4 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/face_landmarks_connections.ts +++ b/mediapipe/tasks/web/vision/face_landmarker/face_landmarks_connections.ts @@ -16,946 +16,945 @@ import {Connection} from '../../../../tasks/web/vision/core/types'; -// tslint:disable:class-as-namespace Using for easier import by 3P users +/** Landmarks for lips */ +export const FACE_LANDMARKS_LIPS: Connection[] = [ + {start: 61, end: 146}, {start: 146, end: 91}, {start: 91, end: 181}, + {start: 181, end: 84}, {start: 84, end: 17}, {start: 17, end: 314}, + {start: 314, end: 405}, {start: 405, end: 321}, {start: 321, end: 375}, + {start: 375, end: 291}, {start: 61, end: 185}, {start: 185, end: 40}, + {start: 40, end: 39}, {start: 39, end: 37}, {start: 37, end: 0}, + {start: 0, end: 267}, {start: 267, end: 269}, {start: 269, end: 270}, + {start: 270, end: 409}, {start: 409, end: 291}, {start: 78, end: 95}, + {start: 95, end: 88}, {start: 88, end: 178}, {start: 178, end: 87}, + {start: 87, end: 14}, {start: 14, end: 317}, {start: 317, end: 402}, + {start: 402, end: 318}, {start: 318, end: 324}, {start: 324, end: 308}, + {start: 78, end: 191}, {start: 191, end: 80}, {start: 80, end: 81}, + {start: 81, end: 82}, {start: 82, end: 13}, {start: 13, end: 312}, + {start: 312, end: 311}, {start: 311, end: 310}, {start: 310, end: 415}, + {start: 415, end: 308} +]; -/** - * A class containing the pairs of landmark indices to be rendered with - * connections. - */ -export class FaceLandmarksConnections { - static FACE_LANDMARKS_LIPS: Connection[] = [ - {start: 61, end: 146}, {start: 146, end: 91}, {start: 91, end: 181}, - {start: 181, end: 84}, {start: 84, end: 17}, {start: 17, end: 314}, - {start: 314, end: 405}, {start: 405, end: 321}, {start: 321, end: 375}, - {start: 375, end: 291}, {start: 61, end: 185}, {start: 185, end: 40}, - {start: 40, end: 39}, {start: 39, end: 37}, {start: 37, end: 0}, - {start: 0, end: 267}, {start: 267, end: 269}, {start: 269, end: 270}, - {start: 270, end: 409}, {start: 409, end: 291}, {start: 78, end: 95}, - {start: 95, end: 88}, {start: 88, end: 178}, {start: 178, end: 87}, - {start: 87, end: 14}, {start: 14, end: 317}, {start: 317, end: 402}, - {start: 402, end: 318}, {start: 318, end: 324}, {start: 324, end: 308}, - {start: 78, end: 191}, {start: 191, end: 80}, {start: 80, end: 81}, - {start: 81, end: 82}, {start: 82, end: 13}, {start: 13, end: 312}, - {start: 312, end: 311}, {start: 311, end: 310}, {start: 310, end: 415}, - {start: 415, end: 308} - ]; +/** Landmarks for left eye */ +export const FACE_LANDMARKS_LEFT_EYE: Connection[] = [ + {start: 263, end: 249}, {start: 249, end: 390}, {start: 390, end: 373}, + {start: 373, end: 374}, {start: 374, end: 380}, {start: 380, end: 381}, + {start: 381, end: 382}, {start: 382, end: 362}, {start: 263, end: 466}, + {start: 466, end: 388}, {start: 388, end: 387}, {start: 387, end: 386}, + {start: 386, end: 385}, {start: 385, end: 384}, {start: 384, end: 398}, + {start: 398, end: 362} +]; - static FACE_LANDMARKS_LEFT_EYE: Connection[] = [ - {start: 263, end: 249}, {start: 249, end: 390}, {start: 390, end: 373}, - {start: 373, end: 374}, {start: 374, end: 380}, {start: 380, end: 381}, - {start: 381, end: 382}, {start: 382, end: 362}, {start: 263, end: 466}, - {start: 466, end: 388}, {start: 388, end: 387}, {start: 387, end: 386}, - {start: 386, end: 385}, {start: 385, end: 384}, {start: 384, end: 398}, - {start: 398, end: 362} - ]; +/** Landmarks for left eyebrow */ +export const FACE_LANDMARKS_LEFT_EYEBROW: Connection[] = [ + {start: 276, end: 283}, {start: 283, end: 282}, {start: 282, end: 295}, + {start: 295, end: 285}, {start: 300, end: 293}, {start: 293, end: 334}, + {start: 334, end: 296}, {start: 296, end: 336} +]; - static FACE_LANDMARKS_LEFT_EYEBROW: Connection[] = [ - {start: 276, end: 283}, {start: 283, end: 282}, {start: 282, end: 295}, - {start: 295, end: 285}, {start: 300, end: 293}, {start: 293, end: 334}, - {start: 334, end: 296}, {start: 296, end: 336} - ]; +/** Landmarks for left iris */ +export const FACE_LANDMARKS_LEFT_IRIS: Connection[] = [ + {start: 474, end: 475}, {start: 475, end: 476}, {start: 476, end: 477}, + {start: 477, end: 474} +]; - static FACE_LANDMARKS_LEFT_IRIS: Connection[] = [ - {start: 474, end: 475}, {start: 475, end: 476}, {start: 476, end: 477}, - {start: 477, end: 474} - ]; +/** Landmarks for right eye */ +export const FACE_LANDMARKS_RIGHT_EYE: Connection[] = [ + {start: 33, end: 7}, {start: 7, end: 163}, {start: 163, end: 144}, + {start: 144, end: 145}, {start: 145, end: 153}, {start: 153, end: 154}, + {start: 154, end: 155}, {start: 155, end: 133}, {start: 33, end: 246}, + {start: 246, end: 161}, {start: 161, end: 160}, {start: 160, end: 159}, + {start: 159, end: 158}, {start: 158, end: 157}, {start: 157, end: 173}, + {start: 173, end: 133} +]; - static FACE_LANDMARKS_RIGHT_EYE: Connection[] = [ - {start: 33, end: 7}, {start: 7, end: 163}, {start: 163, end: 144}, - {start: 144, end: 145}, {start: 145, end: 153}, {start: 153, end: 154}, - {start: 154, end: 155}, {start: 155, end: 133}, {start: 33, end: 246}, - {start: 246, end: 161}, {start: 161, end: 160}, {start: 160, end: 159}, - {start: 159, end: 158}, {start: 158, end: 157}, {start: 157, end: 173}, - {start: 173, end: 133} - ]; +/** Landmarks for right eeyebrow */ +export const FACE_LANDMARKS_RIGHT_EYEBROW: Connection[] = [ + {start: 46, end: 53}, {start: 53, end: 52}, {start: 52, end: 65}, + {start: 65, end: 55}, {start: 70, end: 63}, {start: 63, end: 105}, + {start: 105, end: 66}, {start: 66, end: 107} +]; - static FACE_LANDMARKS_RIGHT_EYEBROW: Connection[] = [ - {start: 46, end: 53}, {start: 53, end: 52}, {start: 52, end: 65}, - {start: 65, end: 55}, {start: 70, end: 63}, {start: 63, end: 105}, - {start: 105, end: 66}, {start: 66, end: 107} - ]; +/** Landmarks for right iris */ +export const FACE_LANDMARKS_RIGHT_IRIS: Connection[] = [ + {start: 469, end: 470}, {start: 470, end: 471}, {start: 471, end: 472}, + {start: 472, end: 469} +]; - static FACE_LANDMARKS_RIGHT_IRIS: Connection[] = [ - {start: 469, end: 470}, {start: 470, end: 471}, {start: 471, end: 472}, - {start: 472, end: 469} - ]; +/** Landmarks for face oval */ +export const FACE_LANDMARKS_FACE_OVAL: Connection[] = [ + {start: 10, end: 338}, {start: 338, end: 297}, {start: 297, end: 332}, + {start: 332, end: 284}, {start: 284, end: 251}, {start: 251, end: 389}, + {start: 389, end: 356}, {start: 356, end: 454}, {start: 454, end: 323}, + {start: 323, end: 361}, {start: 361, end: 288}, {start: 288, end: 397}, + {start: 397, end: 365}, {start: 365, end: 379}, {start: 379, end: 378}, + {start: 378, end: 400}, {start: 400, end: 377}, {start: 377, end: 152}, + {start: 152, end: 148}, {start: 148, end: 176}, {start: 176, end: 149}, + {start: 149, end: 150}, {start: 150, end: 136}, {start: 136, end: 172}, + {start: 172, end: 58}, {start: 58, end: 132}, {start: 132, end: 93}, + {start: 93, end: 234}, {start: 234, end: 127}, {start: 127, end: 162}, + {start: 162, end: 21}, {start: 21, end: 54}, {start: 54, end: 103}, + {start: 103, end: 67}, {start: 67, end: 109}, {start: 109, end: 10} +]; - static FACE_LANDMARKS_FACE_OVAL: Connection[] = [ - {start: 10, end: 338}, {start: 338, end: 297}, {start: 297, end: 332}, - {start: 332, end: 284}, {start: 284, end: 251}, {start: 251, end: 389}, - {start: 389, end: 356}, {start: 356, end: 454}, {start: 454, end: 323}, - {start: 323, end: 361}, {start: 361, end: 288}, {start: 288, end: 397}, - {start: 397, end: 365}, {start: 365, end: 379}, {start: 379, end: 378}, - {start: 378, end: 400}, {start: 400, end: 377}, {start: 377, end: 152}, - {start: 152, end: 148}, {start: 148, end: 176}, {start: 176, end: 149}, - {start: 149, end: 150}, {start: 150, end: 136}, {start: 136, end: 172}, - {start: 172, end: 58}, {start: 58, end: 132}, {start: 132, end: 93}, - {start: 93, end: 234}, {start: 234, end: 127}, {start: 127, end: 162}, - {start: 162, end: 21}, {start: 21, end: 54}, {start: 54, end: 103}, - {start: 103, end: 67}, {start: 67, end: 109}, {start: 109, end: 10} - ]; +/** Landmarks for contours */ +export const FACE_LANDMARKS_CONTOURS: Connection[] = [ + ...FACE_LANDMARKS_LIPS, ...FACE_LANDMARKS_LEFT_EYE, + ...FACE_LANDMARKS_LEFT_EYEBROW, ...FACE_LANDMARKS_RIGHT_EYE, + ...FACE_LANDMARKS_RIGHT_EYEBROW, ...FACE_LANDMARKS_FACE_OVAL +]; - static FACE_LANDMARKS_CONTOURS: Connection[] = [ - ...FaceLandmarksConnections.FACE_LANDMARKS_LIPS, - ...FaceLandmarksConnections.FACE_LANDMARKS_LEFT_EYE, - ...FaceLandmarksConnections.FACE_LANDMARKS_LEFT_EYEBROW, - ...FaceLandmarksConnections.FACE_LANDMARKS_RIGHT_EYE, - ...FaceLandmarksConnections.FACE_LANDMARKS_RIGHT_EYEBROW, - ...FaceLandmarksConnections.FACE_LANDMARKS_FACE_OVAL - ]; - - static FACE_LANDMARKS_TESSELATION: Connection[] = [ - {start: 127, end: 34}, {start: 34, end: 139}, {start: 139, end: 127}, - {start: 11, end: 0}, {start: 0, end: 37}, {start: 37, end: 11}, - {start: 232, end: 231}, {start: 231, end: 120}, {start: 120, end: 232}, - {start: 72, end: 37}, {start: 37, end: 39}, {start: 39, end: 72}, - {start: 128, end: 121}, {start: 121, end: 47}, {start: 47, end: 128}, - {start: 232, end: 121}, {start: 121, end: 128}, {start: 128, end: 232}, - {start: 104, end: 69}, {start: 69, end: 67}, {start: 67, end: 104}, - {start: 175, end: 171}, {start: 171, end: 148}, {start: 148, end: 175}, - {start: 118, end: 50}, {start: 50, end: 101}, {start: 101, end: 118}, - {start: 73, end: 39}, {start: 39, end: 40}, {start: 40, end: 73}, - {start: 9, end: 151}, {start: 151, end: 108}, {start: 108, end: 9}, - {start: 48, end: 115}, {start: 115, end: 131}, {start: 131, end: 48}, - {start: 194, end: 204}, {start: 204, end: 211}, {start: 211, end: 194}, - {start: 74, end: 40}, {start: 40, end: 185}, {start: 185, end: 74}, - {start: 80, end: 42}, {start: 42, end: 183}, {start: 183, end: 80}, - {start: 40, end: 92}, {start: 92, end: 186}, {start: 186, end: 40}, - {start: 230, end: 229}, {start: 229, end: 118}, {start: 118, end: 230}, - {start: 202, end: 212}, {start: 212, end: 214}, {start: 214, end: 202}, - {start: 83, end: 18}, {start: 18, end: 17}, {start: 17, end: 83}, - {start: 76, end: 61}, {start: 61, end: 146}, {start: 146, end: 76}, - {start: 160, end: 29}, {start: 29, end: 30}, {start: 30, end: 160}, - {start: 56, end: 157}, {start: 157, end: 173}, {start: 173, end: 56}, - {start: 106, end: 204}, {start: 204, end: 194}, {start: 194, end: 106}, - {start: 135, end: 214}, {start: 214, end: 192}, {start: 192, end: 135}, - {start: 203, end: 165}, {start: 165, end: 98}, {start: 98, end: 203}, - {start: 21, end: 71}, {start: 71, end: 68}, {start: 68, end: 21}, - {start: 51, end: 45}, {start: 45, end: 4}, {start: 4, end: 51}, - {start: 144, end: 24}, {start: 24, end: 23}, {start: 23, end: 144}, - {start: 77, end: 146}, {start: 146, end: 91}, {start: 91, end: 77}, - {start: 205, end: 50}, {start: 50, end: 187}, {start: 187, end: 205}, - {start: 201, end: 200}, {start: 200, end: 18}, {start: 18, end: 201}, - {start: 91, end: 106}, {start: 106, end: 182}, {start: 182, end: 91}, - {start: 90, end: 91}, {start: 91, end: 181}, {start: 181, end: 90}, - {start: 85, end: 84}, {start: 84, end: 17}, {start: 17, end: 85}, - {start: 206, end: 203}, {start: 203, end: 36}, {start: 36, end: 206}, - {start: 148, end: 171}, {start: 171, end: 140}, {start: 140, end: 148}, - {start: 92, end: 40}, {start: 40, end: 39}, {start: 39, end: 92}, - {start: 193, end: 189}, {start: 189, end: 244}, {start: 244, end: 193}, - {start: 159, end: 158}, {start: 158, end: 28}, {start: 28, end: 159}, - {start: 247, end: 246}, {start: 246, end: 161}, {start: 161, end: 247}, - {start: 236, end: 3}, {start: 3, end: 196}, {start: 196, end: 236}, - {start: 54, end: 68}, {start: 68, end: 104}, {start: 104, end: 54}, - {start: 193, end: 168}, {start: 168, end: 8}, {start: 8, end: 193}, - {start: 117, end: 228}, {start: 228, end: 31}, {start: 31, end: 117}, - {start: 189, end: 193}, {start: 193, end: 55}, {start: 55, end: 189}, - {start: 98, end: 97}, {start: 97, end: 99}, {start: 99, end: 98}, - {start: 126, end: 47}, {start: 47, end: 100}, {start: 100, end: 126}, - {start: 166, end: 79}, {start: 79, end: 218}, {start: 218, end: 166}, - {start: 155, end: 154}, {start: 154, end: 26}, {start: 26, end: 155}, - {start: 209, end: 49}, {start: 49, end: 131}, {start: 131, end: 209}, - {start: 135, end: 136}, {start: 136, end: 150}, {start: 150, end: 135}, - {start: 47, end: 126}, {start: 126, end: 217}, {start: 217, end: 47}, - {start: 223, end: 52}, {start: 52, end: 53}, {start: 53, end: 223}, - {start: 45, end: 51}, {start: 51, end: 134}, {start: 134, end: 45}, - {start: 211, end: 170}, {start: 170, end: 140}, {start: 140, end: 211}, - {start: 67, end: 69}, {start: 69, end: 108}, {start: 108, end: 67}, - {start: 43, end: 106}, {start: 106, end: 91}, {start: 91, end: 43}, - {start: 230, end: 119}, {start: 119, end: 120}, {start: 120, end: 230}, - {start: 226, end: 130}, {start: 130, end: 247}, {start: 247, end: 226}, - {start: 63, end: 53}, {start: 53, end: 52}, {start: 52, end: 63}, - {start: 238, end: 20}, {start: 20, end: 242}, {start: 242, end: 238}, - {start: 46, end: 70}, {start: 70, end: 156}, {start: 156, end: 46}, - {start: 78, end: 62}, {start: 62, end: 96}, {start: 96, end: 78}, - {start: 46, end: 53}, {start: 53, end: 63}, {start: 63, end: 46}, - {start: 143, end: 34}, {start: 34, end: 227}, {start: 227, end: 143}, - {start: 123, end: 117}, {start: 117, end: 111}, {start: 111, end: 123}, - {start: 44, end: 125}, {start: 125, end: 19}, {start: 19, end: 44}, - {start: 236, end: 134}, {start: 134, end: 51}, {start: 51, end: 236}, - {start: 216, end: 206}, {start: 206, end: 205}, {start: 205, end: 216}, - {start: 154, end: 153}, {start: 153, end: 22}, {start: 22, end: 154}, - {start: 39, end: 37}, {start: 37, end: 167}, {start: 167, end: 39}, - {start: 200, end: 201}, {start: 201, end: 208}, {start: 208, end: 200}, - {start: 36, end: 142}, {start: 142, end: 100}, {start: 100, end: 36}, - {start: 57, end: 212}, {start: 212, end: 202}, {start: 202, end: 57}, - {start: 20, end: 60}, {start: 60, end: 99}, {start: 99, end: 20}, - {start: 28, end: 158}, {start: 158, end: 157}, {start: 157, end: 28}, - {start: 35, end: 226}, {start: 226, end: 113}, {start: 113, end: 35}, - {start: 160, end: 159}, {start: 159, end: 27}, {start: 27, end: 160}, - {start: 204, end: 202}, {start: 202, end: 210}, {start: 210, end: 204}, - {start: 113, end: 225}, {start: 225, end: 46}, {start: 46, end: 113}, - {start: 43, end: 202}, {start: 202, end: 204}, {start: 204, end: 43}, - {start: 62, end: 76}, {start: 76, end: 77}, {start: 77, end: 62}, - {start: 137, end: 123}, {start: 123, end: 116}, {start: 116, end: 137}, - {start: 41, end: 38}, {start: 38, end: 72}, {start: 72, end: 41}, - {start: 203, end: 129}, {start: 129, end: 142}, {start: 142, end: 203}, - {start: 64, end: 98}, {start: 98, end: 240}, {start: 240, end: 64}, - {start: 49, end: 102}, {start: 102, end: 64}, {start: 64, end: 49}, - {start: 41, end: 73}, {start: 73, end: 74}, {start: 74, end: 41}, - {start: 212, end: 216}, {start: 216, end: 207}, {start: 207, end: 212}, - {start: 42, end: 74}, {start: 74, end: 184}, {start: 184, end: 42}, - {start: 169, end: 170}, {start: 170, end: 211}, {start: 211, end: 169}, - {start: 170, end: 149}, {start: 149, end: 176}, {start: 176, end: 170}, - {start: 105, end: 66}, {start: 66, end: 69}, {start: 69, end: 105}, - {start: 122, end: 6}, {start: 6, end: 168}, {start: 168, end: 122}, - {start: 123, end: 147}, {start: 147, end: 187}, {start: 187, end: 123}, - {start: 96, end: 77}, {start: 77, end: 90}, {start: 90, end: 96}, - {start: 65, end: 55}, {start: 55, end: 107}, {start: 107, end: 65}, - {start: 89, end: 90}, {start: 90, end: 180}, {start: 180, end: 89}, - {start: 101, end: 100}, {start: 100, end: 120}, {start: 120, end: 101}, - {start: 63, end: 105}, {start: 105, end: 104}, {start: 104, end: 63}, - {start: 93, end: 137}, {start: 137, end: 227}, {start: 227, end: 93}, - {start: 15, end: 86}, {start: 86, end: 85}, {start: 85, end: 15}, - {start: 129, end: 102}, {start: 102, end: 49}, {start: 49, end: 129}, - {start: 14, end: 87}, {start: 87, end: 86}, {start: 86, end: 14}, - {start: 55, end: 8}, {start: 8, end: 9}, {start: 9, end: 55}, - {start: 100, end: 47}, {start: 47, end: 121}, {start: 121, end: 100}, - {start: 145, end: 23}, {start: 23, end: 22}, {start: 22, end: 145}, - {start: 88, end: 89}, {start: 89, end: 179}, {start: 179, end: 88}, - {start: 6, end: 122}, {start: 122, end: 196}, {start: 196, end: 6}, - {start: 88, end: 95}, {start: 95, end: 96}, {start: 96, end: 88}, - {start: 138, end: 172}, {start: 172, end: 136}, {start: 136, end: 138}, - {start: 215, end: 58}, {start: 58, end: 172}, {start: 172, end: 215}, - {start: 115, end: 48}, {start: 48, end: 219}, {start: 219, end: 115}, - {start: 42, end: 80}, {start: 80, end: 81}, {start: 81, end: 42}, - {start: 195, end: 3}, {start: 3, end: 51}, {start: 51, end: 195}, - {start: 43, end: 146}, {start: 146, end: 61}, {start: 61, end: 43}, - {start: 171, end: 175}, {start: 175, end: 199}, {start: 199, end: 171}, - {start: 81, end: 82}, {start: 82, end: 38}, {start: 38, end: 81}, - {start: 53, end: 46}, {start: 46, end: 225}, {start: 225, end: 53}, - {start: 144, end: 163}, {start: 163, end: 110}, {start: 110, end: 144}, - {start: 52, end: 65}, {start: 65, end: 66}, {start: 66, end: 52}, - {start: 229, end: 228}, {start: 228, end: 117}, {start: 117, end: 229}, - {start: 34, end: 127}, {start: 127, end: 234}, {start: 234, end: 34}, - {start: 107, end: 108}, {start: 108, end: 69}, {start: 69, end: 107}, - {start: 109, end: 108}, {start: 108, end: 151}, {start: 151, end: 109}, - {start: 48, end: 64}, {start: 64, end: 235}, {start: 235, end: 48}, - {start: 62, end: 78}, {start: 78, end: 191}, {start: 191, end: 62}, - {start: 129, end: 209}, {start: 209, end: 126}, {start: 126, end: 129}, - {start: 111, end: 35}, {start: 35, end: 143}, {start: 143, end: 111}, - {start: 117, end: 123}, {start: 123, end: 50}, {start: 50, end: 117}, - {start: 222, end: 65}, {start: 65, end: 52}, {start: 52, end: 222}, - {start: 19, end: 125}, {start: 125, end: 141}, {start: 141, end: 19}, - {start: 221, end: 55}, {start: 55, end: 65}, {start: 65, end: 221}, - {start: 3, end: 195}, {start: 195, end: 197}, {start: 197, end: 3}, - {start: 25, end: 7}, {start: 7, end: 33}, {start: 33, end: 25}, - {start: 220, end: 237}, {start: 237, end: 44}, {start: 44, end: 220}, - {start: 70, end: 71}, {start: 71, end: 139}, {start: 139, end: 70}, - {start: 122, end: 193}, {start: 193, end: 245}, {start: 245, end: 122}, - {start: 247, end: 130}, {start: 130, end: 33}, {start: 33, end: 247}, - {start: 71, end: 21}, {start: 21, end: 162}, {start: 162, end: 71}, - {start: 170, end: 169}, {start: 169, end: 150}, {start: 150, end: 170}, - {start: 188, end: 174}, {start: 174, end: 196}, {start: 196, end: 188}, - {start: 216, end: 186}, {start: 186, end: 92}, {start: 92, end: 216}, - {start: 2, end: 97}, {start: 97, end: 167}, {start: 167, end: 2}, - {start: 141, end: 125}, {start: 125, end: 241}, {start: 241, end: 141}, - {start: 164, end: 167}, {start: 167, end: 37}, {start: 37, end: 164}, - {start: 72, end: 38}, {start: 38, end: 12}, {start: 12, end: 72}, - {start: 38, end: 82}, {start: 82, end: 13}, {start: 13, end: 38}, - {start: 63, end: 68}, {start: 68, end: 71}, {start: 71, end: 63}, - {start: 226, end: 35}, {start: 35, end: 111}, {start: 111, end: 226}, - {start: 101, end: 50}, {start: 50, end: 205}, {start: 205, end: 101}, - {start: 206, end: 92}, {start: 92, end: 165}, {start: 165, end: 206}, - {start: 209, end: 198}, {start: 198, end: 217}, {start: 217, end: 209}, - {start: 165, end: 167}, {start: 167, end: 97}, {start: 97, end: 165}, - {start: 220, end: 115}, {start: 115, end: 218}, {start: 218, end: 220}, - {start: 133, end: 112}, {start: 112, end: 243}, {start: 243, end: 133}, - {start: 239, end: 238}, {start: 238, end: 241}, {start: 241, end: 239}, - {start: 214, end: 135}, {start: 135, end: 169}, {start: 169, end: 214}, - {start: 190, end: 173}, {start: 173, end: 133}, {start: 133, end: 190}, - {start: 171, end: 208}, {start: 208, end: 32}, {start: 32, end: 171}, - {start: 125, end: 44}, {start: 44, end: 237}, {start: 237, end: 125}, - {start: 86, end: 87}, {start: 87, end: 178}, {start: 178, end: 86}, - {start: 85, end: 86}, {start: 86, end: 179}, {start: 179, end: 85}, - {start: 84, end: 85}, {start: 85, end: 180}, {start: 180, end: 84}, - {start: 83, end: 84}, {start: 84, end: 181}, {start: 181, end: 83}, - {start: 201, end: 83}, {start: 83, end: 182}, {start: 182, end: 201}, - {start: 137, end: 93}, {start: 93, end: 132}, {start: 132, end: 137}, - {start: 76, end: 62}, {start: 62, end: 183}, {start: 183, end: 76}, - {start: 61, end: 76}, {start: 76, end: 184}, {start: 184, end: 61}, - {start: 57, end: 61}, {start: 61, end: 185}, {start: 185, end: 57}, - {start: 212, end: 57}, {start: 57, end: 186}, {start: 186, end: 212}, - {start: 214, end: 207}, {start: 207, end: 187}, {start: 187, end: 214}, - {start: 34, end: 143}, {start: 143, end: 156}, {start: 156, end: 34}, - {start: 79, end: 239}, {start: 239, end: 237}, {start: 237, end: 79}, - {start: 123, end: 137}, {start: 137, end: 177}, {start: 177, end: 123}, - {start: 44, end: 1}, {start: 1, end: 4}, {start: 4, end: 44}, - {start: 201, end: 194}, {start: 194, end: 32}, {start: 32, end: 201}, - {start: 64, end: 102}, {start: 102, end: 129}, {start: 129, end: 64}, - {start: 213, end: 215}, {start: 215, end: 138}, {start: 138, end: 213}, - {start: 59, end: 166}, {start: 166, end: 219}, {start: 219, end: 59}, - {start: 242, end: 99}, {start: 99, end: 97}, {start: 97, end: 242}, - {start: 2, end: 94}, {start: 94, end: 141}, {start: 141, end: 2}, - {start: 75, end: 59}, {start: 59, end: 235}, {start: 235, end: 75}, - {start: 24, end: 110}, {start: 110, end: 228}, {start: 228, end: 24}, - {start: 25, end: 130}, {start: 130, end: 226}, {start: 226, end: 25}, - {start: 23, end: 24}, {start: 24, end: 229}, {start: 229, end: 23}, - {start: 22, end: 23}, {start: 23, end: 230}, {start: 230, end: 22}, - {start: 26, end: 22}, {start: 22, end: 231}, {start: 231, end: 26}, - {start: 112, end: 26}, {start: 26, end: 232}, {start: 232, end: 112}, - {start: 189, end: 190}, {start: 190, end: 243}, {start: 243, end: 189}, - {start: 221, end: 56}, {start: 56, end: 190}, {start: 190, end: 221}, - {start: 28, end: 56}, {start: 56, end: 221}, {start: 221, end: 28}, - {start: 27, end: 28}, {start: 28, end: 222}, {start: 222, end: 27}, - {start: 29, end: 27}, {start: 27, end: 223}, {start: 223, end: 29}, - {start: 30, end: 29}, {start: 29, end: 224}, {start: 224, end: 30}, - {start: 247, end: 30}, {start: 30, end: 225}, {start: 225, end: 247}, - {start: 238, end: 79}, {start: 79, end: 20}, {start: 20, end: 238}, - {start: 166, end: 59}, {start: 59, end: 75}, {start: 75, end: 166}, - {start: 60, end: 75}, {start: 75, end: 240}, {start: 240, end: 60}, - {start: 147, end: 177}, {start: 177, end: 215}, {start: 215, end: 147}, - {start: 20, end: 79}, {start: 79, end: 166}, {start: 166, end: 20}, - {start: 187, end: 147}, {start: 147, end: 213}, {start: 213, end: 187}, - {start: 112, end: 233}, {start: 233, end: 244}, {start: 244, end: 112}, - {start: 233, end: 128}, {start: 128, end: 245}, {start: 245, end: 233}, - {start: 128, end: 114}, {start: 114, end: 188}, {start: 188, end: 128}, - {start: 114, end: 217}, {start: 217, end: 174}, {start: 174, end: 114}, - {start: 131, end: 115}, {start: 115, end: 220}, {start: 220, end: 131}, - {start: 217, end: 198}, {start: 198, end: 236}, {start: 236, end: 217}, - {start: 198, end: 131}, {start: 131, end: 134}, {start: 134, end: 198}, - {start: 177, end: 132}, {start: 132, end: 58}, {start: 58, end: 177}, - {start: 143, end: 35}, {start: 35, end: 124}, {start: 124, end: 143}, - {start: 110, end: 163}, {start: 163, end: 7}, {start: 7, end: 110}, - {start: 228, end: 110}, {start: 110, end: 25}, {start: 25, end: 228}, - {start: 356, end: 389}, {start: 389, end: 368}, {start: 368, end: 356}, - {start: 11, end: 302}, {start: 302, end: 267}, {start: 267, end: 11}, - {start: 452, end: 350}, {start: 350, end: 349}, {start: 349, end: 452}, - {start: 302, end: 303}, {start: 303, end: 269}, {start: 269, end: 302}, - {start: 357, end: 343}, {start: 343, end: 277}, {start: 277, end: 357}, - {start: 452, end: 453}, {start: 453, end: 357}, {start: 357, end: 452}, - {start: 333, end: 332}, {start: 332, end: 297}, {start: 297, end: 333}, - {start: 175, end: 152}, {start: 152, end: 377}, {start: 377, end: 175}, - {start: 347, end: 348}, {start: 348, end: 330}, {start: 330, end: 347}, - {start: 303, end: 304}, {start: 304, end: 270}, {start: 270, end: 303}, - {start: 9, end: 336}, {start: 336, end: 337}, {start: 337, end: 9}, - {start: 278, end: 279}, {start: 279, end: 360}, {start: 360, end: 278}, - {start: 418, end: 262}, {start: 262, end: 431}, {start: 431, end: 418}, - {start: 304, end: 408}, {start: 408, end: 409}, {start: 409, end: 304}, - {start: 310, end: 415}, {start: 415, end: 407}, {start: 407, end: 310}, - {start: 270, end: 409}, {start: 409, end: 410}, {start: 410, end: 270}, - {start: 450, end: 348}, {start: 348, end: 347}, {start: 347, end: 450}, - {start: 422, end: 430}, {start: 430, end: 434}, {start: 434, end: 422}, - {start: 313, end: 314}, {start: 314, end: 17}, {start: 17, end: 313}, - {start: 306, end: 307}, {start: 307, end: 375}, {start: 375, end: 306}, - {start: 387, end: 388}, {start: 388, end: 260}, {start: 260, end: 387}, - {start: 286, end: 414}, {start: 414, end: 398}, {start: 398, end: 286}, - {start: 335, end: 406}, {start: 406, end: 418}, {start: 418, end: 335}, - {start: 364, end: 367}, {start: 367, end: 416}, {start: 416, end: 364}, - {start: 423, end: 358}, {start: 358, end: 327}, {start: 327, end: 423}, - {start: 251, end: 284}, {start: 284, end: 298}, {start: 298, end: 251}, - {start: 281, end: 5}, {start: 5, end: 4}, {start: 4, end: 281}, - {start: 373, end: 374}, {start: 374, end: 253}, {start: 253, end: 373}, - {start: 307, end: 320}, {start: 320, end: 321}, {start: 321, end: 307}, - {start: 425, end: 427}, {start: 427, end: 411}, {start: 411, end: 425}, - {start: 421, end: 313}, {start: 313, end: 18}, {start: 18, end: 421}, - {start: 321, end: 405}, {start: 405, end: 406}, {start: 406, end: 321}, - {start: 320, end: 404}, {start: 404, end: 405}, {start: 405, end: 320}, - {start: 315, end: 16}, {start: 16, end: 17}, {start: 17, end: 315}, - {start: 426, end: 425}, {start: 425, end: 266}, {start: 266, end: 426}, - {start: 377, end: 400}, {start: 400, end: 369}, {start: 369, end: 377}, - {start: 322, end: 391}, {start: 391, end: 269}, {start: 269, end: 322}, - {start: 417, end: 465}, {start: 465, end: 464}, {start: 464, end: 417}, - {start: 386, end: 257}, {start: 257, end: 258}, {start: 258, end: 386}, - {start: 466, end: 260}, {start: 260, end: 388}, {start: 388, end: 466}, - {start: 456, end: 399}, {start: 399, end: 419}, {start: 419, end: 456}, - {start: 284, end: 332}, {start: 332, end: 333}, {start: 333, end: 284}, - {start: 417, end: 285}, {start: 285, end: 8}, {start: 8, end: 417}, - {start: 346, end: 340}, {start: 340, end: 261}, {start: 261, end: 346}, - {start: 413, end: 441}, {start: 441, end: 285}, {start: 285, end: 413}, - {start: 327, end: 460}, {start: 460, end: 328}, {start: 328, end: 327}, - {start: 355, end: 371}, {start: 371, end: 329}, {start: 329, end: 355}, - {start: 392, end: 439}, {start: 439, end: 438}, {start: 438, end: 392}, - {start: 382, end: 341}, {start: 341, end: 256}, {start: 256, end: 382}, - {start: 429, end: 420}, {start: 420, end: 360}, {start: 360, end: 429}, - {start: 364, end: 394}, {start: 394, end: 379}, {start: 379, end: 364}, - {start: 277, end: 343}, {start: 343, end: 437}, {start: 437, end: 277}, - {start: 443, end: 444}, {start: 444, end: 283}, {start: 283, end: 443}, - {start: 275, end: 440}, {start: 440, end: 363}, {start: 363, end: 275}, - {start: 431, end: 262}, {start: 262, end: 369}, {start: 369, end: 431}, - {start: 297, end: 338}, {start: 338, end: 337}, {start: 337, end: 297}, - {start: 273, end: 375}, {start: 375, end: 321}, {start: 321, end: 273}, - {start: 450, end: 451}, {start: 451, end: 349}, {start: 349, end: 450}, - {start: 446, end: 342}, {start: 342, end: 467}, {start: 467, end: 446}, - {start: 293, end: 334}, {start: 334, end: 282}, {start: 282, end: 293}, - {start: 458, end: 461}, {start: 461, end: 462}, {start: 462, end: 458}, - {start: 276, end: 353}, {start: 353, end: 383}, {start: 383, end: 276}, - {start: 308, end: 324}, {start: 324, end: 325}, {start: 325, end: 308}, - {start: 276, end: 300}, {start: 300, end: 293}, {start: 293, end: 276}, - {start: 372, end: 345}, {start: 345, end: 447}, {start: 447, end: 372}, - {start: 352, end: 345}, {start: 345, end: 340}, {start: 340, end: 352}, - {start: 274, end: 1}, {start: 1, end: 19}, {start: 19, end: 274}, - {start: 456, end: 248}, {start: 248, end: 281}, {start: 281, end: 456}, - {start: 436, end: 427}, {start: 427, end: 425}, {start: 425, end: 436}, - {start: 381, end: 256}, {start: 256, end: 252}, {start: 252, end: 381}, - {start: 269, end: 391}, {start: 391, end: 393}, {start: 393, end: 269}, - {start: 200, end: 199}, {start: 199, end: 428}, {start: 428, end: 200}, - {start: 266, end: 330}, {start: 330, end: 329}, {start: 329, end: 266}, - {start: 287, end: 273}, {start: 273, end: 422}, {start: 422, end: 287}, - {start: 250, end: 462}, {start: 462, end: 328}, {start: 328, end: 250}, - {start: 258, end: 286}, {start: 286, end: 384}, {start: 384, end: 258}, - {start: 265, end: 353}, {start: 353, end: 342}, {start: 342, end: 265}, - {start: 387, end: 259}, {start: 259, end: 257}, {start: 257, end: 387}, - {start: 424, end: 431}, {start: 431, end: 430}, {start: 430, end: 424}, - {start: 342, end: 353}, {start: 353, end: 276}, {start: 276, end: 342}, - {start: 273, end: 335}, {start: 335, end: 424}, {start: 424, end: 273}, - {start: 292, end: 325}, {start: 325, end: 307}, {start: 307, end: 292}, - {start: 366, end: 447}, {start: 447, end: 345}, {start: 345, end: 366}, - {start: 271, end: 303}, {start: 303, end: 302}, {start: 302, end: 271}, - {start: 423, end: 266}, {start: 266, end: 371}, {start: 371, end: 423}, - {start: 294, end: 455}, {start: 455, end: 460}, {start: 460, end: 294}, - {start: 279, end: 278}, {start: 278, end: 294}, {start: 294, end: 279}, - {start: 271, end: 272}, {start: 272, end: 304}, {start: 304, end: 271}, - {start: 432, end: 434}, {start: 434, end: 427}, {start: 427, end: 432}, - {start: 272, end: 407}, {start: 407, end: 408}, {start: 408, end: 272}, - {start: 394, end: 430}, {start: 430, end: 431}, {start: 431, end: 394}, - {start: 395, end: 369}, {start: 369, end: 400}, {start: 400, end: 395}, - {start: 334, end: 333}, {start: 333, end: 299}, {start: 299, end: 334}, - {start: 351, end: 417}, {start: 417, end: 168}, {start: 168, end: 351}, - {start: 352, end: 280}, {start: 280, end: 411}, {start: 411, end: 352}, - {start: 325, end: 319}, {start: 319, end: 320}, {start: 320, end: 325}, - {start: 295, end: 296}, {start: 296, end: 336}, {start: 336, end: 295}, - {start: 319, end: 403}, {start: 403, end: 404}, {start: 404, end: 319}, - {start: 330, end: 348}, {start: 348, end: 349}, {start: 349, end: 330}, - {start: 293, end: 298}, {start: 298, end: 333}, {start: 333, end: 293}, - {start: 323, end: 454}, {start: 454, end: 447}, {start: 447, end: 323}, - {start: 15, end: 16}, {start: 16, end: 315}, {start: 315, end: 15}, - {start: 358, end: 429}, {start: 429, end: 279}, {start: 279, end: 358}, - {start: 14, end: 15}, {start: 15, end: 316}, {start: 316, end: 14}, - {start: 285, end: 336}, {start: 336, end: 9}, {start: 9, end: 285}, - {start: 329, end: 349}, {start: 349, end: 350}, {start: 350, end: 329}, - {start: 374, end: 380}, {start: 380, end: 252}, {start: 252, end: 374}, - {start: 318, end: 402}, {start: 402, end: 403}, {start: 403, end: 318}, - {start: 6, end: 197}, {start: 197, end: 419}, {start: 419, end: 6}, - {start: 318, end: 319}, {start: 319, end: 325}, {start: 325, end: 318}, - {start: 367, end: 364}, {start: 364, end: 365}, {start: 365, end: 367}, - {start: 435, end: 367}, {start: 367, end: 397}, {start: 397, end: 435}, - {start: 344, end: 438}, {start: 438, end: 439}, {start: 439, end: 344}, - {start: 272, end: 271}, {start: 271, end: 311}, {start: 311, end: 272}, - {start: 195, end: 5}, {start: 5, end: 281}, {start: 281, end: 195}, - {start: 273, end: 287}, {start: 287, end: 291}, {start: 291, end: 273}, - {start: 396, end: 428}, {start: 428, end: 199}, {start: 199, end: 396}, - {start: 311, end: 271}, {start: 271, end: 268}, {start: 268, end: 311}, - {start: 283, end: 444}, {start: 444, end: 445}, {start: 445, end: 283}, - {start: 373, end: 254}, {start: 254, end: 339}, {start: 339, end: 373}, - {start: 282, end: 334}, {start: 334, end: 296}, {start: 296, end: 282}, - {start: 449, end: 347}, {start: 347, end: 346}, {start: 346, end: 449}, - {start: 264, end: 447}, {start: 447, end: 454}, {start: 454, end: 264}, - {start: 336, end: 296}, {start: 296, end: 299}, {start: 299, end: 336}, - {start: 338, end: 10}, {start: 10, end: 151}, {start: 151, end: 338}, - {start: 278, end: 439}, {start: 439, end: 455}, {start: 455, end: 278}, - {start: 292, end: 407}, {start: 407, end: 415}, {start: 415, end: 292}, - {start: 358, end: 371}, {start: 371, end: 355}, {start: 355, end: 358}, - {start: 340, end: 345}, {start: 345, end: 372}, {start: 372, end: 340}, - {start: 346, end: 347}, {start: 347, end: 280}, {start: 280, end: 346}, - {start: 442, end: 443}, {start: 443, end: 282}, {start: 282, end: 442}, - {start: 19, end: 94}, {start: 94, end: 370}, {start: 370, end: 19}, - {start: 441, end: 442}, {start: 442, end: 295}, {start: 295, end: 441}, - {start: 248, end: 419}, {start: 419, end: 197}, {start: 197, end: 248}, - {start: 263, end: 255}, {start: 255, end: 359}, {start: 359, end: 263}, - {start: 440, end: 275}, {start: 275, end: 274}, {start: 274, end: 440}, - {start: 300, end: 383}, {start: 383, end: 368}, {start: 368, end: 300}, - {start: 351, end: 412}, {start: 412, end: 465}, {start: 465, end: 351}, - {start: 263, end: 467}, {start: 467, end: 466}, {start: 466, end: 263}, - {start: 301, end: 368}, {start: 368, end: 389}, {start: 389, end: 301}, - {start: 395, end: 378}, {start: 378, end: 379}, {start: 379, end: 395}, - {start: 412, end: 351}, {start: 351, end: 419}, {start: 419, end: 412}, - {start: 436, end: 426}, {start: 426, end: 322}, {start: 322, end: 436}, - {start: 2, end: 164}, {start: 164, end: 393}, {start: 393, end: 2}, - {start: 370, end: 462}, {start: 462, end: 461}, {start: 461, end: 370}, - {start: 164, end: 0}, {start: 0, end: 267}, {start: 267, end: 164}, - {start: 302, end: 11}, {start: 11, end: 12}, {start: 12, end: 302}, - {start: 268, end: 12}, {start: 12, end: 13}, {start: 13, end: 268}, - {start: 293, end: 300}, {start: 300, end: 301}, {start: 301, end: 293}, - {start: 446, end: 261}, {start: 261, end: 340}, {start: 340, end: 446}, - {start: 330, end: 266}, {start: 266, end: 425}, {start: 425, end: 330}, - {start: 426, end: 423}, {start: 423, end: 391}, {start: 391, end: 426}, - {start: 429, end: 355}, {start: 355, end: 437}, {start: 437, end: 429}, - {start: 391, end: 327}, {start: 327, end: 326}, {start: 326, end: 391}, - {start: 440, end: 457}, {start: 457, end: 438}, {start: 438, end: 440}, - {start: 341, end: 382}, {start: 382, end: 362}, {start: 362, end: 341}, - {start: 459, end: 457}, {start: 457, end: 461}, {start: 461, end: 459}, - {start: 434, end: 430}, {start: 430, end: 394}, {start: 394, end: 434}, - {start: 414, end: 463}, {start: 463, end: 362}, {start: 362, end: 414}, - {start: 396, end: 369}, {start: 369, end: 262}, {start: 262, end: 396}, - {start: 354, end: 461}, {start: 461, end: 457}, {start: 457, end: 354}, - {start: 316, end: 403}, {start: 403, end: 402}, {start: 402, end: 316}, - {start: 315, end: 404}, {start: 404, end: 403}, {start: 403, end: 315}, - {start: 314, end: 405}, {start: 405, end: 404}, {start: 404, end: 314}, - {start: 313, end: 406}, {start: 406, end: 405}, {start: 405, end: 313}, - {start: 421, end: 418}, {start: 418, end: 406}, {start: 406, end: 421}, - {start: 366, end: 401}, {start: 401, end: 361}, {start: 361, end: 366}, - {start: 306, end: 408}, {start: 408, end: 407}, {start: 407, end: 306}, - {start: 291, end: 409}, {start: 409, end: 408}, {start: 408, end: 291}, - {start: 287, end: 410}, {start: 410, end: 409}, {start: 409, end: 287}, - {start: 432, end: 436}, {start: 436, end: 410}, {start: 410, end: 432}, - {start: 434, end: 416}, {start: 416, end: 411}, {start: 411, end: 434}, - {start: 264, end: 368}, {start: 368, end: 383}, {start: 383, end: 264}, - {start: 309, end: 438}, {start: 438, end: 457}, {start: 457, end: 309}, - {start: 352, end: 376}, {start: 376, end: 401}, {start: 401, end: 352}, - {start: 274, end: 275}, {start: 275, end: 4}, {start: 4, end: 274}, - {start: 421, end: 428}, {start: 428, end: 262}, {start: 262, end: 421}, - {start: 294, end: 327}, {start: 327, end: 358}, {start: 358, end: 294}, - {start: 433, end: 416}, {start: 416, end: 367}, {start: 367, end: 433}, - {start: 289, end: 455}, {start: 455, end: 439}, {start: 439, end: 289}, - {start: 462, end: 370}, {start: 370, end: 326}, {start: 326, end: 462}, - {start: 2, end: 326}, {start: 326, end: 370}, {start: 370, end: 2}, - {start: 305, end: 460}, {start: 460, end: 455}, {start: 455, end: 305}, - {start: 254, end: 449}, {start: 449, end: 448}, {start: 448, end: 254}, - {start: 255, end: 261}, {start: 261, end: 446}, {start: 446, end: 255}, - {start: 253, end: 450}, {start: 450, end: 449}, {start: 449, end: 253}, - {start: 252, end: 451}, {start: 451, end: 450}, {start: 450, end: 252}, - {start: 256, end: 452}, {start: 452, end: 451}, {start: 451, end: 256}, - {start: 341, end: 453}, {start: 453, end: 452}, {start: 452, end: 341}, - {start: 413, end: 464}, {start: 464, end: 463}, {start: 463, end: 413}, - {start: 441, end: 413}, {start: 413, end: 414}, {start: 414, end: 441}, - {start: 258, end: 442}, {start: 442, end: 441}, {start: 441, end: 258}, - {start: 257, end: 443}, {start: 443, end: 442}, {start: 442, end: 257}, - {start: 259, end: 444}, {start: 444, end: 443}, {start: 443, end: 259}, - {start: 260, end: 445}, {start: 445, end: 444}, {start: 444, end: 260}, - {start: 467, end: 342}, {start: 342, end: 445}, {start: 445, end: 467}, - {start: 459, end: 458}, {start: 458, end: 250}, {start: 250, end: 459}, - {start: 289, end: 392}, {start: 392, end: 290}, {start: 290, end: 289}, - {start: 290, end: 328}, {start: 328, end: 460}, {start: 460, end: 290}, - {start: 376, end: 433}, {start: 433, end: 435}, {start: 435, end: 376}, - {start: 250, end: 290}, {start: 290, end: 392}, {start: 392, end: 250}, - {start: 411, end: 416}, {start: 416, end: 433}, {start: 433, end: 411}, - {start: 341, end: 463}, {start: 463, end: 464}, {start: 464, end: 341}, - {start: 453, end: 464}, {start: 464, end: 465}, {start: 465, end: 453}, - {start: 357, end: 465}, {start: 465, end: 412}, {start: 412, end: 357}, - {start: 343, end: 412}, {start: 412, end: 399}, {start: 399, end: 343}, - {start: 360, end: 363}, {start: 363, end: 440}, {start: 440, end: 360}, - {start: 437, end: 399}, {start: 399, end: 456}, {start: 456, end: 437}, - {start: 420, end: 456}, {start: 456, end: 363}, {start: 363, end: 420}, - {start: 401, end: 435}, {start: 435, end: 288}, {start: 288, end: 401}, - {start: 372, end: 383}, {start: 383, end: 353}, {start: 353, end: 372}, - {start: 339, end: 255}, {start: 255, end: 249}, {start: 249, end: 339}, - {start: 448, end: 261}, {start: 261, end: 255}, {start: 255, end: 448}, - {start: 133, end: 243}, {start: 243, end: 190}, {start: 190, end: 133}, - {start: 133, end: 155}, {start: 155, end: 112}, {start: 112, end: 133}, - {start: 33, end: 246}, {start: 246, end: 247}, {start: 247, end: 33}, - {start: 33, end: 130}, {start: 130, end: 25}, {start: 25, end: 33}, - {start: 398, end: 384}, {start: 384, end: 286}, {start: 286, end: 398}, - {start: 362, end: 398}, {start: 398, end: 414}, {start: 414, end: 362}, - {start: 362, end: 463}, {start: 463, end: 341}, {start: 341, end: 362}, - {start: 263, end: 359}, {start: 359, end: 467}, {start: 467, end: 263}, - {start: 263, end: 249}, {start: 249, end: 255}, {start: 255, end: 263}, - {start: 466, end: 467}, {start: 467, end: 260}, {start: 260, end: 466}, - {start: 75, end: 60}, {start: 60, end: 166}, {start: 166, end: 75}, - {start: 238, end: 239}, {start: 239, end: 79}, {start: 79, end: 238}, - {start: 162, end: 127}, {start: 127, end: 139}, {start: 139, end: 162}, - {start: 72, end: 11}, {start: 11, end: 37}, {start: 37, end: 72}, - {start: 121, end: 232}, {start: 232, end: 120}, {start: 120, end: 121}, - {start: 73, end: 72}, {start: 72, end: 39}, {start: 39, end: 73}, - {start: 114, end: 128}, {start: 128, end: 47}, {start: 47, end: 114}, - {start: 233, end: 232}, {start: 232, end: 128}, {start: 128, end: 233}, - {start: 103, end: 104}, {start: 104, end: 67}, {start: 67, end: 103}, - {start: 152, end: 175}, {start: 175, end: 148}, {start: 148, end: 152}, - {start: 119, end: 118}, {start: 118, end: 101}, {start: 101, end: 119}, - {start: 74, end: 73}, {start: 73, end: 40}, {start: 40, end: 74}, - {start: 107, end: 9}, {start: 9, end: 108}, {start: 108, end: 107}, - {start: 49, end: 48}, {start: 48, end: 131}, {start: 131, end: 49}, - {start: 32, end: 194}, {start: 194, end: 211}, {start: 211, end: 32}, - {start: 184, end: 74}, {start: 74, end: 185}, {start: 185, end: 184}, - {start: 191, end: 80}, {start: 80, end: 183}, {start: 183, end: 191}, - {start: 185, end: 40}, {start: 40, end: 186}, {start: 186, end: 185}, - {start: 119, end: 230}, {start: 230, end: 118}, {start: 118, end: 119}, - {start: 210, end: 202}, {start: 202, end: 214}, {start: 214, end: 210}, - {start: 84, end: 83}, {start: 83, end: 17}, {start: 17, end: 84}, - {start: 77, end: 76}, {start: 76, end: 146}, {start: 146, end: 77}, - {start: 161, end: 160}, {start: 160, end: 30}, {start: 30, end: 161}, - {start: 190, end: 56}, {start: 56, end: 173}, {start: 173, end: 190}, - {start: 182, end: 106}, {start: 106, end: 194}, {start: 194, end: 182}, - {start: 138, end: 135}, {start: 135, end: 192}, {start: 192, end: 138}, - {start: 129, end: 203}, {start: 203, end: 98}, {start: 98, end: 129}, - {start: 54, end: 21}, {start: 21, end: 68}, {start: 68, end: 54}, - {start: 5, end: 51}, {start: 51, end: 4}, {start: 4, end: 5}, - {start: 145, end: 144}, {start: 144, end: 23}, {start: 23, end: 145}, - {start: 90, end: 77}, {start: 77, end: 91}, {start: 91, end: 90}, - {start: 207, end: 205}, {start: 205, end: 187}, {start: 187, end: 207}, - {start: 83, end: 201}, {start: 201, end: 18}, {start: 18, end: 83}, - {start: 181, end: 91}, {start: 91, end: 182}, {start: 182, end: 181}, - {start: 180, end: 90}, {start: 90, end: 181}, {start: 181, end: 180}, - {start: 16, end: 85}, {start: 85, end: 17}, {start: 17, end: 16}, - {start: 205, end: 206}, {start: 206, end: 36}, {start: 36, end: 205}, - {start: 176, end: 148}, {start: 148, end: 140}, {start: 140, end: 176}, - {start: 165, end: 92}, {start: 92, end: 39}, {start: 39, end: 165}, - {start: 245, end: 193}, {start: 193, end: 244}, {start: 244, end: 245}, - {start: 27, end: 159}, {start: 159, end: 28}, {start: 28, end: 27}, - {start: 30, end: 247}, {start: 247, end: 161}, {start: 161, end: 30}, - {start: 174, end: 236}, {start: 236, end: 196}, {start: 196, end: 174}, - {start: 103, end: 54}, {start: 54, end: 104}, {start: 104, end: 103}, - {start: 55, end: 193}, {start: 193, end: 8}, {start: 8, end: 55}, - {start: 111, end: 117}, {start: 117, end: 31}, {start: 31, end: 111}, - {start: 221, end: 189}, {start: 189, end: 55}, {start: 55, end: 221}, - {start: 240, end: 98}, {start: 98, end: 99}, {start: 99, end: 240}, - {start: 142, end: 126}, {start: 126, end: 100}, {start: 100, end: 142}, - {start: 219, end: 166}, {start: 166, end: 218}, {start: 218, end: 219}, - {start: 112, end: 155}, {start: 155, end: 26}, {start: 26, end: 112}, - {start: 198, end: 209}, {start: 209, end: 131}, {start: 131, end: 198}, - {start: 169, end: 135}, {start: 135, end: 150}, {start: 150, end: 169}, - {start: 114, end: 47}, {start: 47, end: 217}, {start: 217, end: 114}, - {start: 224, end: 223}, {start: 223, end: 53}, {start: 53, end: 224}, - {start: 220, end: 45}, {start: 45, end: 134}, {start: 134, end: 220}, - {start: 32, end: 211}, {start: 211, end: 140}, {start: 140, end: 32}, - {start: 109, end: 67}, {start: 67, end: 108}, {start: 108, end: 109}, - {start: 146, end: 43}, {start: 43, end: 91}, {start: 91, end: 146}, - {start: 231, end: 230}, {start: 230, end: 120}, {start: 120, end: 231}, - {start: 113, end: 226}, {start: 226, end: 247}, {start: 247, end: 113}, - {start: 105, end: 63}, {start: 63, end: 52}, {start: 52, end: 105}, - {start: 241, end: 238}, {start: 238, end: 242}, {start: 242, end: 241}, - {start: 124, end: 46}, {start: 46, end: 156}, {start: 156, end: 124}, - {start: 95, end: 78}, {start: 78, end: 96}, {start: 96, end: 95}, - {start: 70, end: 46}, {start: 46, end: 63}, {start: 63, end: 70}, - {start: 116, end: 143}, {start: 143, end: 227}, {start: 227, end: 116}, - {start: 116, end: 123}, {start: 123, end: 111}, {start: 111, end: 116}, - {start: 1, end: 44}, {start: 44, end: 19}, {start: 19, end: 1}, - {start: 3, end: 236}, {start: 236, end: 51}, {start: 51, end: 3}, - {start: 207, end: 216}, {start: 216, end: 205}, {start: 205, end: 207}, - {start: 26, end: 154}, {start: 154, end: 22}, {start: 22, end: 26}, - {start: 165, end: 39}, {start: 39, end: 167}, {start: 167, end: 165}, - {start: 199, end: 200}, {start: 200, end: 208}, {start: 208, end: 199}, - {start: 101, end: 36}, {start: 36, end: 100}, {start: 100, end: 101}, - {start: 43, end: 57}, {start: 57, end: 202}, {start: 202, end: 43}, - {start: 242, end: 20}, {start: 20, end: 99}, {start: 99, end: 242}, - {start: 56, end: 28}, {start: 28, end: 157}, {start: 157, end: 56}, - {start: 124, end: 35}, {start: 35, end: 113}, {start: 113, end: 124}, - {start: 29, end: 160}, {start: 160, end: 27}, {start: 27, end: 29}, - {start: 211, end: 204}, {start: 204, end: 210}, {start: 210, end: 211}, - {start: 124, end: 113}, {start: 113, end: 46}, {start: 46, end: 124}, - {start: 106, end: 43}, {start: 43, end: 204}, {start: 204, end: 106}, - {start: 96, end: 62}, {start: 62, end: 77}, {start: 77, end: 96}, - {start: 227, end: 137}, {start: 137, end: 116}, {start: 116, end: 227}, - {start: 73, end: 41}, {start: 41, end: 72}, {start: 72, end: 73}, - {start: 36, end: 203}, {start: 203, end: 142}, {start: 142, end: 36}, - {start: 235, end: 64}, {start: 64, end: 240}, {start: 240, end: 235}, - {start: 48, end: 49}, {start: 49, end: 64}, {start: 64, end: 48}, - {start: 42, end: 41}, {start: 41, end: 74}, {start: 74, end: 42}, - {start: 214, end: 212}, {start: 212, end: 207}, {start: 207, end: 214}, - {start: 183, end: 42}, {start: 42, end: 184}, {start: 184, end: 183}, - {start: 210, end: 169}, {start: 169, end: 211}, {start: 211, end: 210}, - {start: 140, end: 170}, {start: 170, end: 176}, {start: 176, end: 140}, - {start: 104, end: 105}, {start: 105, end: 69}, {start: 69, end: 104}, - {start: 193, end: 122}, {start: 122, end: 168}, {start: 168, end: 193}, - {start: 50, end: 123}, {start: 123, end: 187}, {start: 187, end: 50}, - {start: 89, end: 96}, {start: 96, end: 90}, {start: 90, end: 89}, - {start: 66, end: 65}, {start: 65, end: 107}, {start: 107, end: 66}, - {start: 179, end: 89}, {start: 89, end: 180}, {start: 180, end: 179}, - {start: 119, end: 101}, {start: 101, end: 120}, {start: 120, end: 119}, - {start: 68, end: 63}, {start: 63, end: 104}, {start: 104, end: 68}, - {start: 234, end: 93}, {start: 93, end: 227}, {start: 227, end: 234}, - {start: 16, end: 15}, {start: 15, end: 85}, {start: 85, end: 16}, - {start: 209, end: 129}, {start: 129, end: 49}, {start: 49, end: 209}, - {start: 15, end: 14}, {start: 14, end: 86}, {start: 86, end: 15}, - {start: 107, end: 55}, {start: 55, end: 9}, {start: 9, end: 107}, - {start: 120, end: 100}, {start: 100, end: 121}, {start: 121, end: 120}, - {start: 153, end: 145}, {start: 145, end: 22}, {start: 22, end: 153}, - {start: 178, end: 88}, {start: 88, end: 179}, {start: 179, end: 178}, - {start: 197, end: 6}, {start: 6, end: 196}, {start: 196, end: 197}, - {start: 89, end: 88}, {start: 88, end: 96}, {start: 96, end: 89}, - {start: 135, end: 138}, {start: 138, end: 136}, {start: 136, end: 135}, - {start: 138, end: 215}, {start: 215, end: 172}, {start: 172, end: 138}, - {start: 218, end: 115}, {start: 115, end: 219}, {start: 219, end: 218}, - {start: 41, end: 42}, {start: 42, end: 81}, {start: 81, end: 41}, - {start: 5, end: 195}, {start: 195, end: 51}, {start: 51, end: 5}, - {start: 57, end: 43}, {start: 43, end: 61}, {start: 61, end: 57}, - {start: 208, end: 171}, {start: 171, end: 199}, {start: 199, end: 208}, - {start: 41, end: 81}, {start: 81, end: 38}, {start: 38, end: 41}, - {start: 224, end: 53}, {start: 53, end: 225}, {start: 225, end: 224}, - {start: 24, end: 144}, {start: 144, end: 110}, {start: 110, end: 24}, - {start: 105, end: 52}, {start: 52, end: 66}, {start: 66, end: 105}, - {start: 118, end: 229}, {start: 229, end: 117}, {start: 117, end: 118}, - {start: 227, end: 34}, {start: 34, end: 234}, {start: 234, end: 227}, - {start: 66, end: 107}, {start: 107, end: 69}, {start: 69, end: 66}, - {start: 10, end: 109}, {start: 109, end: 151}, {start: 151, end: 10}, - {start: 219, end: 48}, {start: 48, end: 235}, {start: 235, end: 219}, - {start: 183, end: 62}, {start: 62, end: 191}, {start: 191, end: 183}, - {start: 142, end: 129}, {start: 129, end: 126}, {start: 126, end: 142}, - {start: 116, end: 111}, {start: 111, end: 143}, {start: 143, end: 116}, - {start: 118, end: 117}, {start: 117, end: 50}, {start: 50, end: 118}, - {start: 223, end: 222}, {start: 222, end: 52}, {start: 52, end: 223}, - {start: 94, end: 19}, {start: 19, end: 141}, {start: 141, end: 94}, - {start: 222, end: 221}, {start: 221, end: 65}, {start: 65, end: 222}, - {start: 196, end: 3}, {start: 3, end: 197}, {start: 197, end: 196}, - {start: 45, end: 220}, {start: 220, end: 44}, {start: 44, end: 45}, - {start: 156, end: 70}, {start: 70, end: 139}, {start: 139, end: 156}, - {start: 188, end: 122}, {start: 122, end: 245}, {start: 245, end: 188}, - {start: 139, end: 71}, {start: 71, end: 162}, {start: 162, end: 139}, - {start: 149, end: 170}, {start: 170, end: 150}, {start: 150, end: 149}, - {start: 122, end: 188}, {start: 188, end: 196}, {start: 196, end: 122}, - {start: 206, end: 216}, {start: 216, end: 92}, {start: 92, end: 206}, - {start: 164, end: 2}, {start: 2, end: 167}, {start: 167, end: 164}, - {start: 242, end: 141}, {start: 141, end: 241}, {start: 241, end: 242}, - {start: 0, end: 164}, {start: 164, end: 37}, {start: 37, end: 0}, - {start: 11, end: 72}, {start: 72, end: 12}, {start: 12, end: 11}, - {start: 12, end: 38}, {start: 38, end: 13}, {start: 13, end: 12}, - {start: 70, end: 63}, {start: 63, end: 71}, {start: 71, end: 70}, - {start: 31, end: 226}, {start: 226, end: 111}, {start: 111, end: 31}, - {start: 36, end: 101}, {start: 101, end: 205}, {start: 205, end: 36}, - {start: 203, end: 206}, {start: 206, end: 165}, {start: 165, end: 203}, - {start: 126, end: 209}, {start: 209, end: 217}, {start: 217, end: 126}, - {start: 98, end: 165}, {start: 165, end: 97}, {start: 97, end: 98}, - {start: 237, end: 220}, {start: 220, end: 218}, {start: 218, end: 237}, - {start: 237, end: 239}, {start: 239, end: 241}, {start: 241, end: 237}, - {start: 210, end: 214}, {start: 214, end: 169}, {start: 169, end: 210}, - {start: 140, end: 171}, {start: 171, end: 32}, {start: 32, end: 140}, - {start: 241, end: 125}, {start: 125, end: 237}, {start: 237, end: 241}, - {start: 179, end: 86}, {start: 86, end: 178}, {start: 178, end: 179}, - {start: 180, end: 85}, {start: 85, end: 179}, {start: 179, end: 180}, - {start: 181, end: 84}, {start: 84, end: 180}, {start: 180, end: 181}, - {start: 182, end: 83}, {start: 83, end: 181}, {start: 181, end: 182}, - {start: 194, end: 201}, {start: 201, end: 182}, {start: 182, end: 194}, - {start: 177, end: 137}, {start: 137, end: 132}, {start: 132, end: 177}, - {start: 184, end: 76}, {start: 76, end: 183}, {start: 183, end: 184}, - {start: 185, end: 61}, {start: 61, end: 184}, {start: 184, end: 185}, - {start: 186, end: 57}, {start: 57, end: 185}, {start: 185, end: 186}, - {start: 216, end: 212}, {start: 212, end: 186}, {start: 186, end: 216}, - {start: 192, end: 214}, {start: 214, end: 187}, {start: 187, end: 192}, - {start: 139, end: 34}, {start: 34, end: 156}, {start: 156, end: 139}, - {start: 218, end: 79}, {start: 79, end: 237}, {start: 237, end: 218}, - {start: 147, end: 123}, {start: 123, end: 177}, {start: 177, end: 147}, - {start: 45, end: 44}, {start: 44, end: 4}, {start: 4, end: 45}, - {start: 208, end: 201}, {start: 201, end: 32}, {start: 32, end: 208}, - {start: 98, end: 64}, {start: 64, end: 129}, {start: 129, end: 98}, - {start: 192, end: 213}, {start: 213, end: 138}, {start: 138, end: 192}, - {start: 235, end: 59}, {start: 59, end: 219}, {start: 219, end: 235}, - {start: 141, end: 242}, {start: 242, end: 97}, {start: 97, end: 141}, - {start: 97, end: 2}, {start: 2, end: 141}, {start: 141, end: 97}, - {start: 240, end: 75}, {start: 75, end: 235}, {start: 235, end: 240}, - {start: 229, end: 24}, {start: 24, end: 228}, {start: 228, end: 229}, - {start: 31, end: 25}, {start: 25, end: 226}, {start: 226, end: 31}, - {start: 230, end: 23}, {start: 23, end: 229}, {start: 229, end: 230}, - {start: 231, end: 22}, {start: 22, end: 230}, {start: 230, end: 231}, - {start: 232, end: 26}, {start: 26, end: 231}, {start: 231, end: 232}, - {start: 233, end: 112}, {start: 112, end: 232}, {start: 232, end: 233}, - {start: 244, end: 189}, {start: 189, end: 243}, {start: 243, end: 244}, - {start: 189, end: 221}, {start: 221, end: 190}, {start: 190, end: 189}, - {start: 222, end: 28}, {start: 28, end: 221}, {start: 221, end: 222}, - {start: 223, end: 27}, {start: 27, end: 222}, {start: 222, end: 223}, - {start: 224, end: 29}, {start: 29, end: 223}, {start: 223, end: 224}, - {start: 225, end: 30}, {start: 30, end: 224}, {start: 224, end: 225}, - {start: 113, end: 247}, {start: 247, end: 225}, {start: 225, end: 113}, - {start: 99, end: 60}, {start: 60, end: 240}, {start: 240, end: 99}, - {start: 213, end: 147}, {start: 147, end: 215}, {start: 215, end: 213}, - {start: 60, end: 20}, {start: 20, end: 166}, {start: 166, end: 60}, - {start: 192, end: 187}, {start: 187, end: 213}, {start: 213, end: 192}, - {start: 243, end: 112}, {start: 112, end: 244}, {start: 244, end: 243}, - {start: 244, end: 233}, {start: 233, end: 245}, {start: 245, end: 244}, - {start: 245, end: 128}, {start: 128, end: 188}, {start: 188, end: 245}, - {start: 188, end: 114}, {start: 114, end: 174}, {start: 174, end: 188}, - {start: 134, end: 131}, {start: 131, end: 220}, {start: 220, end: 134}, - {start: 174, end: 217}, {start: 217, end: 236}, {start: 236, end: 174}, - {start: 236, end: 198}, {start: 198, end: 134}, {start: 134, end: 236}, - {start: 215, end: 177}, {start: 177, end: 58}, {start: 58, end: 215}, - {start: 156, end: 143}, {start: 143, end: 124}, {start: 124, end: 156}, - {start: 25, end: 110}, {start: 110, end: 7}, {start: 7, end: 25}, - {start: 31, end: 228}, {start: 228, end: 25}, {start: 25, end: 31}, - {start: 264, end: 356}, {start: 356, end: 368}, {start: 368, end: 264}, - {start: 0, end: 11}, {start: 11, end: 267}, {start: 267, end: 0}, - {start: 451, end: 452}, {start: 452, end: 349}, {start: 349, end: 451}, - {start: 267, end: 302}, {start: 302, end: 269}, {start: 269, end: 267}, - {start: 350, end: 357}, {start: 357, end: 277}, {start: 277, end: 350}, - {start: 350, end: 452}, {start: 452, end: 357}, {start: 357, end: 350}, - {start: 299, end: 333}, {start: 333, end: 297}, {start: 297, end: 299}, - {start: 396, end: 175}, {start: 175, end: 377}, {start: 377, end: 396}, - {start: 280, end: 347}, {start: 347, end: 330}, {start: 330, end: 280}, - {start: 269, end: 303}, {start: 303, end: 270}, {start: 270, end: 269}, - {start: 151, end: 9}, {start: 9, end: 337}, {start: 337, end: 151}, - {start: 344, end: 278}, {start: 278, end: 360}, {start: 360, end: 344}, - {start: 424, end: 418}, {start: 418, end: 431}, {start: 431, end: 424}, - {start: 270, end: 304}, {start: 304, end: 409}, {start: 409, end: 270}, - {start: 272, end: 310}, {start: 310, end: 407}, {start: 407, end: 272}, - {start: 322, end: 270}, {start: 270, end: 410}, {start: 410, end: 322}, - {start: 449, end: 450}, {start: 450, end: 347}, {start: 347, end: 449}, - {start: 432, end: 422}, {start: 422, end: 434}, {start: 434, end: 432}, - {start: 18, end: 313}, {start: 313, end: 17}, {start: 17, end: 18}, - {start: 291, end: 306}, {start: 306, end: 375}, {start: 375, end: 291}, - {start: 259, end: 387}, {start: 387, end: 260}, {start: 260, end: 259}, - {start: 424, end: 335}, {start: 335, end: 418}, {start: 418, end: 424}, - {start: 434, end: 364}, {start: 364, end: 416}, {start: 416, end: 434}, - {start: 391, end: 423}, {start: 423, end: 327}, {start: 327, end: 391}, - {start: 301, end: 251}, {start: 251, end: 298}, {start: 298, end: 301}, - {start: 275, end: 281}, {start: 281, end: 4}, {start: 4, end: 275}, - {start: 254, end: 373}, {start: 373, end: 253}, {start: 253, end: 254}, - {start: 375, end: 307}, {start: 307, end: 321}, {start: 321, end: 375}, - {start: 280, end: 425}, {start: 425, end: 411}, {start: 411, end: 280}, - {start: 200, end: 421}, {start: 421, end: 18}, {start: 18, end: 200}, - {start: 335, end: 321}, {start: 321, end: 406}, {start: 406, end: 335}, - {start: 321, end: 320}, {start: 320, end: 405}, {start: 405, end: 321}, - {start: 314, end: 315}, {start: 315, end: 17}, {start: 17, end: 314}, - {start: 423, end: 426}, {start: 426, end: 266}, {start: 266, end: 423}, - {start: 396, end: 377}, {start: 377, end: 369}, {start: 369, end: 396}, - {start: 270, end: 322}, {start: 322, end: 269}, {start: 269, end: 270}, - {start: 413, end: 417}, {start: 417, end: 464}, {start: 464, end: 413}, - {start: 385, end: 386}, {start: 386, end: 258}, {start: 258, end: 385}, - {start: 248, end: 456}, {start: 456, end: 419}, {start: 419, end: 248}, - {start: 298, end: 284}, {start: 284, end: 333}, {start: 333, end: 298}, - {start: 168, end: 417}, {start: 417, end: 8}, {start: 8, end: 168}, - {start: 448, end: 346}, {start: 346, end: 261}, {start: 261, end: 448}, - {start: 417, end: 413}, {start: 413, end: 285}, {start: 285, end: 417}, - {start: 326, end: 327}, {start: 327, end: 328}, {start: 328, end: 326}, - {start: 277, end: 355}, {start: 355, end: 329}, {start: 329, end: 277}, - {start: 309, end: 392}, {start: 392, end: 438}, {start: 438, end: 309}, - {start: 381, end: 382}, {start: 382, end: 256}, {start: 256, end: 381}, - {start: 279, end: 429}, {start: 429, end: 360}, {start: 360, end: 279}, - {start: 365, end: 364}, {start: 364, end: 379}, {start: 379, end: 365}, - {start: 355, end: 277}, {start: 277, end: 437}, {start: 437, end: 355}, - {start: 282, end: 443}, {start: 443, end: 283}, {start: 283, end: 282}, - {start: 281, end: 275}, {start: 275, end: 363}, {start: 363, end: 281}, - {start: 395, end: 431}, {start: 431, end: 369}, {start: 369, end: 395}, - {start: 299, end: 297}, {start: 297, end: 337}, {start: 337, end: 299}, - {start: 335, end: 273}, {start: 273, end: 321}, {start: 321, end: 335}, - {start: 348, end: 450}, {start: 450, end: 349}, {start: 349, end: 348}, - {start: 359, end: 446}, {start: 446, end: 467}, {start: 467, end: 359}, - {start: 283, end: 293}, {start: 293, end: 282}, {start: 282, end: 283}, - {start: 250, end: 458}, {start: 458, end: 462}, {start: 462, end: 250}, - {start: 300, end: 276}, {start: 276, end: 383}, {start: 383, end: 300}, - {start: 292, end: 308}, {start: 308, end: 325}, {start: 325, end: 292}, - {start: 283, end: 276}, {start: 276, end: 293}, {start: 293, end: 283}, - {start: 264, end: 372}, {start: 372, end: 447}, {start: 447, end: 264}, - {start: 346, end: 352}, {start: 352, end: 340}, {start: 340, end: 346}, - {start: 354, end: 274}, {start: 274, end: 19}, {start: 19, end: 354}, - {start: 363, end: 456}, {start: 456, end: 281}, {start: 281, end: 363}, - {start: 426, end: 436}, {start: 436, end: 425}, {start: 425, end: 426}, - {start: 380, end: 381}, {start: 381, end: 252}, {start: 252, end: 380}, - {start: 267, end: 269}, {start: 269, end: 393}, {start: 393, end: 267}, - {start: 421, end: 200}, {start: 200, end: 428}, {start: 428, end: 421}, - {start: 371, end: 266}, {start: 266, end: 329}, {start: 329, end: 371}, - {start: 432, end: 287}, {start: 287, end: 422}, {start: 422, end: 432}, - {start: 290, end: 250}, {start: 250, end: 328}, {start: 328, end: 290}, - {start: 385, end: 258}, {start: 258, end: 384}, {start: 384, end: 385}, - {start: 446, end: 265}, {start: 265, end: 342}, {start: 342, end: 446}, - {start: 386, end: 387}, {start: 387, end: 257}, {start: 257, end: 386}, - {start: 422, end: 424}, {start: 424, end: 430}, {start: 430, end: 422}, - {start: 445, end: 342}, {start: 342, end: 276}, {start: 276, end: 445}, - {start: 422, end: 273}, {start: 273, end: 424}, {start: 424, end: 422}, - {start: 306, end: 292}, {start: 292, end: 307}, {start: 307, end: 306}, - {start: 352, end: 366}, {start: 366, end: 345}, {start: 345, end: 352}, - {start: 268, end: 271}, {start: 271, end: 302}, {start: 302, end: 268}, - {start: 358, end: 423}, {start: 423, end: 371}, {start: 371, end: 358}, - {start: 327, end: 294}, {start: 294, end: 460}, {start: 460, end: 327}, - {start: 331, end: 279}, {start: 279, end: 294}, {start: 294, end: 331}, - {start: 303, end: 271}, {start: 271, end: 304}, {start: 304, end: 303}, - {start: 436, end: 432}, {start: 432, end: 427}, {start: 427, end: 436}, - {start: 304, end: 272}, {start: 272, end: 408}, {start: 408, end: 304}, - {start: 395, end: 394}, {start: 394, end: 431}, {start: 431, end: 395}, - {start: 378, end: 395}, {start: 395, end: 400}, {start: 400, end: 378}, - {start: 296, end: 334}, {start: 334, end: 299}, {start: 299, end: 296}, - {start: 6, end: 351}, {start: 351, end: 168}, {start: 168, end: 6}, - {start: 376, end: 352}, {start: 352, end: 411}, {start: 411, end: 376}, - {start: 307, end: 325}, {start: 325, end: 320}, {start: 320, end: 307}, - {start: 285, end: 295}, {start: 295, end: 336}, {start: 336, end: 285}, - {start: 320, end: 319}, {start: 319, end: 404}, {start: 404, end: 320}, - {start: 329, end: 330}, {start: 330, end: 349}, {start: 349, end: 329}, - {start: 334, end: 293}, {start: 293, end: 333}, {start: 333, end: 334}, - {start: 366, end: 323}, {start: 323, end: 447}, {start: 447, end: 366}, - {start: 316, end: 15}, {start: 15, end: 315}, {start: 315, end: 316}, - {start: 331, end: 358}, {start: 358, end: 279}, {start: 279, end: 331}, - {start: 317, end: 14}, {start: 14, end: 316}, {start: 316, end: 317}, - {start: 8, end: 285}, {start: 285, end: 9}, {start: 9, end: 8}, - {start: 277, end: 329}, {start: 329, end: 350}, {start: 350, end: 277}, - {start: 253, end: 374}, {start: 374, end: 252}, {start: 252, end: 253}, - {start: 319, end: 318}, {start: 318, end: 403}, {start: 403, end: 319}, - {start: 351, end: 6}, {start: 6, end: 419}, {start: 419, end: 351}, - {start: 324, end: 318}, {start: 318, end: 325}, {start: 325, end: 324}, - {start: 397, end: 367}, {start: 367, end: 365}, {start: 365, end: 397}, - {start: 288, end: 435}, {start: 435, end: 397}, {start: 397, end: 288}, - {start: 278, end: 344}, {start: 344, end: 439}, {start: 439, end: 278}, - {start: 310, end: 272}, {start: 272, end: 311}, {start: 311, end: 310}, - {start: 248, end: 195}, {start: 195, end: 281}, {start: 281, end: 248}, - {start: 375, end: 273}, {start: 273, end: 291}, {start: 291, end: 375}, - {start: 175, end: 396}, {start: 396, end: 199}, {start: 199, end: 175}, - {start: 312, end: 311}, {start: 311, end: 268}, {start: 268, end: 312}, - {start: 276, end: 283}, {start: 283, end: 445}, {start: 445, end: 276}, - {start: 390, end: 373}, {start: 373, end: 339}, {start: 339, end: 390}, - {start: 295, end: 282}, {start: 282, end: 296}, {start: 296, end: 295}, - {start: 448, end: 449}, {start: 449, end: 346}, {start: 346, end: 448}, - {start: 356, end: 264}, {start: 264, end: 454}, {start: 454, end: 356}, - {start: 337, end: 336}, {start: 336, end: 299}, {start: 299, end: 337}, - {start: 337, end: 338}, {start: 338, end: 151}, {start: 151, end: 337}, - {start: 294, end: 278}, {start: 278, end: 455}, {start: 455, end: 294}, - {start: 308, end: 292}, {start: 292, end: 415}, {start: 415, end: 308}, - {start: 429, end: 358}, {start: 358, end: 355}, {start: 355, end: 429}, - {start: 265, end: 340}, {start: 340, end: 372}, {start: 372, end: 265}, - {start: 352, end: 346}, {start: 346, end: 280}, {start: 280, end: 352}, - {start: 295, end: 442}, {start: 442, end: 282}, {start: 282, end: 295}, - {start: 354, end: 19}, {start: 19, end: 370}, {start: 370, end: 354}, - {start: 285, end: 441}, {start: 441, end: 295}, {start: 295, end: 285}, - {start: 195, end: 248}, {start: 248, end: 197}, {start: 197, end: 195}, - {start: 457, end: 440}, {start: 440, end: 274}, {start: 274, end: 457}, - {start: 301, end: 300}, {start: 300, end: 368}, {start: 368, end: 301}, - {start: 417, end: 351}, {start: 351, end: 465}, {start: 465, end: 417}, - {start: 251, end: 301}, {start: 301, end: 389}, {start: 389, end: 251}, - {start: 394, end: 395}, {start: 395, end: 379}, {start: 379, end: 394}, - {start: 399, end: 412}, {start: 412, end: 419}, {start: 419, end: 399}, - {start: 410, end: 436}, {start: 436, end: 322}, {start: 322, end: 410}, - {start: 326, end: 2}, {start: 2, end: 393}, {start: 393, end: 326}, - {start: 354, end: 370}, {start: 370, end: 461}, {start: 461, end: 354}, - {start: 393, end: 164}, {start: 164, end: 267}, {start: 267, end: 393}, - {start: 268, end: 302}, {start: 302, end: 12}, {start: 12, end: 268}, - {start: 312, end: 268}, {start: 268, end: 13}, {start: 13, end: 312}, - {start: 298, end: 293}, {start: 293, end: 301}, {start: 301, end: 298}, - {start: 265, end: 446}, {start: 446, end: 340}, {start: 340, end: 265}, - {start: 280, end: 330}, {start: 330, end: 425}, {start: 425, end: 280}, - {start: 322, end: 426}, {start: 426, end: 391}, {start: 391, end: 322}, - {start: 420, end: 429}, {start: 429, end: 437}, {start: 437, end: 420}, - {start: 393, end: 391}, {start: 391, end: 326}, {start: 326, end: 393}, - {start: 344, end: 440}, {start: 440, end: 438}, {start: 438, end: 344}, - {start: 458, end: 459}, {start: 459, end: 461}, {start: 461, end: 458}, - {start: 364, end: 434}, {start: 434, end: 394}, {start: 394, end: 364}, - {start: 428, end: 396}, {start: 396, end: 262}, {start: 262, end: 428}, - {start: 274, end: 354}, {start: 354, end: 457}, {start: 457, end: 274}, - {start: 317, end: 316}, {start: 316, end: 402}, {start: 402, end: 317}, - {start: 316, end: 315}, {start: 315, end: 403}, {start: 403, end: 316}, - {start: 315, end: 314}, {start: 314, end: 404}, {start: 404, end: 315}, - {start: 314, end: 313}, {start: 313, end: 405}, {start: 405, end: 314}, - {start: 313, end: 421}, {start: 421, end: 406}, {start: 406, end: 313}, - {start: 323, end: 366}, {start: 366, end: 361}, {start: 361, end: 323}, - {start: 292, end: 306}, {start: 306, end: 407}, {start: 407, end: 292}, - {start: 306, end: 291}, {start: 291, end: 408}, {start: 408, end: 306}, - {start: 291, end: 287}, {start: 287, end: 409}, {start: 409, end: 291}, - {start: 287, end: 432}, {start: 432, end: 410}, {start: 410, end: 287}, - {start: 427, end: 434}, {start: 434, end: 411}, {start: 411, end: 427}, - {start: 372, end: 264}, {start: 264, end: 383}, {start: 383, end: 372}, - {start: 459, end: 309}, {start: 309, end: 457}, {start: 457, end: 459}, - {start: 366, end: 352}, {start: 352, end: 401}, {start: 401, end: 366}, - {start: 1, end: 274}, {start: 274, end: 4}, {start: 4, end: 1}, - {start: 418, end: 421}, {start: 421, end: 262}, {start: 262, end: 418}, - {start: 331, end: 294}, {start: 294, end: 358}, {start: 358, end: 331}, - {start: 435, end: 433}, {start: 433, end: 367}, {start: 367, end: 435}, - {start: 392, end: 289}, {start: 289, end: 439}, {start: 439, end: 392}, - {start: 328, end: 462}, {start: 462, end: 326}, {start: 326, end: 328}, - {start: 94, end: 2}, {start: 2, end: 370}, {start: 370, end: 94}, - {start: 289, end: 305}, {start: 305, end: 455}, {start: 455, end: 289}, - {start: 339, end: 254}, {start: 254, end: 448}, {start: 448, end: 339}, - {start: 359, end: 255}, {start: 255, end: 446}, {start: 446, end: 359}, - {start: 254, end: 253}, {start: 253, end: 449}, {start: 449, end: 254}, - {start: 253, end: 252}, {start: 252, end: 450}, {start: 450, end: 253}, - {start: 252, end: 256}, {start: 256, end: 451}, {start: 451, end: 252}, - {start: 256, end: 341}, {start: 341, end: 452}, {start: 452, end: 256}, - {start: 414, end: 413}, {start: 413, end: 463}, {start: 463, end: 414}, - {start: 286, end: 441}, {start: 441, end: 414}, {start: 414, end: 286}, - {start: 286, end: 258}, {start: 258, end: 441}, {start: 441, end: 286}, - {start: 258, end: 257}, {start: 257, end: 442}, {start: 442, end: 258}, - {start: 257, end: 259}, {start: 259, end: 443}, {start: 443, end: 257}, - {start: 259, end: 260}, {start: 260, end: 444}, {start: 444, end: 259}, - {start: 260, end: 467}, {start: 467, end: 445}, {start: 445, end: 260}, - {start: 309, end: 459}, {start: 459, end: 250}, {start: 250, end: 309}, - {start: 305, end: 289}, {start: 289, end: 290}, {start: 290, end: 305}, - {start: 305, end: 290}, {start: 290, end: 460}, {start: 460, end: 305}, - {start: 401, end: 376}, {start: 376, end: 435}, {start: 435, end: 401}, - {start: 309, end: 250}, {start: 250, end: 392}, {start: 392, end: 309}, - {start: 376, end: 411}, {start: 411, end: 433}, {start: 433, end: 376}, - {start: 453, end: 341}, {start: 341, end: 464}, {start: 464, end: 453}, - {start: 357, end: 453}, {start: 453, end: 465}, {start: 465, end: 357}, - {start: 343, end: 357}, {start: 357, end: 412}, {start: 412, end: 343}, - {start: 437, end: 343}, {start: 343, end: 399}, {start: 399, end: 437}, - {start: 344, end: 360}, {start: 360, end: 440}, {start: 440, end: 344}, - {start: 420, end: 437}, {start: 437, end: 456}, {start: 456, end: 420}, - {start: 360, end: 420}, {start: 420, end: 363}, {start: 363, end: 360}, - {start: 361, end: 401}, {start: 401, end: 288}, {start: 288, end: 361}, - {start: 265, end: 372}, {start: 372, end: 353}, {start: 353, end: 265}, - {start: 390, end: 339}, {start: 339, end: 249}, {start: 249, end: 390}, - {start: 339, end: 448}, {start: 448, end: 255}, {start: 255, end: 339} - ]; -} +/** Landmarks for face tesselation */ +export const FACE_LANDMARKS_TESSELATION: Connection[] = [ + {start: 127, end: 34}, {start: 34, end: 139}, {start: 139, end: 127}, + {start: 11, end: 0}, {start: 0, end: 37}, {start: 37, end: 11}, + {start: 232, end: 231}, {start: 231, end: 120}, {start: 120, end: 232}, + {start: 72, end: 37}, {start: 37, end: 39}, {start: 39, end: 72}, + {start: 128, end: 121}, {start: 121, end: 47}, {start: 47, end: 128}, + {start: 232, end: 121}, {start: 121, end: 128}, {start: 128, end: 232}, + {start: 104, end: 69}, {start: 69, end: 67}, {start: 67, end: 104}, + {start: 175, end: 171}, {start: 171, end: 148}, {start: 148, end: 175}, + {start: 118, end: 50}, {start: 50, end: 101}, {start: 101, end: 118}, + {start: 73, end: 39}, {start: 39, end: 40}, {start: 40, end: 73}, + {start: 9, end: 151}, {start: 151, end: 108}, {start: 108, end: 9}, + {start: 48, end: 115}, {start: 115, end: 131}, {start: 131, end: 48}, + {start: 194, end: 204}, {start: 204, end: 211}, {start: 211, end: 194}, + {start: 74, end: 40}, {start: 40, end: 185}, {start: 185, end: 74}, + {start: 80, end: 42}, {start: 42, end: 183}, {start: 183, end: 80}, + {start: 40, end: 92}, {start: 92, end: 186}, {start: 186, end: 40}, + {start: 230, end: 229}, {start: 229, end: 118}, {start: 118, end: 230}, + {start: 202, end: 212}, {start: 212, end: 214}, {start: 214, end: 202}, + {start: 83, end: 18}, {start: 18, end: 17}, {start: 17, end: 83}, + {start: 76, end: 61}, {start: 61, end: 146}, {start: 146, end: 76}, + {start: 160, end: 29}, {start: 29, end: 30}, {start: 30, end: 160}, + {start: 56, end: 157}, {start: 157, end: 173}, {start: 173, end: 56}, + {start: 106, end: 204}, {start: 204, end: 194}, {start: 194, end: 106}, + {start: 135, end: 214}, {start: 214, end: 192}, {start: 192, end: 135}, + {start: 203, end: 165}, {start: 165, end: 98}, {start: 98, end: 203}, + {start: 21, end: 71}, {start: 71, end: 68}, {start: 68, end: 21}, + {start: 51, end: 45}, {start: 45, end: 4}, {start: 4, end: 51}, + {start: 144, end: 24}, {start: 24, end: 23}, {start: 23, end: 144}, + {start: 77, end: 146}, {start: 146, end: 91}, {start: 91, end: 77}, + {start: 205, end: 50}, {start: 50, end: 187}, {start: 187, end: 205}, + {start: 201, end: 200}, {start: 200, end: 18}, {start: 18, end: 201}, + {start: 91, end: 106}, {start: 106, end: 182}, {start: 182, end: 91}, + {start: 90, end: 91}, {start: 91, end: 181}, {start: 181, end: 90}, + {start: 85, end: 84}, {start: 84, end: 17}, {start: 17, end: 85}, + {start: 206, end: 203}, {start: 203, end: 36}, {start: 36, end: 206}, + {start: 148, end: 171}, {start: 171, end: 140}, {start: 140, end: 148}, + {start: 92, end: 40}, {start: 40, end: 39}, {start: 39, end: 92}, + {start: 193, end: 189}, {start: 189, end: 244}, {start: 244, end: 193}, + {start: 159, end: 158}, {start: 158, end: 28}, {start: 28, end: 159}, + {start: 247, end: 246}, {start: 246, end: 161}, {start: 161, end: 247}, + {start: 236, end: 3}, {start: 3, end: 196}, {start: 196, end: 236}, + {start: 54, end: 68}, {start: 68, end: 104}, {start: 104, end: 54}, + {start: 193, end: 168}, {start: 168, end: 8}, {start: 8, end: 193}, + {start: 117, end: 228}, {start: 228, end: 31}, {start: 31, end: 117}, + {start: 189, end: 193}, {start: 193, end: 55}, {start: 55, end: 189}, + {start: 98, end: 97}, {start: 97, end: 99}, {start: 99, end: 98}, + {start: 126, end: 47}, {start: 47, end: 100}, {start: 100, end: 126}, + {start: 166, end: 79}, {start: 79, end: 218}, {start: 218, end: 166}, + {start: 155, end: 154}, {start: 154, end: 26}, {start: 26, end: 155}, + {start: 209, end: 49}, {start: 49, end: 131}, {start: 131, end: 209}, + {start: 135, end: 136}, {start: 136, end: 150}, {start: 150, end: 135}, + {start: 47, end: 126}, {start: 126, end: 217}, {start: 217, end: 47}, + {start: 223, end: 52}, {start: 52, end: 53}, {start: 53, end: 223}, + {start: 45, end: 51}, {start: 51, end: 134}, {start: 134, end: 45}, + {start: 211, end: 170}, {start: 170, end: 140}, {start: 140, end: 211}, + {start: 67, end: 69}, {start: 69, end: 108}, {start: 108, end: 67}, + {start: 43, end: 106}, {start: 106, end: 91}, {start: 91, end: 43}, + {start: 230, end: 119}, {start: 119, end: 120}, {start: 120, end: 230}, + {start: 226, end: 130}, {start: 130, end: 247}, {start: 247, end: 226}, + {start: 63, end: 53}, {start: 53, end: 52}, {start: 52, end: 63}, + {start: 238, end: 20}, {start: 20, end: 242}, {start: 242, end: 238}, + {start: 46, end: 70}, {start: 70, end: 156}, {start: 156, end: 46}, + {start: 78, end: 62}, {start: 62, end: 96}, {start: 96, end: 78}, + {start: 46, end: 53}, {start: 53, end: 63}, {start: 63, end: 46}, + {start: 143, end: 34}, {start: 34, end: 227}, {start: 227, end: 143}, + {start: 123, end: 117}, {start: 117, end: 111}, {start: 111, end: 123}, + {start: 44, end: 125}, {start: 125, end: 19}, {start: 19, end: 44}, + {start: 236, end: 134}, {start: 134, end: 51}, {start: 51, end: 236}, + {start: 216, end: 206}, {start: 206, end: 205}, {start: 205, end: 216}, + {start: 154, end: 153}, {start: 153, end: 22}, {start: 22, end: 154}, + {start: 39, end: 37}, {start: 37, end: 167}, {start: 167, end: 39}, + {start: 200, end: 201}, {start: 201, end: 208}, {start: 208, end: 200}, + {start: 36, end: 142}, {start: 142, end: 100}, {start: 100, end: 36}, + {start: 57, end: 212}, {start: 212, end: 202}, {start: 202, end: 57}, + {start: 20, end: 60}, {start: 60, end: 99}, {start: 99, end: 20}, + {start: 28, end: 158}, {start: 158, end: 157}, {start: 157, end: 28}, + {start: 35, end: 226}, {start: 226, end: 113}, {start: 113, end: 35}, + {start: 160, end: 159}, {start: 159, end: 27}, {start: 27, end: 160}, + {start: 204, end: 202}, {start: 202, end: 210}, {start: 210, end: 204}, + {start: 113, end: 225}, {start: 225, end: 46}, {start: 46, end: 113}, + {start: 43, end: 202}, {start: 202, end: 204}, {start: 204, end: 43}, + {start: 62, end: 76}, {start: 76, end: 77}, {start: 77, end: 62}, + {start: 137, end: 123}, {start: 123, end: 116}, {start: 116, end: 137}, + {start: 41, end: 38}, {start: 38, end: 72}, {start: 72, end: 41}, + {start: 203, end: 129}, {start: 129, end: 142}, {start: 142, end: 203}, + {start: 64, end: 98}, {start: 98, end: 240}, {start: 240, end: 64}, + {start: 49, end: 102}, {start: 102, end: 64}, {start: 64, end: 49}, + {start: 41, end: 73}, {start: 73, end: 74}, {start: 74, end: 41}, + {start: 212, end: 216}, {start: 216, end: 207}, {start: 207, end: 212}, + {start: 42, end: 74}, {start: 74, end: 184}, {start: 184, end: 42}, + {start: 169, end: 170}, {start: 170, end: 211}, {start: 211, end: 169}, + {start: 170, end: 149}, {start: 149, end: 176}, {start: 176, end: 170}, + {start: 105, end: 66}, {start: 66, end: 69}, {start: 69, end: 105}, + {start: 122, end: 6}, {start: 6, end: 168}, {start: 168, end: 122}, + {start: 123, end: 147}, {start: 147, end: 187}, {start: 187, end: 123}, + {start: 96, end: 77}, {start: 77, end: 90}, {start: 90, end: 96}, + {start: 65, end: 55}, {start: 55, end: 107}, {start: 107, end: 65}, + {start: 89, end: 90}, {start: 90, end: 180}, {start: 180, end: 89}, + {start: 101, end: 100}, {start: 100, end: 120}, {start: 120, end: 101}, + {start: 63, end: 105}, {start: 105, end: 104}, {start: 104, end: 63}, + {start: 93, end: 137}, {start: 137, end: 227}, {start: 227, end: 93}, + {start: 15, end: 86}, {start: 86, end: 85}, {start: 85, end: 15}, + {start: 129, end: 102}, {start: 102, end: 49}, {start: 49, end: 129}, + {start: 14, end: 87}, {start: 87, end: 86}, {start: 86, end: 14}, + {start: 55, end: 8}, {start: 8, end: 9}, {start: 9, end: 55}, + {start: 100, end: 47}, {start: 47, end: 121}, {start: 121, end: 100}, + {start: 145, end: 23}, {start: 23, end: 22}, {start: 22, end: 145}, + {start: 88, end: 89}, {start: 89, end: 179}, {start: 179, end: 88}, + {start: 6, end: 122}, {start: 122, end: 196}, {start: 196, end: 6}, + {start: 88, end: 95}, {start: 95, end: 96}, {start: 96, end: 88}, + {start: 138, end: 172}, {start: 172, end: 136}, {start: 136, end: 138}, + {start: 215, end: 58}, {start: 58, end: 172}, {start: 172, end: 215}, + {start: 115, end: 48}, {start: 48, end: 219}, {start: 219, end: 115}, + {start: 42, end: 80}, {start: 80, end: 81}, {start: 81, end: 42}, + {start: 195, end: 3}, {start: 3, end: 51}, {start: 51, end: 195}, + {start: 43, end: 146}, {start: 146, end: 61}, {start: 61, end: 43}, + {start: 171, end: 175}, {start: 175, end: 199}, {start: 199, end: 171}, + {start: 81, end: 82}, {start: 82, end: 38}, {start: 38, end: 81}, + {start: 53, end: 46}, {start: 46, end: 225}, {start: 225, end: 53}, + {start: 144, end: 163}, {start: 163, end: 110}, {start: 110, end: 144}, + {start: 52, end: 65}, {start: 65, end: 66}, {start: 66, end: 52}, + {start: 229, end: 228}, {start: 228, end: 117}, {start: 117, end: 229}, + {start: 34, end: 127}, {start: 127, end: 234}, {start: 234, end: 34}, + {start: 107, end: 108}, {start: 108, end: 69}, {start: 69, end: 107}, + {start: 109, end: 108}, {start: 108, end: 151}, {start: 151, end: 109}, + {start: 48, end: 64}, {start: 64, end: 235}, {start: 235, end: 48}, + {start: 62, end: 78}, {start: 78, end: 191}, {start: 191, end: 62}, + {start: 129, end: 209}, {start: 209, end: 126}, {start: 126, end: 129}, + {start: 111, end: 35}, {start: 35, end: 143}, {start: 143, end: 111}, + {start: 117, end: 123}, {start: 123, end: 50}, {start: 50, end: 117}, + {start: 222, end: 65}, {start: 65, end: 52}, {start: 52, end: 222}, + {start: 19, end: 125}, {start: 125, end: 141}, {start: 141, end: 19}, + {start: 221, end: 55}, {start: 55, end: 65}, {start: 65, end: 221}, + {start: 3, end: 195}, {start: 195, end: 197}, {start: 197, end: 3}, + {start: 25, end: 7}, {start: 7, end: 33}, {start: 33, end: 25}, + {start: 220, end: 237}, {start: 237, end: 44}, {start: 44, end: 220}, + {start: 70, end: 71}, {start: 71, end: 139}, {start: 139, end: 70}, + {start: 122, end: 193}, {start: 193, end: 245}, {start: 245, end: 122}, + {start: 247, end: 130}, {start: 130, end: 33}, {start: 33, end: 247}, + {start: 71, end: 21}, {start: 21, end: 162}, {start: 162, end: 71}, + {start: 170, end: 169}, {start: 169, end: 150}, {start: 150, end: 170}, + {start: 188, end: 174}, {start: 174, end: 196}, {start: 196, end: 188}, + {start: 216, end: 186}, {start: 186, end: 92}, {start: 92, end: 216}, + {start: 2, end: 97}, {start: 97, end: 167}, {start: 167, end: 2}, + {start: 141, end: 125}, {start: 125, end: 241}, {start: 241, end: 141}, + {start: 164, end: 167}, {start: 167, end: 37}, {start: 37, end: 164}, + {start: 72, end: 38}, {start: 38, end: 12}, {start: 12, end: 72}, + {start: 38, end: 82}, {start: 82, end: 13}, {start: 13, end: 38}, + {start: 63, end: 68}, {start: 68, end: 71}, {start: 71, end: 63}, + {start: 226, end: 35}, {start: 35, end: 111}, {start: 111, end: 226}, + {start: 101, end: 50}, {start: 50, end: 205}, {start: 205, end: 101}, + {start: 206, end: 92}, {start: 92, end: 165}, {start: 165, end: 206}, + {start: 209, end: 198}, {start: 198, end: 217}, {start: 217, end: 209}, + {start: 165, end: 167}, {start: 167, end: 97}, {start: 97, end: 165}, + {start: 220, end: 115}, {start: 115, end: 218}, {start: 218, end: 220}, + {start: 133, end: 112}, {start: 112, end: 243}, {start: 243, end: 133}, + {start: 239, end: 238}, {start: 238, end: 241}, {start: 241, end: 239}, + {start: 214, end: 135}, {start: 135, end: 169}, {start: 169, end: 214}, + {start: 190, end: 173}, {start: 173, end: 133}, {start: 133, end: 190}, + {start: 171, end: 208}, {start: 208, end: 32}, {start: 32, end: 171}, + {start: 125, end: 44}, {start: 44, end: 237}, {start: 237, end: 125}, + {start: 86, end: 87}, {start: 87, end: 178}, {start: 178, end: 86}, + {start: 85, end: 86}, {start: 86, end: 179}, {start: 179, end: 85}, + {start: 84, end: 85}, {start: 85, end: 180}, {start: 180, end: 84}, + {start: 83, end: 84}, {start: 84, end: 181}, {start: 181, end: 83}, + {start: 201, end: 83}, {start: 83, end: 182}, {start: 182, end: 201}, + {start: 137, end: 93}, {start: 93, end: 132}, {start: 132, end: 137}, + {start: 76, end: 62}, {start: 62, end: 183}, {start: 183, end: 76}, + {start: 61, end: 76}, {start: 76, end: 184}, {start: 184, end: 61}, + {start: 57, end: 61}, {start: 61, end: 185}, {start: 185, end: 57}, + {start: 212, end: 57}, {start: 57, end: 186}, {start: 186, end: 212}, + {start: 214, end: 207}, {start: 207, end: 187}, {start: 187, end: 214}, + {start: 34, end: 143}, {start: 143, end: 156}, {start: 156, end: 34}, + {start: 79, end: 239}, {start: 239, end: 237}, {start: 237, end: 79}, + {start: 123, end: 137}, {start: 137, end: 177}, {start: 177, end: 123}, + {start: 44, end: 1}, {start: 1, end: 4}, {start: 4, end: 44}, + {start: 201, end: 194}, {start: 194, end: 32}, {start: 32, end: 201}, + {start: 64, end: 102}, {start: 102, end: 129}, {start: 129, end: 64}, + {start: 213, end: 215}, {start: 215, end: 138}, {start: 138, end: 213}, + {start: 59, end: 166}, {start: 166, end: 219}, {start: 219, end: 59}, + {start: 242, end: 99}, {start: 99, end: 97}, {start: 97, end: 242}, + {start: 2, end: 94}, {start: 94, end: 141}, {start: 141, end: 2}, + {start: 75, end: 59}, {start: 59, end: 235}, {start: 235, end: 75}, + {start: 24, end: 110}, {start: 110, end: 228}, {start: 228, end: 24}, + {start: 25, end: 130}, {start: 130, end: 226}, {start: 226, end: 25}, + {start: 23, end: 24}, {start: 24, end: 229}, {start: 229, end: 23}, + {start: 22, end: 23}, {start: 23, end: 230}, {start: 230, end: 22}, + {start: 26, end: 22}, {start: 22, end: 231}, {start: 231, end: 26}, + {start: 112, end: 26}, {start: 26, end: 232}, {start: 232, end: 112}, + {start: 189, end: 190}, {start: 190, end: 243}, {start: 243, end: 189}, + {start: 221, end: 56}, {start: 56, end: 190}, {start: 190, end: 221}, + {start: 28, end: 56}, {start: 56, end: 221}, {start: 221, end: 28}, + {start: 27, end: 28}, {start: 28, end: 222}, {start: 222, end: 27}, + {start: 29, end: 27}, {start: 27, end: 223}, {start: 223, end: 29}, + {start: 30, end: 29}, {start: 29, end: 224}, {start: 224, end: 30}, + {start: 247, end: 30}, {start: 30, end: 225}, {start: 225, end: 247}, + {start: 238, end: 79}, {start: 79, end: 20}, {start: 20, end: 238}, + {start: 166, end: 59}, {start: 59, end: 75}, {start: 75, end: 166}, + {start: 60, end: 75}, {start: 75, end: 240}, {start: 240, end: 60}, + {start: 147, end: 177}, {start: 177, end: 215}, {start: 215, end: 147}, + {start: 20, end: 79}, {start: 79, end: 166}, {start: 166, end: 20}, + {start: 187, end: 147}, {start: 147, end: 213}, {start: 213, end: 187}, + {start: 112, end: 233}, {start: 233, end: 244}, {start: 244, end: 112}, + {start: 233, end: 128}, {start: 128, end: 245}, {start: 245, end: 233}, + {start: 128, end: 114}, {start: 114, end: 188}, {start: 188, end: 128}, + {start: 114, end: 217}, {start: 217, end: 174}, {start: 174, end: 114}, + {start: 131, end: 115}, {start: 115, end: 220}, {start: 220, end: 131}, + {start: 217, end: 198}, {start: 198, end: 236}, {start: 236, end: 217}, + {start: 198, end: 131}, {start: 131, end: 134}, {start: 134, end: 198}, + {start: 177, end: 132}, {start: 132, end: 58}, {start: 58, end: 177}, + {start: 143, end: 35}, {start: 35, end: 124}, {start: 124, end: 143}, + {start: 110, end: 163}, {start: 163, end: 7}, {start: 7, end: 110}, + {start: 228, end: 110}, {start: 110, end: 25}, {start: 25, end: 228}, + {start: 356, end: 389}, {start: 389, end: 368}, {start: 368, end: 356}, + {start: 11, end: 302}, {start: 302, end: 267}, {start: 267, end: 11}, + {start: 452, end: 350}, {start: 350, end: 349}, {start: 349, end: 452}, + {start: 302, end: 303}, {start: 303, end: 269}, {start: 269, end: 302}, + {start: 357, end: 343}, {start: 343, end: 277}, {start: 277, end: 357}, + {start: 452, end: 453}, {start: 453, end: 357}, {start: 357, end: 452}, + {start: 333, end: 332}, {start: 332, end: 297}, {start: 297, end: 333}, + {start: 175, end: 152}, {start: 152, end: 377}, {start: 377, end: 175}, + {start: 347, end: 348}, {start: 348, end: 330}, {start: 330, end: 347}, + {start: 303, end: 304}, {start: 304, end: 270}, {start: 270, end: 303}, + {start: 9, end: 336}, {start: 336, end: 337}, {start: 337, end: 9}, + {start: 278, end: 279}, {start: 279, end: 360}, {start: 360, end: 278}, + {start: 418, end: 262}, {start: 262, end: 431}, {start: 431, end: 418}, + {start: 304, end: 408}, {start: 408, end: 409}, {start: 409, end: 304}, + {start: 310, end: 415}, {start: 415, end: 407}, {start: 407, end: 310}, + {start: 270, end: 409}, {start: 409, end: 410}, {start: 410, end: 270}, + {start: 450, end: 348}, {start: 348, end: 347}, {start: 347, end: 450}, + {start: 422, end: 430}, {start: 430, end: 434}, {start: 434, end: 422}, + {start: 313, end: 314}, {start: 314, end: 17}, {start: 17, end: 313}, + {start: 306, end: 307}, {start: 307, end: 375}, {start: 375, end: 306}, + {start: 387, end: 388}, {start: 388, end: 260}, {start: 260, end: 387}, + {start: 286, end: 414}, {start: 414, end: 398}, {start: 398, end: 286}, + {start: 335, end: 406}, {start: 406, end: 418}, {start: 418, end: 335}, + {start: 364, end: 367}, {start: 367, end: 416}, {start: 416, end: 364}, + {start: 423, end: 358}, {start: 358, end: 327}, {start: 327, end: 423}, + {start: 251, end: 284}, {start: 284, end: 298}, {start: 298, end: 251}, + {start: 281, end: 5}, {start: 5, end: 4}, {start: 4, end: 281}, + {start: 373, end: 374}, {start: 374, end: 253}, {start: 253, end: 373}, + {start: 307, end: 320}, {start: 320, end: 321}, {start: 321, end: 307}, + {start: 425, end: 427}, {start: 427, end: 411}, {start: 411, end: 425}, + {start: 421, end: 313}, {start: 313, end: 18}, {start: 18, end: 421}, + {start: 321, end: 405}, {start: 405, end: 406}, {start: 406, end: 321}, + {start: 320, end: 404}, {start: 404, end: 405}, {start: 405, end: 320}, + {start: 315, end: 16}, {start: 16, end: 17}, {start: 17, end: 315}, + {start: 426, end: 425}, {start: 425, end: 266}, {start: 266, end: 426}, + {start: 377, end: 400}, {start: 400, end: 369}, {start: 369, end: 377}, + {start: 322, end: 391}, {start: 391, end: 269}, {start: 269, end: 322}, + {start: 417, end: 465}, {start: 465, end: 464}, {start: 464, end: 417}, + {start: 386, end: 257}, {start: 257, end: 258}, {start: 258, end: 386}, + {start: 466, end: 260}, {start: 260, end: 388}, {start: 388, end: 466}, + {start: 456, end: 399}, {start: 399, end: 419}, {start: 419, end: 456}, + {start: 284, end: 332}, {start: 332, end: 333}, {start: 333, end: 284}, + {start: 417, end: 285}, {start: 285, end: 8}, {start: 8, end: 417}, + {start: 346, end: 340}, {start: 340, end: 261}, {start: 261, end: 346}, + {start: 413, end: 441}, {start: 441, end: 285}, {start: 285, end: 413}, + {start: 327, end: 460}, {start: 460, end: 328}, {start: 328, end: 327}, + {start: 355, end: 371}, {start: 371, end: 329}, {start: 329, end: 355}, + {start: 392, end: 439}, {start: 439, end: 438}, {start: 438, end: 392}, + {start: 382, end: 341}, {start: 341, end: 256}, {start: 256, end: 382}, + {start: 429, end: 420}, {start: 420, end: 360}, {start: 360, end: 429}, + {start: 364, end: 394}, {start: 394, end: 379}, {start: 379, end: 364}, + {start: 277, end: 343}, {start: 343, end: 437}, {start: 437, end: 277}, + {start: 443, end: 444}, {start: 444, end: 283}, {start: 283, end: 443}, + {start: 275, end: 440}, {start: 440, end: 363}, {start: 363, end: 275}, + {start: 431, end: 262}, {start: 262, end: 369}, {start: 369, end: 431}, + {start: 297, end: 338}, {start: 338, end: 337}, {start: 337, end: 297}, + {start: 273, end: 375}, {start: 375, end: 321}, {start: 321, end: 273}, + {start: 450, end: 451}, {start: 451, end: 349}, {start: 349, end: 450}, + {start: 446, end: 342}, {start: 342, end: 467}, {start: 467, end: 446}, + {start: 293, end: 334}, {start: 334, end: 282}, {start: 282, end: 293}, + {start: 458, end: 461}, {start: 461, end: 462}, {start: 462, end: 458}, + {start: 276, end: 353}, {start: 353, end: 383}, {start: 383, end: 276}, + {start: 308, end: 324}, {start: 324, end: 325}, {start: 325, end: 308}, + {start: 276, end: 300}, {start: 300, end: 293}, {start: 293, end: 276}, + {start: 372, end: 345}, {start: 345, end: 447}, {start: 447, end: 372}, + {start: 352, end: 345}, {start: 345, end: 340}, {start: 340, end: 352}, + {start: 274, end: 1}, {start: 1, end: 19}, {start: 19, end: 274}, + {start: 456, end: 248}, {start: 248, end: 281}, {start: 281, end: 456}, + {start: 436, end: 427}, {start: 427, end: 425}, {start: 425, end: 436}, + {start: 381, end: 256}, {start: 256, end: 252}, {start: 252, end: 381}, + {start: 269, end: 391}, {start: 391, end: 393}, {start: 393, end: 269}, + {start: 200, end: 199}, {start: 199, end: 428}, {start: 428, end: 200}, + {start: 266, end: 330}, {start: 330, end: 329}, {start: 329, end: 266}, + {start: 287, end: 273}, {start: 273, end: 422}, {start: 422, end: 287}, + {start: 250, end: 462}, {start: 462, end: 328}, {start: 328, end: 250}, + {start: 258, end: 286}, {start: 286, end: 384}, {start: 384, end: 258}, + {start: 265, end: 353}, {start: 353, end: 342}, {start: 342, end: 265}, + {start: 387, end: 259}, {start: 259, end: 257}, {start: 257, end: 387}, + {start: 424, end: 431}, {start: 431, end: 430}, {start: 430, end: 424}, + {start: 342, end: 353}, {start: 353, end: 276}, {start: 276, end: 342}, + {start: 273, end: 335}, {start: 335, end: 424}, {start: 424, end: 273}, + {start: 292, end: 325}, {start: 325, end: 307}, {start: 307, end: 292}, + {start: 366, end: 447}, {start: 447, end: 345}, {start: 345, end: 366}, + {start: 271, end: 303}, {start: 303, end: 302}, {start: 302, end: 271}, + {start: 423, end: 266}, {start: 266, end: 371}, {start: 371, end: 423}, + {start: 294, end: 455}, {start: 455, end: 460}, {start: 460, end: 294}, + {start: 279, end: 278}, {start: 278, end: 294}, {start: 294, end: 279}, + {start: 271, end: 272}, {start: 272, end: 304}, {start: 304, end: 271}, + {start: 432, end: 434}, {start: 434, end: 427}, {start: 427, end: 432}, + {start: 272, end: 407}, {start: 407, end: 408}, {start: 408, end: 272}, + {start: 394, end: 430}, {start: 430, end: 431}, {start: 431, end: 394}, + {start: 395, end: 369}, {start: 369, end: 400}, {start: 400, end: 395}, + {start: 334, end: 333}, {start: 333, end: 299}, {start: 299, end: 334}, + {start: 351, end: 417}, {start: 417, end: 168}, {start: 168, end: 351}, + {start: 352, end: 280}, {start: 280, end: 411}, {start: 411, end: 352}, + {start: 325, end: 319}, {start: 319, end: 320}, {start: 320, end: 325}, + {start: 295, end: 296}, {start: 296, end: 336}, {start: 336, end: 295}, + {start: 319, end: 403}, {start: 403, end: 404}, {start: 404, end: 319}, + {start: 330, end: 348}, {start: 348, end: 349}, {start: 349, end: 330}, + {start: 293, end: 298}, {start: 298, end: 333}, {start: 333, end: 293}, + {start: 323, end: 454}, {start: 454, end: 447}, {start: 447, end: 323}, + {start: 15, end: 16}, {start: 16, end: 315}, {start: 315, end: 15}, + {start: 358, end: 429}, {start: 429, end: 279}, {start: 279, end: 358}, + {start: 14, end: 15}, {start: 15, end: 316}, {start: 316, end: 14}, + {start: 285, end: 336}, {start: 336, end: 9}, {start: 9, end: 285}, + {start: 329, end: 349}, {start: 349, end: 350}, {start: 350, end: 329}, + {start: 374, end: 380}, {start: 380, end: 252}, {start: 252, end: 374}, + {start: 318, end: 402}, {start: 402, end: 403}, {start: 403, end: 318}, + {start: 6, end: 197}, {start: 197, end: 419}, {start: 419, end: 6}, + {start: 318, end: 319}, {start: 319, end: 325}, {start: 325, end: 318}, + {start: 367, end: 364}, {start: 364, end: 365}, {start: 365, end: 367}, + {start: 435, end: 367}, {start: 367, end: 397}, {start: 397, end: 435}, + {start: 344, end: 438}, {start: 438, end: 439}, {start: 439, end: 344}, + {start: 272, end: 271}, {start: 271, end: 311}, {start: 311, end: 272}, + {start: 195, end: 5}, {start: 5, end: 281}, {start: 281, end: 195}, + {start: 273, end: 287}, {start: 287, end: 291}, {start: 291, end: 273}, + {start: 396, end: 428}, {start: 428, end: 199}, {start: 199, end: 396}, + {start: 311, end: 271}, {start: 271, end: 268}, {start: 268, end: 311}, + {start: 283, end: 444}, {start: 444, end: 445}, {start: 445, end: 283}, + {start: 373, end: 254}, {start: 254, end: 339}, {start: 339, end: 373}, + {start: 282, end: 334}, {start: 334, end: 296}, {start: 296, end: 282}, + {start: 449, end: 347}, {start: 347, end: 346}, {start: 346, end: 449}, + {start: 264, end: 447}, {start: 447, end: 454}, {start: 454, end: 264}, + {start: 336, end: 296}, {start: 296, end: 299}, {start: 299, end: 336}, + {start: 338, end: 10}, {start: 10, end: 151}, {start: 151, end: 338}, + {start: 278, end: 439}, {start: 439, end: 455}, {start: 455, end: 278}, + {start: 292, end: 407}, {start: 407, end: 415}, {start: 415, end: 292}, + {start: 358, end: 371}, {start: 371, end: 355}, {start: 355, end: 358}, + {start: 340, end: 345}, {start: 345, end: 372}, {start: 372, end: 340}, + {start: 346, end: 347}, {start: 347, end: 280}, {start: 280, end: 346}, + {start: 442, end: 443}, {start: 443, end: 282}, {start: 282, end: 442}, + {start: 19, end: 94}, {start: 94, end: 370}, {start: 370, end: 19}, + {start: 441, end: 442}, {start: 442, end: 295}, {start: 295, end: 441}, + {start: 248, end: 419}, {start: 419, end: 197}, {start: 197, end: 248}, + {start: 263, end: 255}, {start: 255, end: 359}, {start: 359, end: 263}, + {start: 440, end: 275}, {start: 275, end: 274}, {start: 274, end: 440}, + {start: 300, end: 383}, {start: 383, end: 368}, {start: 368, end: 300}, + {start: 351, end: 412}, {start: 412, end: 465}, {start: 465, end: 351}, + {start: 263, end: 467}, {start: 467, end: 466}, {start: 466, end: 263}, + {start: 301, end: 368}, {start: 368, end: 389}, {start: 389, end: 301}, + {start: 395, end: 378}, {start: 378, end: 379}, {start: 379, end: 395}, + {start: 412, end: 351}, {start: 351, end: 419}, {start: 419, end: 412}, + {start: 436, end: 426}, {start: 426, end: 322}, {start: 322, end: 436}, + {start: 2, end: 164}, {start: 164, end: 393}, {start: 393, end: 2}, + {start: 370, end: 462}, {start: 462, end: 461}, {start: 461, end: 370}, + {start: 164, end: 0}, {start: 0, end: 267}, {start: 267, end: 164}, + {start: 302, end: 11}, {start: 11, end: 12}, {start: 12, end: 302}, + {start: 268, end: 12}, {start: 12, end: 13}, {start: 13, end: 268}, + {start: 293, end: 300}, {start: 300, end: 301}, {start: 301, end: 293}, + {start: 446, end: 261}, {start: 261, end: 340}, {start: 340, end: 446}, + {start: 330, end: 266}, {start: 266, end: 425}, {start: 425, end: 330}, + {start: 426, end: 423}, {start: 423, end: 391}, {start: 391, end: 426}, + {start: 429, end: 355}, {start: 355, end: 437}, {start: 437, end: 429}, + {start: 391, end: 327}, {start: 327, end: 326}, {start: 326, end: 391}, + {start: 440, end: 457}, {start: 457, end: 438}, {start: 438, end: 440}, + {start: 341, end: 382}, {start: 382, end: 362}, {start: 362, end: 341}, + {start: 459, end: 457}, {start: 457, end: 461}, {start: 461, end: 459}, + {start: 434, end: 430}, {start: 430, end: 394}, {start: 394, end: 434}, + {start: 414, end: 463}, {start: 463, end: 362}, {start: 362, end: 414}, + {start: 396, end: 369}, {start: 369, end: 262}, {start: 262, end: 396}, + {start: 354, end: 461}, {start: 461, end: 457}, {start: 457, end: 354}, + {start: 316, end: 403}, {start: 403, end: 402}, {start: 402, end: 316}, + {start: 315, end: 404}, {start: 404, end: 403}, {start: 403, end: 315}, + {start: 314, end: 405}, {start: 405, end: 404}, {start: 404, end: 314}, + {start: 313, end: 406}, {start: 406, end: 405}, {start: 405, end: 313}, + {start: 421, end: 418}, {start: 418, end: 406}, {start: 406, end: 421}, + {start: 366, end: 401}, {start: 401, end: 361}, {start: 361, end: 366}, + {start: 306, end: 408}, {start: 408, end: 407}, {start: 407, end: 306}, + {start: 291, end: 409}, {start: 409, end: 408}, {start: 408, end: 291}, + {start: 287, end: 410}, {start: 410, end: 409}, {start: 409, end: 287}, + {start: 432, end: 436}, {start: 436, end: 410}, {start: 410, end: 432}, + {start: 434, end: 416}, {start: 416, end: 411}, {start: 411, end: 434}, + {start: 264, end: 368}, {start: 368, end: 383}, {start: 383, end: 264}, + {start: 309, end: 438}, {start: 438, end: 457}, {start: 457, end: 309}, + {start: 352, end: 376}, {start: 376, end: 401}, {start: 401, end: 352}, + {start: 274, end: 275}, {start: 275, end: 4}, {start: 4, end: 274}, + {start: 421, end: 428}, {start: 428, end: 262}, {start: 262, end: 421}, + {start: 294, end: 327}, {start: 327, end: 358}, {start: 358, end: 294}, + {start: 433, end: 416}, {start: 416, end: 367}, {start: 367, end: 433}, + {start: 289, end: 455}, {start: 455, end: 439}, {start: 439, end: 289}, + {start: 462, end: 370}, {start: 370, end: 326}, {start: 326, end: 462}, + {start: 2, end: 326}, {start: 326, end: 370}, {start: 370, end: 2}, + {start: 305, end: 460}, {start: 460, end: 455}, {start: 455, end: 305}, + {start: 254, end: 449}, {start: 449, end: 448}, {start: 448, end: 254}, + {start: 255, end: 261}, {start: 261, end: 446}, {start: 446, end: 255}, + {start: 253, end: 450}, {start: 450, end: 449}, {start: 449, end: 253}, + {start: 252, end: 451}, {start: 451, end: 450}, {start: 450, end: 252}, + {start: 256, end: 452}, {start: 452, end: 451}, {start: 451, end: 256}, + {start: 341, end: 453}, {start: 453, end: 452}, {start: 452, end: 341}, + {start: 413, end: 464}, {start: 464, end: 463}, {start: 463, end: 413}, + {start: 441, end: 413}, {start: 413, end: 414}, {start: 414, end: 441}, + {start: 258, end: 442}, {start: 442, end: 441}, {start: 441, end: 258}, + {start: 257, end: 443}, {start: 443, end: 442}, {start: 442, end: 257}, + {start: 259, end: 444}, {start: 444, end: 443}, {start: 443, end: 259}, + {start: 260, end: 445}, {start: 445, end: 444}, {start: 444, end: 260}, + {start: 467, end: 342}, {start: 342, end: 445}, {start: 445, end: 467}, + {start: 459, end: 458}, {start: 458, end: 250}, {start: 250, end: 459}, + {start: 289, end: 392}, {start: 392, end: 290}, {start: 290, end: 289}, + {start: 290, end: 328}, {start: 328, end: 460}, {start: 460, end: 290}, + {start: 376, end: 433}, {start: 433, end: 435}, {start: 435, end: 376}, + {start: 250, end: 290}, {start: 290, end: 392}, {start: 392, end: 250}, + {start: 411, end: 416}, {start: 416, end: 433}, {start: 433, end: 411}, + {start: 341, end: 463}, {start: 463, end: 464}, {start: 464, end: 341}, + {start: 453, end: 464}, {start: 464, end: 465}, {start: 465, end: 453}, + {start: 357, end: 465}, {start: 465, end: 412}, {start: 412, end: 357}, + {start: 343, end: 412}, {start: 412, end: 399}, {start: 399, end: 343}, + {start: 360, end: 363}, {start: 363, end: 440}, {start: 440, end: 360}, + {start: 437, end: 399}, {start: 399, end: 456}, {start: 456, end: 437}, + {start: 420, end: 456}, {start: 456, end: 363}, {start: 363, end: 420}, + {start: 401, end: 435}, {start: 435, end: 288}, {start: 288, end: 401}, + {start: 372, end: 383}, {start: 383, end: 353}, {start: 353, end: 372}, + {start: 339, end: 255}, {start: 255, end: 249}, {start: 249, end: 339}, + {start: 448, end: 261}, {start: 261, end: 255}, {start: 255, end: 448}, + {start: 133, end: 243}, {start: 243, end: 190}, {start: 190, end: 133}, + {start: 133, end: 155}, {start: 155, end: 112}, {start: 112, end: 133}, + {start: 33, end: 246}, {start: 246, end: 247}, {start: 247, end: 33}, + {start: 33, end: 130}, {start: 130, end: 25}, {start: 25, end: 33}, + {start: 398, end: 384}, {start: 384, end: 286}, {start: 286, end: 398}, + {start: 362, end: 398}, {start: 398, end: 414}, {start: 414, end: 362}, + {start: 362, end: 463}, {start: 463, end: 341}, {start: 341, end: 362}, + {start: 263, end: 359}, {start: 359, end: 467}, {start: 467, end: 263}, + {start: 263, end: 249}, {start: 249, end: 255}, {start: 255, end: 263}, + {start: 466, end: 467}, {start: 467, end: 260}, {start: 260, end: 466}, + {start: 75, end: 60}, {start: 60, end: 166}, {start: 166, end: 75}, + {start: 238, end: 239}, {start: 239, end: 79}, {start: 79, end: 238}, + {start: 162, end: 127}, {start: 127, end: 139}, {start: 139, end: 162}, + {start: 72, end: 11}, {start: 11, end: 37}, {start: 37, end: 72}, + {start: 121, end: 232}, {start: 232, end: 120}, {start: 120, end: 121}, + {start: 73, end: 72}, {start: 72, end: 39}, {start: 39, end: 73}, + {start: 114, end: 128}, {start: 128, end: 47}, {start: 47, end: 114}, + {start: 233, end: 232}, {start: 232, end: 128}, {start: 128, end: 233}, + {start: 103, end: 104}, {start: 104, end: 67}, {start: 67, end: 103}, + {start: 152, end: 175}, {start: 175, end: 148}, {start: 148, end: 152}, + {start: 119, end: 118}, {start: 118, end: 101}, {start: 101, end: 119}, + {start: 74, end: 73}, {start: 73, end: 40}, {start: 40, end: 74}, + {start: 107, end: 9}, {start: 9, end: 108}, {start: 108, end: 107}, + {start: 49, end: 48}, {start: 48, end: 131}, {start: 131, end: 49}, + {start: 32, end: 194}, {start: 194, end: 211}, {start: 211, end: 32}, + {start: 184, end: 74}, {start: 74, end: 185}, {start: 185, end: 184}, + {start: 191, end: 80}, {start: 80, end: 183}, {start: 183, end: 191}, + {start: 185, end: 40}, {start: 40, end: 186}, {start: 186, end: 185}, + {start: 119, end: 230}, {start: 230, end: 118}, {start: 118, end: 119}, + {start: 210, end: 202}, {start: 202, end: 214}, {start: 214, end: 210}, + {start: 84, end: 83}, {start: 83, end: 17}, {start: 17, end: 84}, + {start: 77, end: 76}, {start: 76, end: 146}, {start: 146, end: 77}, + {start: 161, end: 160}, {start: 160, end: 30}, {start: 30, end: 161}, + {start: 190, end: 56}, {start: 56, end: 173}, {start: 173, end: 190}, + {start: 182, end: 106}, {start: 106, end: 194}, {start: 194, end: 182}, + {start: 138, end: 135}, {start: 135, end: 192}, {start: 192, end: 138}, + {start: 129, end: 203}, {start: 203, end: 98}, {start: 98, end: 129}, + {start: 54, end: 21}, {start: 21, end: 68}, {start: 68, end: 54}, + {start: 5, end: 51}, {start: 51, end: 4}, {start: 4, end: 5}, + {start: 145, end: 144}, {start: 144, end: 23}, {start: 23, end: 145}, + {start: 90, end: 77}, {start: 77, end: 91}, {start: 91, end: 90}, + {start: 207, end: 205}, {start: 205, end: 187}, {start: 187, end: 207}, + {start: 83, end: 201}, {start: 201, end: 18}, {start: 18, end: 83}, + {start: 181, end: 91}, {start: 91, end: 182}, {start: 182, end: 181}, + {start: 180, end: 90}, {start: 90, end: 181}, {start: 181, end: 180}, + {start: 16, end: 85}, {start: 85, end: 17}, {start: 17, end: 16}, + {start: 205, end: 206}, {start: 206, end: 36}, {start: 36, end: 205}, + {start: 176, end: 148}, {start: 148, end: 140}, {start: 140, end: 176}, + {start: 165, end: 92}, {start: 92, end: 39}, {start: 39, end: 165}, + {start: 245, end: 193}, {start: 193, end: 244}, {start: 244, end: 245}, + {start: 27, end: 159}, {start: 159, end: 28}, {start: 28, end: 27}, + {start: 30, end: 247}, {start: 247, end: 161}, {start: 161, end: 30}, + {start: 174, end: 236}, {start: 236, end: 196}, {start: 196, end: 174}, + {start: 103, end: 54}, {start: 54, end: 104}, {start: 104, end: 103}, + {start: 55, end: 193}, {start: 193, end: 8}, {start: 8, end: 55}, + {start: 111, end: 117}, {start: 117, end: 31}, {start: 31, end: 111}, + {start: 221, end: 189}, {start: 189, end: 55}, {start: 55, end: 221}, + {start: 240, end: 98}, {start: 98, end: 99}, {start: 99, end: 240}, + {start: 142, end: 126}, {start: 126, end: 100}, {start: 100, end: 142}, + {start: 219, end: 166}, {start: 166, end: 218}, {start: 218, end: 219}, + {start: 112, end: 155}, {start: 155, end: 26}, {start: 26, end: 112}, + {start: 198, end: 209}, {start: 209, end: 131}, {start: 131, end: 198}, + {start: 169, end: 135}, {start: 135, end: 150}, {start: 150, end: 169}, + {start: 114, end: 47}, {start: 47, end: 217}, {start: 217, end: 114}, + {start: 224, end: 223}, {start: 223, end: 53}, {start: 53, end: 224}, + {start: 220, end: 45}, {start: 45, end: 134}, {start: 134, end: 220}, + {start: 32, end: 211}, {start: 211, end: 140}, {start: 140, end: 32}, + {start: 109, end: 67}, {start: 67, end: 108}, {start: 108, end: 109}, + {start: 146, end: 43}, {start: 43, end: 91}, {start: 91, end: 146}, + {start: 231, end: 230}, {start: 230, end: 120}, {start: 120, end: 231}, + {start: 113, end: 226}, {start: 226, end: 247}, {start: 247, end: 113}, + {start: 105, end: 63}, {start: 63, end: 52}, {start: 52, end: 105}, + {start: 241, end: 238}, {start: 238, end: 242}, {start: 242, end: 241}, + {start: 124, end: 46}, {start: 46, end: 156}, {start: 156, end: 124}, + {start: 95, end: 78}, {start: 78, end: 96}, {start: 96, end: 95}, + {start: 70, end: 46}, {start: 46, end: 63}, {start: 63, end: 70}, + {start: 116, end: 143}, {start: 143, end: 227}, {start: 227, end: 116}, + {start: 116, end: 123}, {start: 123, end: 111}, {start: 111, end: 116}, + {start: 1, end: 44}, {start: 44, end: 19}, {start: 19, end: 1}, + {start: 3, end: 236}, {start: 236, end: 51}, {start: 51, end: 3}, + {start: 207, end: 216}, {start: 216, end: 205}, {start: 205, end: 207}, + {start: 26, end: 154}, {start: 154, end: 22}, {start: 22, end: 26}, + {start: 165, end: 39}, {start: 39, end: 167}, {start: 167, end: 165}, + {start: 199, end: 200}, {start: 200, end: 208}, {start: 208, end: 199}, + {start: 101, end: 36}, {start: 36, end: 100}, {start: 100, end: 101}, + {start: 43, end: 57}, {start: 57, end: 202}, {start: 202, end: 43}, + {start: 242, end: 20}, {start: 20, end: 99}, {start: 99, end: 242}, + {start: 56, end: 28}, {start: 28, end: 157}, {start: 157, end: 56}, + {start: 124, end: 35}, {start: 35, end: 113}, {start: 113, end: 124}, + {start: 29, end: 160}, {start: 160, end: 27}, {start: 27, end: 29}, + {start: 211, end: 204}, {start: 204, end: 210}, {start: 210, end: 211}, + {start: 124, end: 113}, {start: 113, end: 46}, {start: 46, end: 124}, + {start: 106, end: 43}, {start: 43, end: 204}, {start: 204, end: 106}, + {start: 96, end: 62}, {start: 62, end: 77}, {start: 77, end: 96}, + {start: 227, end: 137}, {start: 137, end: 116}, {start: 116, end: 227}, + {start: 73, end: 41}, {start: 41, end: 72}, {start: 72, end: 73}, + {start: 36, end: 203}, {start: 203, end: 142}, {start: 142, end: 36}, + {start: 235, end: 64}, {start: 64, end: 240}, {start: 240, end: 235}, + {start: 48, end: 49}, {start: 49, end: 64}, {start: 64, end: 48}, + {start: 42, end: 41}, {start: 41, end: 74}, {start: 74, end: 42}, + {start: 214, end: 212}, {start: 212, end: 207}, {start: 207, end: 214}, + {start: 183, end: 42}, {start: 42, end: 184}, {start: 184, end: 183}, + {start: 210, end: 169}, {start: 169, end: 211}, {start: 211, end: 210}, + {start: 140, end: 170}, {start: 170, end: 176}, {start: 176, end: 140}, + {start: 104, end: 105}, {start: 105, end: 69}, {start: 69, end: 104}, + {start: 193, end: 122}, {start: 122, end: 168}, {start: 168, end: 193}, + {start: 50, end: 123}, {start: 123, end: 187}, {start: 187, end: 50}, + {start: 89, end: 96}, {start: 96, end: 90}, {start: 90, end: 89}, + {start: 66, end: 65}, {start: 65, end: 107}, {start: 107, end: 66}, + {start: 179, end: 89}, {start: 89, end: 180}, {start: 180, end: 179}, + {start: 119, end: 101}, {start: 101, end: 120}, {start: 120, end: 119}, + {start: 68, end: 63}, {start: 63, end: 104}, {start: 104, end: 68}, + {start: 234, end: 93}, {start: 93, end: 227}, {start: 227, end: 234}, + {start: 16, end: 15}, {start: 15, end: 85}, {start: 85, end: 16}, + {start: 209, end: 129}, {start: 129, end: 49}, {start: 49, end: 209}, + {start: 15, end: 14}, {start: 14, end: 86}, {start: 86, end: 15}, + {start: 107, end: 55}, {start: 55, end: 9}, {start: 9, end: 107}, + {start: 120, end: 100}, {start: 100, end: 121}, {start: 121, end: 120}, + {start: 153, end: 145}, {start: 145, end: 22}, {start: 22, end: 153}, + {start: 178, end: 88}, {start: 88, end: 179}, {start: 179, end: 178}, + {start: 197, end: 6}, {start: 6, end: 196}, {start: 196, end: 197}, + {start: 89, end: 88}, {start: 88, end: 96}, {start: 96, end: 89}, + {start: 135, end: 138}, {start: 138, end: 136}, {start: 136, end: 135}, + {start: 138, end: 215}, {start: 215, end: 172}, {start: 172, end: 138}, + {start: 218, end: 115}, {start: 115, end: 219}, {start: 219, end: 218}, + {start: 41, end: 42}, {start: 42, end: 81}, {start: 81, end: 41}, + {start: 5, end: 195}, {start: 195, end: 51}, {start: 51, end: 5}, + {start: 57, end: 43}, {start: 43, end: 61}, {start: 61, end: 57}, + {start: 208, end: 171}, {start: 171, end: 199}, {start: 199, end: 208}, + {start: 41, end: 81}, {start: 81, end: 38}, {start: 38, end: 41}, + {start: 224, end: 53}, {start: 53, end: 225}, {start: 225, end: 224}, + {start: 24, end: 144}, {start: 144, end: 110}, {start: 110, end: 24}, + {start: 105, end: 52}, {start: 52, end: 66}, {start: 66, end: 105}, + {start: 118, end: 229}, {start: 229, end: 117}, {start: 117, end: 118}, + {start: 227, end: 34}, {start: 34, end: 234}, {start: 234, end: 227}, + {start: 66, end: 107}, {start: 107, end: 69}, {start: 69, end: 66}, + {start: 10, end: 109}, {start: 109, end: 151}, {start: 151, end: 10}, + {start: 219, end: 48}, {start: 48, end: 235}, {start: 235, end: 219}, + {start: 183, end: 62}, {start: 62, end: 191}, {start: 191, end: 183}, + {start: 142, end: 129}, {start: 129, end: 126}, {start: 126, end: 142}, + {start: 116, end: 111}, {start: 111, end: 143}, {start: 143, end: 116}, + {start: 118, end: 117}, {start: 117, end: 50}, {start: 50, end: 118}, + {start: 223, end: 222}, {start: 222, end: 52}, {start: 52, end: 223}, + {start: 94, end: 19}, {start: 19, end: 141}, {start: 141, end: 94}, + {start: 222, end: 221}, {start: 221, end: 65}, {start: 65, end: 222}, + {start: 196, end: 3}, {start: 3, end: 197}, {start: 197, end: 196}, + {start: 45, end: 220}, {start: 220, end: 44}, {start: 44, end: 45}, + {start: 156, end: 70}, {start: 70, end: 139}, {start: 139, end: 156}, + {start: 188, end: 122}, {start: 122, end: 245}, {start: 245, end: 188}, + {start: 139, end: 71}, {start: 71, end: 162}, {start: 162, end: 139}, + {start: 149, end: 170}, {start: 170, end: 150}, {start: 150, end: 149}, + {start: 122, end: 188}, {start: 188, end: 196}, {start: 196, end: 122}, + {start: 206, end: 216}, {start: 216, end: 92}, {start: 92, end: 206}, + {start: 164, end: 2}, {start: 2, end: 167}, {start: 167, end: 164}, + {start: 242, end: 141}, {start: 141, end: 241}, {start: 241, end: 242}, + {start: 0, end: 164}, {start: 164, end: 37}, {start: 37, end: 0}, + {start: 11, end: 72}, {start: 72, end: 12}, {start: 12, end: 11}, + {start: 12, end: 38}, {start: 38, end: 13}, {start: 13, end: 12}, + {start: 70, end: 63}, {start: 63, end: 71}, {start: 71, end: 70}, + {start: 31, end: 226}, {start: 226, end: 111}, {start: 111, end: 31}, + {start: 36, end: 101}, {start: 101, end: 205}, {start: 205, end: 36}, + {start: 203, end: 206}, {start: 206, end: 165}, {start: 165, end: 203}, + {start: 126, end: 209}, {start: 209, end: 217}, {start: 217, end: 126}, + {start: 98, end: 165}, {start: 165, end: 97}, {start: 97, end: 98}, + {start: 237, end: 220}, {start: 220, end: 218}, {start: 218, end: 237}, + {start: 237, end: 239}, {start: 239, end: 241}, {start: 241, end: 237}, + {start: 210, end: 214}, {start: 214, end: 169}, {start: 169, end: 210}, + {start: 140, end: 171}, {start: 171, end: 32}, {start: 32, end: 140}, + {start: 241, end: 125}, {start: 125, end: 237}, {start: 237, end: 241}, + {start: 179, end: 86}, {start: 86, end: 178}, {start: 178, end: 179}, + {start: 180, end: 85}, {start: 85, end: 179}, {start: 179, end: 180}, + {start: 181, end: 84}, {start: 84, end: 180}, {start: 180, end: 181}, + {start: 182, end: 83}, {start: 83, end: 181}, {start: 181, end: 182}, + {start: 194, end: 201}, {start: 201, end: 182}, {start: 182, end: 194}, + {start: 177, end: 137}, {start: 137, end: 132}, {start: 132, end: 177}, + {start: 184, end: 76}, {start: 76, end: 183}, {start: 183, end: 184}, + {start: 185, end: 61}, {start: 61, end: 184}, {start: 184, end: 185}, + {start: 186, end: 57}, {start: 57, end: 185}, {start: 185, end: 186}, + {start: 216, end: 212}, {start: 212, end: 186}, {start: 186, end: 216}, + {start: 192, end: 214}, {start: 214, end: 187}, {start: 187, end: 192}, + {start: 139, end: 34}, {start: 34, end: 156}, {start: 156, end: 139}, + {start: 218, end: 79}, {start: 79, end: 237}, {start: 237, end: 218}, + {start: 147, end: 123}, {start: 123, end: 177}, {start: 177, end: 147}, + {start: 45, end: 44}, {start: 44, end: 4}, {start: 4, end: 45}, + {start: 208, end: 201}, {start: 201, end: 32}, {start: 32, end: 208}, + {start: 98, end: 64}, {start: 64, end: 129}, {start: 129, end: 98}, + {start: 192, end: 213}, {start: 213, end: 138}, {start: 138, end: 192}, + {start: 235, end: 59}, {start: 59, end: 219}, {start: 219, end: 235}, + {start: 141, end: 242}, {start: 242, end: 97}, {start: 97, end: 141}, + {start: 97, end: 2}, {start: 2, end: 141}, {start: 141, end: 97}, + {start: 240, end: 75}, {start: 75, end: 235}, {start: 235, end: 240}, + {start: 229, end: 24}, {start: 24, end: 228}, {start: 228, end: 229}, + {start: 31, end: 25}, {start: 25, end: 226}, {start: 226, end: 31}, + {start: 230, end: 23}, {start: 23, end: 229}, {start: 229, end: 230}, + {start: 231, end: 22}, {start: 22, end: 230}, {start: 230, end: 231}, + {start: 232, end: 26}, {start: 26, end: 231}, {start: 231, end: 232}, + {start: 233, end: 112}, {start: 112, end: 232}, {start: 232, end: 233}, + {start: 244, end: 189}, {start: 189, end: 243}, {start: 243, end: 244}, + {start: 189, end: 221}, {start: 221, end: 190}, {start: 190, end: 189}, + {start: 222, end: 28}, {start: 28, end: 221}, {start: 221, end: 222}, + {start: 223, end: 27}, {start: 27, end: 222}, {start: 222, end: 223}, + {start: 224, end: 29}, {start: 29, end: 223}, {start: 223, end: 224}, + {start: 225, end: 30}, {start: 30, end: 224}, {start: 224, end: 225}, + {start: 113, end: 247}, {start: 247, end: 225}, {start: 225, end: 113}, + {start: 99, end: 60}, {start: 60, end: 240}, {start: 240, end: 99}, + {start: 213, end: 147}, {start: 147, end: 215}, {start: 215, end: 213}, + {start: 60, end: 20}, {start: 20, end: 166}, {start: 166, end: 60}, + {start: 192, end: 187}, {start: 187, end: 213}, {start: 213, end: 192}, + {start: 243, end: 112}, {start: 112, end: 244}, {start: 244, end: 243}, + {start: 244, end: 233}, {start: 233, end: 245}, {start: 245, end: 244}, + {start: 245, end: 128}, {start: 128, end: 188}, {start: 188, end: 245}, + {start: 188, end: 114}, {start: 114, end: 174}, {start: 174, end: 188}, + {start: 134, end: 131}, {start: 131, end: 220}, {start: 220, end: 134}, + {start: 174, end: 217}, {start: 217, end: 236}, {start: 236, end: 174}, + {start: 236, end: 198}, {start: 198, end: 134}, {start: 134, end: 236}, + {start: 215, end: 177}, {start: 177, end: 58}, {start: 58, end: 215}, + {start: 156, end: 143}, {start: 143, end: 124}, {start: 124, end: 156}, + {start: 25, end: 110}, {start: 110, end: 7}, {start: 7, end: 25}, + {start: 31, end: 228}, {start: 228, end: 25}, {start: 25, end: 31}, + {start: 264, end: 356}, {start: 356, end: 368}, {start: 368, end: 264}, + {start: 0, end: 11}, {start: 11, end: 267}, {start: 267, end: 0}, + {start: 451, end: 452}, {start: 452, end: 349}, {start: 349, end: 451}, + {start: 267, end: 302}, {start: 302, end: 269}, {start: 269, end: 267}, + {start: 350, end: 357}, {start: 357, end: 277}, {start: 277, end: 350}, + {start: 350, end: 452}, {start: 452, end: 357}, {start: 357, end: 350}, + {start: 299, end: 333}, {start: 333, end: 297}, {start: 297, end: 299}, + {start: 396, end: 175}, {start: 175, end: 377}, {start: 377, end: 396}, + {start: 280, end: 347}, {start: 347, end: 330}, {start: 330, end: 280}, + {start: 269, end: 303}, {start: 303, end: 270}, {start: 270, end: 269}, + {start: 151, end: 9}, {start: 9, end: 337}, {start: 337, end: 151}, + {start: 344, end: 278}, {start: 278, end: 360}, {start: 360, end: 344}, + {start: 424, end: 418}, {start: 418, end: 431}, {start: 431, end: 424}, + {start: 270, end: 304}, {start: 304, end: 409}, {start: 409, end: 270}, + {start: 272, end: 310}, {start: 310, end: 407}, {start: 407, end: 272}, + {start: 322, end: 270}, {start: 270, end: 410}, {start: 410, end: 322}, + {start: 449, end: 450}, {start: 450, end: 347}, {start: 347, end: 449}, + {start: 432, end: 422}, {start: 422, end: 434}, {start: 434, end: 432}, + {start: 18, end: 313}, {start: 313, end: 17}, {start: 17, end: 18}, + {start: 291, end: 306}, {start: 306, end: 375}, {start: 375, end: 291}, + {start: 259, end: 387}, {start: 387, end: 260}, {start: 260, end: 259}, + {start: 424, end: 335}, {start: 335, end: 418}, {start: 418, end: 424}, + {start: 434, end: 364}, {start: 364, end: 416}, {start: 416, end: 434}, + {start: 391, end: 423}, {start: 423, end: 327}, {start: 327, end: 391}, + {start: 301, end: 251}, {start: 251, end: 298}, {start: 298, end: 301}, + {start: 275, end: 281}, {start: 281, end: 4}, {start: 4, end: 275}, + {start: 254, end: 373}, {start: 373, end: 253}, {start: 253, end: 254}, + {start: 375, end: 307}, {start: 307, end: 321}, {start: 321, end: 375}, + {start: 280, end: 425}, {start: 425, end: 411}, {start: 411, end: 280}, + {start: 200, end: 421}, {start: 421, end: 18}, {start: 18, end: 200}, + {start: 335, end: 321}, {start: 321, end: 406}, {start: 406, end: 335}, + {start: 321, end: 320}, {start: 320, end: 405}, {start: 405, end: 321}, + {start: 314, end: 315}, {start: 315, end: 17}, {start: 17, end: 314}, + {start: 423, end: 426}, {start: 426, end: 266}, {start: 266, end: 423}, + {start: 396, end: 377}, {start: 377, end: 369}, {start: 369, end: 396}, + {start: 270, end: 322}, {start: 322, end: 269}, {start: 269, end: 270}, + {start: 413, end: 417}, {start: 417, end: 464}, {start: 464, end: 413}, + {start: 385, end: 386}, {start: 386, end: 258}, {start: 258, end: 385}, + {start: 248, end: 456}, {start: 456, end: 419}, {start: 419, end: 248}, + {start: 298, end: 284}, {start: 284, end: 333}, {start: 333, end: 298}, + {start: 168, end: 417}, {start: 417, end: 8}, {start: 8, end: 168}, + {start: 448, end: 346}, {start: 346, end: 261}, {start: 261, end: 448}, + {start: 417, end: 413}, {start: 413, end: 285}, {start: 285, end: 417}, + {start: 326, end: 327}, {start: 327, end: 328}, {start: 328, end: 326}, + {start: 277, end: 355}, {start: 355, end: 329}, {start: 329, end: 277}, + {start: 309, end: 392}, {start: 392, end: 438}, {start: 438, end: 309}, + {start: 381, end: 382}, {start: 382, end: 256}, {start: 256, end: 381}, + {start: 279, end: 429}, {start: 429, end: 360}, {start: 360, end: 279}, + {start: 365, end: 364}, {start: 364, end: 379}, {start: 379, end: 365}, + {start: 355, end: 277}, {start: 277, end: 437}, {start: 437, end: 355}, + {start: 282, end: 443}, {start: 443, end: 283}, {start: 283, end: 282}, + {start: 281, end: 275}, {start: 275, end: 363}, {start: 363, end: 281}, + {start: 395, end: 431}, {start: 431, end: 369}, {start: 369, end: 395}, + {start: 299, end: 297}, {start: 297, end: 337}, {start: 337, end: 299}, + {start: 335, end: 273}, {start: 273, end: 321}, {start: 321, end: 335}, + {start: 348, end: 450}, {start: 450, end: 349}, {start: 349, end: 348}, + {start: 359, end: 446}, {start: 446, end: 467}, {start: 467, end: 359}, + {start: 283, end: 293}, {start: 293, end: 282}, {start: 282, end: 283}, + {start: 250, end: 458}, {start: 458, end: 462}, {start: 462, end: 250}, + {start: 300, end: 276}, {start: 276, end: 383}, {start: 383, end: 300}, + {start: 292, end: 308}, {start: 308, end: 325}, {start: 325, end: 292}, + {start: 283, end: 276}, {start: 276, end: 293}, {start: 293, end: 283}, + {start: 264, end: 372}, {start: 372, end: 447}, {start: 447, end: 264}, + {start: 346, end: 352}, {start: 352, end: 340}, {start: 340, end: 346}, + {start: 354, end: 274}, {start: 274, end: 19}, {start: 19, end: 354}, + {start: 363, end: 456}, {start: 456, end: 281}, {start: 281, end: 363}, + {start: 426, end: 436}, {start: 436, end: 425}, {start: 425, end: 426}, + {start: 380, end: 381}, {start: 381, end: 252}, {start: 252, end: 380}, + {start: 267, end: 269}, {start: 269, end: 393}, {start: 393, end: 267}, + {start: 421, end: 200}, {start: 200, end: 428}, {start: 428, end: 421}, + {start: 371, end: 266}, {start: 266, end: 329}, {start: 329, end: 371}, + {start: 432, end: 287}, {start: 287, end: 422}, {start: 422, end: 432}, + {start: 290, end: 250}, {start: 250, end: 328}, {start: 328, end: 290}, + {start: 385, end: 258}, {start: 258, end: 384}, {start: 384, end: 385}, + {start: 446, end: 265}, {start: 265, end: 342}, {start: 342, end: 446}, + {start: 386, end: 387}, {start: 387, end: 257}, {start: 257, end: 386}, + {start: 422, end: 424}, {start: 424, end: 430}, {start: 430, end: 422}, + {start: 445, end: 342}, {start: 342, end: 276}, {start: 276, end: 445}, + {start: 422, end: 273}, {start: 273, end: 424}, {start: 424, end: 422}, + {start: 306, end: 292}, {start: 292, end: 307}, {start: 307, end: 306}, + {start: 352, end: 366}, {start: 366, end: 345}, {start: 345, end: 352}, + {start: 268, end: 271}, {start: 271, end: 302}, {start: 302, end: 268}, + {start: 358, end: 423}, {start: 423, end: 371}, {start: 371, end: 358}, + {start: 327, end: 294}, {start: 294, end: 460}, {start: 460, end: 327}, + {start: 331, end: 279}, {start: 279, end: 294}, {start: 294, end: 331}, + {start: 303, end: 271}, {start: 271, end: 304}, {start: 304, end: 303}, + {start: 436, end: 432}, {start: 432, end: 427}, {start: 427, end: 436}, + {start: 304, end: 272}, {start: 272, end: 408}, {start: 408, end: 304}, + {start: 395, end: 394}, {start: 394, end: 431}, {start: 431, end: 395}, + {start: 378, end: 395}, {start: 395, end: 400}, {start: 400, end: 378}, + {start: 296, end: 334}, {start: 334, end: 299}, {start: 299, end: 296}, + {start: 6, end: 351}, {start: 351, end: 168}, {start: 168, end: 6}, + {start: 376, end: 352}, {start: 352, end: 411}, {start: 411, end: 376}, + {start: 307, end: 325}, {start: 325, end: 320}, {start: 320, end: 307}, + {start: 285, end: 295}, {start: 295, end: 336}, {start: 336, end: 285}, + {start: 320, end: 319}, {start: 319, end: 404}, {start: 404, end: 320}, + {start: 329, end: 330}, {start: 330, end: 349}, {start: 349, end: 329}, + {start: 334, end: 293}, {start: 293, end: 333}, {start: 333, end: 334}, + {start: 366, end: 323}, {start: 323, end: 447}, {start: 447, end: 366}, + {start: 316, end: 15}, {start: 15, end: 315}, {start: 315, end: 316}, + {start: 331, end: 358}, {start: 358, end: 279}, {start: 279, end: 331}, + {start: 317, end: 14}, {start: 14, end: 316}, {start: 316, end: 317}, + {start: 8, end: 285}, {start: 285, end: 9}, {start: 9, end: 8}, + {start: 277, end: 329}, {start: 329, end: 350}, {start: 350, end: 277}, + {start: 253, end: 374}, {start: 374, end: 252}, {start: 252, end: 253}, + {start: 319, end: 318}, {start: 318, end: 403}, {start: 403, end: 319}, + {start: 351, end: 6}, {start: 6, end: 419}, {start: 419, end: 351}, + {start: 324, end: 318}, {start: 318, end: 325}, {start: 325, end: 324}, + {start: 397, end: 367}, {start: 367, end: 365}, {start: 365, end: 397}, + {start: 288, end: 435}, {start: 435, end: 397}, {start: 397, end: 288}, + {start: 278, end: 344}, {start: 344, end: 439}, {start: 439, end: 278}, + {start: 310, end: 272}, {start: 272, end: 311}, {start: 311, end: 310}, + {start: 248, end: 195}, {start: 195, end: 281}, {start: 281, end: 248}, + {start: 375, end: 273}, {start: 273, end: 291}, {start: 291, end: 375}, + {start: 175, end: 396}, {start: 396, end: 199}, {start: 199, end: 175}, + {start: 312, end: 311}, {start: 311, end: 268}, {start: 268, end: 312}, + {start: 276, end: 283}, {start: 283, end: 445}, {start: 445, end: 276}, + {start: 390, end: 373}, {start: 373, end: 339}, {start: 339, end: 390}, + {start: 295, end: 282}, {start: 282, end: 296}, {start: 296, end: 295}, + {start: 448, end: 449}, {start: 449, end: 346}, {start: 346, end: 448}, + {start: 356, end: 264}, {start: 264, end: 454}, {start: 454, end: 356}, + {start: 337, end: 336}, {start: 336, end: 299}, {start: 299, end: 337}, + {start: 337, end: 338}, {start: 338, end: 151}, {start: 151, end: 337}, + {start: 294, end: 278}, {start: 278, end: 455}, {start: 455, end: 294}, + {start: 308, end: 292}, {start: 292, end: 415}, {start: 415, end: 308}, + {start: 429, end: 358}, {start: 358, end: 355}, {start: 355, end: 429}, + {start: 265, end: 340}, {start: 340, end: 372}, {start: 372, end: 265}, + {start: 352, end: 346}, {start: 346, end: 280}, {start: 280, end: 352}, + {start: 295, end: 442}, {start: 442, end: 282}, {start: 282, end: 295}, + {start: 354, end: 19}, {start: 19, end: 370}, {start: 370, end: 354}, + {start: 285, end: 441}, {start: 441, end: 295}, {start: 295, end: 285}, + {start: 195, end: 248}, {start: 248, end: 197}, {start: 197, end: 195}, + {start: 457, end: 440}, {start: 440, end: 274}, {start: 274, end: 457}, + {start: 301, end: 300}, {start: 300, end: 368}, {start: 368, end: 301}, + {start: 417, end: 351}, {start: 351, end: 465}, {start: 465, end: 417}, + {start: 251, end: 301}, {start: 301, end: 389}, {start: 389, end: 251}, + {start: 394, end: 395}, {start: 395, end: 379}, {start: 379, end: 394}, + {start: 399, end: 412}, {start: 412, end: 419}, {start: 419, end: 399}, + {start: 410, end: 436}, {start: 436, end: 322}, {start: 322, end: 410}, + {start: 326, end: 2}, {start: 2, end: 393}, {start: 393, end: 326}, + {start: 354, end: 370}, {start: 370, end: 461}, {start: 461, end: 354}, + {start: 393, end: 164}, {start: 164, end: 267}, {start: 267, end: 393}, + {start: 268, end: 302}, {start: 302, end: 12}, {start: 12, end: 268}, + {start: 312, end: 268}, {start: 268, end: 13}, {start: 13, end: 312}, + {start: 298, end: 293}, {start: 293, end: 301}, {start: 301, end: 298}, + {start: 265, end: 446}, {start: 446, end: 340}, {start: 340, end: 265}, + {start: 280, end: 330}, {start: 330, end: 425}, {start: 425, end: 280}, + {start: 322, end: 426}, {start: 426, end: 391}, {start: 391, end: 322}, + {start: 420, end: 429}, {start: 429, end: 437}, {start: 437, end: 420}, + {start: 393, end: 391}, {start: 391, end: 326}, {start: 326, end: 393}, + {start: 344, end: 440}, {start: 440, end: 438}, {start: 438, end: 344}, + {start: 458, end: 459}, {start: 459, end: 461}, {start: 461, end: 458}, + {start: 364, end: 434}, {start: 434, end: 394}, {start: 394, end: 364}, + {start: 428, end: 396}, {start: 396, end: 262}, {start: 262, end: 428}, + {start: 274, end: 354}, {start: 354, end: 457}, {start: 457, end: 274}, + {start: 317, end: 316}, {start: 316, end: 402}, {start: 402, end: 317}, + {start: 316, end: 315}, {start: 315, end: 403}, {start: 403, end: 316}, + {start: 315, end: 314}, {start: 314, end: 404}, {start: 404, end: 315}, + {start: 314, end: 313}, {start: 313, end: 405}, {start: 405, end: 314}, + {start: 313, end: 421}, {start: 421, end: 406}, {start: 406, end: 313}, + {start: 323, end: 366}, {start: 366, end: 361}, {start: 361, end: 323}, + {start: 292, end: 306}, {start: 306, end: 407}, {start: 407, end: 292}, + {start: 306, end: 291}, {start: 291, end: 408}, {start: 408, end: 306}, + {start: 291, end: 287}, {start: 287, end: 409}, {start: 409, end: 291}, + {start: 287, end: 432}, {start: 432, end: 410}, {start: 410, end: 287}, + {start: 427, end: 434}, {start: 434, end: 411}, {start: 411, end: 427}, + {start: 372, end: 264}, {start: 264, end: 383}, {start: 383, end: 372}, + {start: 459, end: 309}, {start: 309, end: 457}, {start: 457, end: 459}, + {start: 366, end: 352}, {start: 352, end: 401}, {start: 401, end: 366}, + {start: 1, end: 274}, {start: 274, end: 4}, {start: 4, end: 1}, + {start: 418, end: 421}, {start: 421, end: 262}, {start: 262, end: 418}, + {start: 331, end: 294}, {start: 294, end: 358}, {start: 358, end: 331}, + {start: 435, end: 433}, {start: 433, end: 367}, {start: 367, end: 435}, + {start: 392, end: 289}, {start: 289, end: 439}, {start: 439, end: 392}, + {start: 328, end: 462}, {start: 462, end: 326}, {start: 326, end: 328}, + {start: 94, end: 2}, {start: 2, end: 370}, {start: 370, end: 94}, + {start: 289, end: 305}, {start: 305, end: 455}, {start: 455, end: 289}, + {start: 339, end: 254}, {start: 254, end: 448}, {start: 448, end: 339}, + {start: 359, end: 255}, {start: 255, end: 446}, {start: 446, end: 359}, + {start: 254, end: 253}, {start: 253, end: 449}, {start: 449, end: 254}, + {start: 253, end: 252}, {start: 252, end: 450}, {start: 450, end: 253}, + {start: 252, end: 256}, {start: 256, end: 451}, {start: 451, end: 252}, + {start: 256, end: 341}, {start: 341, end: 452}, {start: 452, end: 256}, + {start: 414, end: 413}, {start: 413, end: 463}, {start: 463, end: 414}, + {start: 286, end: 441}, {start: 441, end: 414}, {start: 414, end: 286}, + {start: 286, end: 258}, {start: 258, end: 441}, {start: 441, end: 286}, + {start: 258, end: 257}, {start: 257, end: 442}, {start: 442, end: 258}, + {start: 257, end: 259}, {start: 259, end: 443}, {start: 443, end: 257}, + {start: 259, end: 260}, {start: 260, end: 444}, {start: 444, end: 259}, + {start: 260, end: 467}, {start: 467, end: 445}, {start: 445, end: 260}, + {start: 309, end: 459}, {start: 459, end: 250}, {start: 250, end: 309}, + {start: 305, end: 289}, {start: 289, end: 290}, {start: 290, end: 305}, + {start: 305, end: 290}, {start: 290, end: 460}, {start: 460, end: 305}, + {start: 401, end: 376}, {start: 376, end: 435}, {start: 435, end: 401}, + {start: 309, end: 250}, {start: 250, end: 392}, {start: 392, end: 309}, + {start: 376, end: 411}, {start: 411, end: 433}, {start: 433, end: 376}, + {start: 453, end: 341}, {start: 341, end: 464}, {start: 464, end: 453}, + {start: 357, end: 453}, {start: 453, end: 465}, {start: 465, end: 357}, + {start: 343, end: 357}, {start: 357, end: 412}, {start: 412, end: 343}, + {start: 437, end: 343}, {start: 343, end: 399}, {start: 399, end: 437}, + {start: 344, end: 360}, {start: 360, end: 440}, {start: 440, end: 344}, + {start: 420, end: 437}, {start: 437, end: 456}, {start: 456, end: 420}, + {start: 360, end: 420}, {start: 420, end: 363}, {start: 363, end: 360}, + {start: 361, end: 401}, {start: 401, end: 288}, {start: 288, end: 361}, + {start: 265, end: 372}, {start: 372, end: 353}, {start: 353, end: 265}, + {start: 390, end: 339}, {start: 339, end: 249}, {start: 249, end: 390}, + {start: 339, end: 448}, {start: 448, end: 255}, {start: 255, end: 339} +]; diff --git a/mediapipe/tasks/web/vision/index.ts b/mediapipe/tasks/web/vision/index.ts index 5b643b84e..52bafdd5f 100644 --- a/mediapipe/tasks/web/vision/index.ts +++ b/mediapipe/tasks/web/vision/index.ts @@ -19,7 +19,7 @@ import {DrawingUtils as DrawingUtilsImpl} from '../../../tasks/web/vision/core/d import {MPImage as MPImageImpl} from '../../../tasks/web/vision/core/image'; import {MPMask as MPMaskImpl} from '../../../tasks/web/vision/core/mask'; import {FaceDetector as FaceDetectorImpl} from '../../../tasks/web/vision/face_detector/face_detector'; -import {FaceLandmarker as FaceLandmarkerImpl, FaceLandmarksConnections as FaceLandmarksConnectionsImpl} from '../../../tasks/web/vision/face_landmarker/face_landmarker'; +import {FaceLandmarker as FaceLandmarkerImpl} from '../../../tasks/web/vision/face_landmarker/face_landmarker'; import {FaceStylizer as FaceStylizerImpl} from '../../../tasks/web/vision/face_stylizer/face_stylizer'; import {GestureRecognizer as GestureRecognizerImpl} from '../../../tasks/web/vision/gesture_recognizer/gesture_recognizer'; import {HandLandmarker as HandLandmarkerImpl} from '../../../tasks/web/vision/hand_landmarker/hand_landmarker'; @@ -38,7 +38,6 @@ const MPImage = MPImageImpl; const MPMask = MPMaskImpl; const FaceDetector = FaceDetectorImpl; const FaceLandmarker = FaceLandmarkerImpl; -const FaceLandmarksConnections = FaceLandmarksConnectionsImpl; const FaceStylizer = FaceStylizerImpl; const GestureRecognizer = GestureRecognizerImpl; const HandLandmarker = HandLandmarkerImpl; @@ -56,7 +55,6 @@ export { MPMask, FaceDetector, FaceLandmarker, - FaceLandmarksConnections, FaceStylizer, GestureRecognizer, HandLandmarker, From b40f0d3b7260a9540e7139bd71646338577dbde6 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Mon, 8 May 2023 13:02:28 -0700 Subject: [PATCH 246/753] Internal change PiperOrigin-RevId: 530385895 --- mediapipe/calculators/util/annotation_overlay_calculator.cc | 2 +- mediapipe/util/BUILD | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediapipe/calculators/util/annotation_overlay_calculator.cc b/mediapipe/calculators/util/annotation_overlay_calculator.cc index 6e0dc769b..34093702c 100644 --- a/mediapipe/calculators/util/annotation_overlay_calculator.cc +++ b/mediapipe/calculators/util/annotation_overlay_calculator.cc @@ -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); diff --git a/mediapipe/util/BUILD b/mediapipe/util/BUILD index b0b7f3468..b9fe8b0c9 100644 --- a/mediapipe/util/BUILD +++ b/mediapipe/util/BUILD @@ -163,12 +163,12 @@ cc_library( hdrs = ["annotation_renderer.h"], visibility = ["//visibility:public"], deps = [ + ":color_cc_proto", ":render_data_cc_proto", "//mediapipe/framework/port:logging", "//mediapipe/framework/port:opencv_core", "//mediapipe/framework/port:opencv_imgproc", "//mediapipe/framework/port:vector", - "//mediapipe/util:color_cc_proto", ], ) From 83a8743a8b94a45bcbde9cbb627abb882e29f6f7 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Mon, 8 May 2023 14:28:53 -0700 Subject: [PATCH 247/753] Internal change PiperOrigin-RevId: 530408554 --- mediapipe/tasks/cc/core/base_options.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mediapipe/tasks/cc/core/base_options.cc b/mediapipe/tasks/cc/core/base_options.cc index 410e8d353..a34c23168 100644 --- a/mediapipe/tasks/cc/core/base_options.cc +++ b/mediapipe/tasks/cc/core/base_options.cc @@ -55,7 +55,9 @@ proto::BaseOptions ConvertBaseOptionsToProto(BaseOptions* base_options) { base_options_proto.mutable_acceleration()->mutable_tflite(); break; case BaseOptions::Delegate::GPU: - base_options_proto.mutable_acceleration()->mutable_gpu(); + base_options_proto.mutable_acceleration() + ->mutable_gpu() + ->set_use_advanced_gpu_api(true); break; case BaseOptions::Delegate::EDGETPU_NNAPI: base_options_proto.mutable_acceleration() From 65cb5f4e6b6da9e8bfa5ea02b67dad880a9a97f2 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Mon, 8 May 2023 16:18:00 -0700 Subject: [PATCH 248/753] Do not depend on *.ts files in ts_declaration PiperOrigin-RevId: 530435849 --- .../tasks/web/vision/image_segmenter/BUILD | 27 ++++++------------ ...ptions.d.ts => image_segmenter_options.ts} | 0 ..._result.d.ts => image_segmenter_result.ts} | 0 .../web/vision/interactive_segmenter/BUILD | 27 ++++++------------ ....d.ts => interactive_segmenter_options.ts} | 0 ...t.d.ts => interactive_segmenter_result.ts} | 0 .../tasks/web/vision/pose_landmarker/BUILD | 28 ++++++------------- ...ptions.d.ts => pose_landmarker_options.ts} | 0 ..._result.d.ts => pose_landmarker_result.ts} | 0 9 files changed, 26 insertions(+), 56 deletions(-) rename mediapipe/tasks/web/vision/image_segmenter/{image_segmenter_options.d.ts => image_segmenter_options.ts} (100%) rename mediapipe/tasks/web/vision/image_segmenter/{image_segmenter_result.d.ts => image_segmenter_result.ts} (100%) rename mediapipe/tasks/web/vision/interactive_segmenter/{interactive_segmenter_options.d.ts => interactive_segmenter_options.ts} (100%) rename mediapipe/tasks/web/vision/interactive_segmenter/{interactive_segmenter_result.d.ts => interactive_segmenter_result.ts} (100%) rename mediapipe/tasks/web/vision/pose_landmarker/{pose_landmarker_options.d.ts => pose_landmarker_options.ts} (100%) rename mediapipe/tasks/web/vision/pose_landmarker/{pose_landmarker_result.d.ts => pose_landmarker_result.ts} (100%) diff --git a/mediapipe/tasks/web/vision/image_segmenter/BUILD b/mediapipe/tasks/web/vision/image_segmenter/BUILD index 1a008cc95..4d9aca996 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/BUILD +++ b/mediapipe/tasks/web/vision/image_segmenter/BUILD @@ -1,6 +1,6 @@ # This contains the MediaPipe Image Segmenter Task. -load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_declaration", "mediapipe_ts_library") +load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_library") load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test") package(default_visibility = ["//mediapipe/tasks:internal"]) @@ -9,9 +9,12 @@ licenses(["notice"]) mediapipe_ts_library( name = "image_segmenter", - srcs = ["image_segmenter.ts"], + srcs = [ + "image_segmenter.ts", + "image_segmenter_options.ts", + "image_segmenter_result.ts", + ], deps = [ - ":image_segmenter_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/framework:calculator_options_jspb_proto", "//mediapipe/tasks/cc/core/proto:base_options_jspb_proto", @@ -19,27 +22,16 @@ mediapipe_ts_library( "//mediapipe/tasks/cc/vision/image_segmenter/proto:image_segmenter_graph_options_jspb_proto", "//mediapipe/tasks/cc/vision/image_segmenter/proto:segmenter_options_jspb_proto", "//mediapipe/tasks/web/core", + "//mediapipe/tasks/web/core:classifier_options", "//mediapipe/tasks/web/vision/core:image_processing_options", + "//mediapipe/tasks/web/vision/core:mask", + "//mediapipe/tasks/web/vision/core:vision_task_options", "//mediapipe/tasks/web/vision/core:vision_task_runner", "//mediapipe/util:label_map_jspb_proto", "//mediapipe/web/graph_runner:graph_runner_ts", ], ) -mediapipe_ts_declaration( - name = "image_segmenter_types", - srcs = [ - "image_segmenter_options.d.ts", - "image_segmenter_result.d.ts", - ], - deps = [ - "//mediapipe/tasks/web/core", - "//mediapipe/tasks/web/core:classifier_options", - "//mediapipe/tasks/web/vision/core:mask", - "//mediapipe/tasks/web/vision/core:vision_task_options", - ], -) - mediapipe_ts_library( name = "image_segmenter_test_lib", testonly = True, @@ -48,7 +40,6 @@ mediapipe_ts_library( ], deps = [ ":image_segmenter", - ":image_segmenter_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.d.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.ts similarity index 100% rename from mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.d.ts rename to mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.ts diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.ts similarity index 100% rename from mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.d.ts rename to mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.ts diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/BUILD b/mediapipe/tasks/web/vision/interactive_segmenter/BUILD index 57b0946a2..c4216463f 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/BUILD +++ b/mediapipe/tasks/web/vision/interactive_segmenter/BUILD @@ -1,6 +1,6 @@ # This contains the MediaPipe Interactive Segmenter Task. -load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_declaration", "mediapipe_ts_library") +load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_library") load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test") package(default_visibility = ["//mediapipe/tasks:internal"]) @@ -9,9 +9,12 @@ licenses(["notice"]) mediapipe_ts_library( name = "interactive_segmenter", - srcs = ["interactive_segmenter.ts"], + srcs = [ + "interactive_segmenter.ts", + "interactive_segmenter_options.ts", + "interactive_segmenter_result.ts", + ], deps = [ - ":interactive_segmenter_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/framework:calculator_options_jspb_proto", "//mediapipe/tasks/cc/core/proto:base_options_jspb_proto", @@ -19,8 +22,11 @@ mediapipe_ts_library( "//mediapipe/tasks/cc/vision/image_segmenter/proto:segmenter_options_jspb_proto", "//mediapipe/tasks/web/components/containers:keypoint", "//mediapipe/tasks/web/core", + "//mediapipe/tasks/web/core:classifier_options", "//mediapipe/tasks/web/vision/core:image_processing_options", + "//mediapipe/tasks/web/vision/core:mask", "//mediapipe/tasks/web/vision/core:types", + "//mediapipe/tasks/web/vision/core:vision_task_options", "//mediapipe/tasks/web/vision/core:vision_task_runner", "//mediapipe/util:color_jspb_proto", "//mediapipe/util:render_data_jspb_proto", @@ -28,20 +34,6 @@ mediapipe_ts_library( ], ) -mediapipe_ts_declaration( - name = "interactive_segmenter_types", - srcs = [ - "interactive_segmenter_options.d.ts", - "interactive_segmenter_result.d.ts", - ], - deps = [ - "//mediapipe/tasks/web/core", - "//mediapipe/tasks/web/core:classifier_options", - "//mediapipe/tasks/web/vision/core:mask", - "//mediapipe/tasks/web/vision/core:vision_task_options", - ], -) - mediapipe_ts_library( name = "interactive_segmenter_test_lib", testonly = True, @@ -50,7 +42,6 @@ mediapipe_ts_library( ], deps = [ ":interactive_segmenter", - ":interactive_segmenter_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.d.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.ts similarity index 100% rename from mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.d.ts rename to mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.ts diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.ts similarity index 100% rename from mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.d.ts rename to mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.ts diff --git a/mediapipe/tasks/web/vision/pose_landmarker/BUILD b/mediapipe/tasks/web/vision/pose_landmarker/BUILD index 566513b40..727f44407 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/BUILD +++ b/mediapipe/tasks/web/vision/pose_landmarker/BUILD @@ -3,7 +3,7 @@ # This task takes video frames and outputs synchronized frames along with # the detection results for one or more pose categories, using Pose Landmarker. -load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_declaration", "mediapipe_ts_library") +load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_library") load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test") package(default_visibility = ["//mediapipe/tasks:internal"]) @@ -12,10 +12,13 @@ licenses(["notice"]) mediapipe_ts_library( name = "pose_landmarker", - srcs = ["pose_landmarker.ts"], + srcs = [ + "pose_landmarker.ts", + "pose_landmarker_options.ts", + "pose_landmarker_result.ts", + ], visibility = ["//visibility:public"], deps = [ - ":pose_landmarker_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/framework:calculator_options_jspb_proto", "//mediapipe/framework/formats:landmark_jspb_proto", @@ -28,28 +31,14 @@ mediapipe_ts_library( "//mediapipe/tasks/web/components/processors:landmark_result", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/vision/core:image_processing_options", + "//mediapipe/tasks/web/vision/core:mask", "//mediapipe/tasks/web/vision/core:types", + "//mediapipe/tasks/web/vision/core:vision_task_options", "//mediapipe/tasks/web/vision/core:vision_task_runner", "//mediapipe/web/graph_runner:graph_runner_ts", ], ) -mediapipe_ts_declaration( - name = "pose_landmarker_types", - srcs = [ - "pose_landmarker_options.d.ts", - "pose_landmarker_result.d.ts", - ], - visibility = ["//visibility:public"], - deps = [ - "//mediapipe/tasks/web/components/containers:category", - "//mediapipe/tasks/web/components/containers:landmark", - "//mediapipe/tasks/web/core", - "//mediapipe/tasks/web/vision/core:mask", - "//mediapipe/tasks/web/vision/core:vision_task_options", - ], -) - mediapipe_ts_library( name = "pose_landmarker_test_lib", testonly = True, @@ -58,7 +47,6 @@ mediapipe_ts_library( ], deps = [ ":pose_landmarker", - ":pose_landmarker_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/tasks/web/components/processors:landmark_result", "//mediapipe/tasks/web/core", diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.d.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.ts similarity index 100% rename from mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.d.ts rename to mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.ts diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.ts similarity index 100% rename from mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.d.ts rename to mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.ts From 10776ef86fc42c6930cafe8196d3264012972c43 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Mon, 8 May 2023 22:18:20 -0700 Subject: [PATCH 249/753] Added error message if no provisioning profile found PiperOrigin-RevId: 530498369 --- mediapipe/examples/ios/link_local_profiles.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mediapipe/examples/ios/link_local_profiles.py b/mediapipe/examples/ios/link_local_profiles.py index bc4a06c97..d353c337e 100755 --- a/mediapipe/examples/ios/link_local_profiles.py +++ b/mediapipe/examples/ios/link_local_profiles.py @@ -147,12 +147,18 @@ def main(): f"Looking for profiles for app ids with prefix '{bundle_id_prefix}' in '{profile_dir}'" ) + profiles_found = False for name in os.listdir(profile_dir): if not name.endswith(".mobileprovision"): continue + profiles_found = True profile_path = os.path.join(profile_dir, name) process_profile(profile_path, our_app_id_re) + if not profiles_found: + print("Error: Unable to find any provisioning profiles " + + f"(*.mobileprovision files) in '{profile_dir}'") + if __name__ == "__main__": main() From 99e3d355cba6bec71ae332285c06dbcc125bf394 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 9 May 2023 11:28:19 +0530 Subject: [PATCH 250/753] Removed opencv framework dep from MPPVisionTaskRunner deps --- mediapipe/tasks/ios/vision/core/BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/mediapipe/tasks/ios/vision/core/BUILD b/mediapipe/tasks/ios/vision/core/BUILD index 328d9e892..a97410e1a 100644 --- a/mediapipe/tasks/ios/vision/core/BUILD +++ b/mediapipe/tasks/ios/vision/core/BUILD @@ -62,6 +62,5 @@ objc_library( "//mediapipe/tasks/ios/core:MPPTaskRunner", "//third_party/apple_frameworks:UIKit", "@com_google_absl//absl/status:statusor", - "@ios_opencv//:OpencvFramework", ], ) From 9de52a4a30e152adf0756c4160713576744f7584 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 9 May 2023 03:46:38 -0700 Subject: [PATCH 251/753] Internal change PiperOrigin-RevId: 530562491 --- mediapipe/calculators/core/gate_calculator.cc | 31 ++++++++++--------- .../calculators/core/gate_calculator.proto | 9 ++++++ .../calculators/core/gate_calculator_test.cc | 24 ++++++++++++++ 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/mediapipe/calculators/core/gate_calculator.cc b/mediapipe/calculators/core/gate_calculator.cc index 448329b88..e5e87b69b 100644 --- a/mediapipe/calculators/core/gate_calculator.cc +++ b/mediapipe/calculators/core/gate_calculator.cc @@ -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(); } } - 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; diff --git a/mediapipe/calculators/core/gate_calculator.proto b/mediapipe/calculators/core/gate_calculator.proto index b7d597a63..4153d5f32 100644 --- a/mediapipe/calculators/core/gate_calculator.proto +++ b/mediapipe/calculators/core/gate_calculator.proto @@ -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]; } diff --git a/mediapipe/calculators/core/gate_calculator_test.cc b/mediapipe/calculators/core/gate_calculator_test.cc index 192019820..8875bd7e3 100644 --- a/mediapipe/calculators/core/gate_calculator_test.cc +++ b/mediapipe/calculators/core/gate_calculator_test.cc @@ -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& output = + runner()->Outputs().Get("STATE_CHANGE", 0).packets; + ASSERT_EQ(1, output.size()); +} + } // namespace } // namespace mediapipe From 08d19739e0c030dc78028feecc33141a553a3b5b Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 9 May 2023 08:37:54 -0700 Subject: [PATCH 252/753] Allow passing --resource_root_dir to resolve asset lookups. PiperOrigin-RevId: 530618235 --- mediapipe/examples/desktop/BUILD | 2 ++ mediapipe/examples/desktop/demo_run_graph_main.cc | 1 + mediapipe/examples/desktop/demo_run_graph_main_gpu.cc | 1 + 3 files changed, 4 insertions(+) diff --git a/mediapipe/examples/desktop/BUILD b/mediapipe/examples/desktop/BUILD index 80cb7ad81..eec485ef0 100644 --- a/mediapipe/examples/desktop/BUILD +++ b/mediapipe/examples/desktop/BUILD @@ -48,6 +48,7 @@ cc_library( "//mediapipe/framework/port:opencv_video", "//mediapipe/framework/port:parse_text_proto", "//mediapipe/framework/port:status", + "//mediapipe/util:resource_util", "@com_google_absl//absl/flags:flag", "@com_google_absl//absl/flags:parse", ], @@ -73,6 +74,7 @@ cc_library( "//mediapipe/gpu:gl_calculator_helper", "//mediapipe/gpu:gpu_buffer", "//mediapipe/gpu:gpu_shared_data_internal", + "//mediapipe/util:resource_util", "@com_google_absl//absl/flags:flag", "@com_google_absl//absl/flags:parse", ], diff --git a/mediapipe/examples/desktop/demo_run_graph_main.cc b/mediapipe/examples/desktop/demo_run_graph_main.cc index 0d26aa0d3..bb70d3df7 100644 --- a/mediapipe/examples/desktop/demo_run_graph_main.cc +++ b/mediapipe/examples/desktop/demo_run_graph_main.cc @@ -26,6 +26,7 @@ #include "mediapipe/framework/port/opencv_video_inc.h" #include "mediapipe/framework/port/parse_text_proto.h" #include "mediapipe/framework/port/status.h" +#include "mediapipe/util/resource_util.h" constexpr char kInputStream[] = "input_video"; constexpr char kOutputStream[] = "output_video"; diff --git a/mediapipe/examples/desktop/demo_run_graph_main_gpu.cc b/mediapipe/examples/desktop/demo_run_graph_main_gpu.cc index 586565db4..8336e5670 100644 --- a/mediapipe/examples/desktop/demo_run_graph_main_gpu.cc +++ b/mediapipe/examples/desktop/demo_run_graph_main_gpu.cc @@ -30,6 +30,7 @@ #include "mediapipe/gpu/gl_calculator_helper.h" #include "mediapipe/gpu/gpu_buffer.h" #include "mediapipe/gpu/gpu_shared_data_internal.h" +#include "mediapipe/util/resource_util.h" constexpr char kInputStream[] = "input_video"; constexpr char kOutputStream[] = "output_video"; From 05c565898a29494be5658738d82e7c91894e89a4 Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Tue, 9 May 2023 12:00:13 -0700 Subject: [PATCH 253/753] Add image_segmenter_metadata_schema and object_detector_metadata_schema python files to the mediapipe python wheels. PiperOrigin-RevId: 530674961 --- setup.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 202917ef2..a073128e7 100644 --- a/setup.py +++ b/setup.py @@ -294,7 +294,12 @@ class GenerateMetadataSchema(build_ext.build_ext): """Generate metadata python schema files.""" def run(self): - for target in ['metadata_schema_py', 'schema_py']: + for target in [ + 'image_segmenter_metadata_schema_py', + 'metadata_schema_py', + 'object_detector_metadata_schema_py', + 'schema_py', + ]: bazel_command = [ 'bazel', 'build', From 6f3c80ae8a6ebbf70062bc5bf96730e20617f6c6 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Tue, 9 May 2023 14:02:42 -0700 Subject: [PATCH 254/753] Prevent property mangling for options types PiperOrigin-RevId: 530707361 --- .../containers/classification_result.d.ts | 2 +- .../components/containers/detection_result.d.ts | 2 +- .../components/containers/embedding_result.d.ts | 2 +- mediapipe/tasks/web/vision/core/image.ts | 2 ++ mediapipe/tasks/web/vision/core/mask.ts | 2 ++ .../face_detector/face_detector_options.d.ts | 2 +- .../face_stylizer/face_stylizer_options.d.ts | 2 +- mediapipe/tasks/web/vision/image_segmenter/BUILD | 12 +++++++++--- ...ter_options.ts => image_segmenter_options.d.ts} | 2 +- .../tasks/web/vision/interactive_segmenter/BUILD | 14 +++++++++++--- ...tions.ts => interactive_segmenter_options.d.ts} | 2 +- .../object_detector/object_detector_options.d.ts | 4 ++-- mediapipe/tasks/web/vision/pose_landmarker/BUILD | 12 +++++++++--- ...ker_options.ts => pose_landmarker_options.d.ts} | 0 14 files changed, 42 insertions(+), 18 deletions(-) rename mediapipe/tasks/web/vision/image_segmenter/{image_segmenter_options.ts => image_segmenter_options.d.ts} (93%) rename mediapipe/tasks/web/vision/interactive_segmenter/{interactive_segmenter_options.ts => interactive_segmenter_options.d.ts} (92%) rename mediapipe/tasks/web/vision/pose_landmarker/{pose_landmarker_options.ts => pose_landmarker_options.d.ts} (100%) diff --git a/mediapipe/tasks/web/components/containers/classification_result.d.ts b/mediapipe/tasks/web/components/containers/classification_result.d.ts index f7294dcac..7557560cf 100644 --- a/mediapipe/tasks/web/components/containers/classification_result.d.ts +++ b/mediapipe/tasks/web/components/containers/classification_result.d.ts @@ -38,7 +38,7 @@ export declare interface Classifications { } /** Classification results of a model. */ -export interface ClassificationResult { +export declare interface ClassificationResult { /** The classification results for each head of the model. */ classifications: Classifications[]; diff --git a/mediapipe/tasks/web/components/containers/detection_result.d.ts b/mediapipe/tasks/web/components/containers/detection_result.d.ts index 3d0e86a0b..287632f2d 100644 --- a/mediapipe/tasks/web/components/containers/detection_result.d.ts +++ b/mediapipe/tasks/web/components/containers/detection_result.d.ts @@ -37,7 +37,7 @@ export declare interface Detection { } /** Detection results of a model. */ -export interface DetectionResult { +export declare interface DetectionResult { /** A list of Detections. */ detections: Detection[]; } diff --git a/mediapipe/tasks/web/components/containers/embedding_result.d.ts b/mediapipe/tasks/web/components/containers/embedding_result.d.ts index a4b4ec203..812d66f5b 100644 --- a/mediapipe/tasks/web/components/containers/embedding_result.d.ts +++ b/mediapipe/tasks/web/components/containers/embedding_result.d.ts @@ -48,7 +48,7 @@ export declare interface Embedding { } /** Embedding results for a given embedder model. */ -export interface EmbeddingResult { +export declare interface EmbeddingResult { /** * The embedding results for each model head, i.e. one for each output tensor. */ diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index bcc6b7ca1..4a7b6dce7 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -393,3 +393,5 @@ export class MPImage { } } } + + diff --git a/mediapipe/tasks/web/vision/core/mask.ts b/mediapipe/tasks/web/vision/core/mask.ts index da14f104f..13deab3fc 100644 --- a/mediapipe/tasks/web/vision/core/mask.ts +++ b/mediapipe/tasks/web/vision/core/mask.ts @@ -313,3 +313,5 @@ export class MPMask { } } } + + diff --git a/mediapipe/tasks/web/vision/face_detector/face_detector_options.d.ts b/mediapipe/tasks/web/vision/face_detector/face_detector_options.d.ts index d2539ecb5..81c8fb139 100644 --- a/mediapipe/tasks/web/vision/face_detector/face_detector_options.d.ts +++ b/mediapipe/tasks/web/vision/face_detector/face_detector_options.d.ts @@ -18,7 +18,7 @@ import {ClassifierOptions} from '../../../../tasks/web/core/classifier_options'; import {VisionTaskOptions} from '../../../../tasks/web/vision/core/vision_task_options'; /** Options to configure the MediaPipe Face Detector Task */ -export interface FaceDetectorOptions extends VisionTaskOptions { +export declare interface FaceDetectorOptions extends VisionTaskOptions { /** * The minimum confidence score for the face detection to be considered * successful. Defaults to 0.5. diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_options.d.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_options.d.ts index 73942badc..6afd236fc 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_options.d.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer_options.d.ts @@ -17,4 +17,4 @@ import {VisionTaskOptions} from '../../../../tasks/web/vision/core/vision_task_options'; /** Options to configure the MediaPipe Face Stylizer Task */ -export interface FaceStylizerOptions extends VisionTaskOptions {} +export declare interface FaceStylizerOptions extends VisionTaskOptions {} diff --git a/mediapipe/tasks/web/vision/image_segmenter/BUILD b/mediapipe/tasks/web/vision/image_segmenter/BUILD index 4d9aca996..13f01e8b6 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/BUILD +++ b/mediapipe/tasks/web/vision/image_segmenter/BUILD @@ -1,6 +1,6 @@ # This contains the MediaPipe Image Segmenter Task. -load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_library") +load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_declaration", "mediapipe_ts_library") load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test") package(default_visibility = ["//mediapipe/tasks:internal"]) @@ -11,10 +11,10 @@ mediapipe_ts_library( name = "image_segmenter", srcs = [ "image_segmenter.ts", - "image_segmenter_options.ts", "image_segmenter_result.ts", ], deps = [ + ":image_segmenter_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/framework:calculator_options_jspb_proto", "//mediapipe/tasks/cc/core/proto:base_options_jspb_proto", @@ -25,13 +25,18 @@ mediapipe_ts_library( "//mediapipe/tasks/web/core:classifier_options", "//mediapipe/tasks/web/vision/core:image_processing_options", "//mediapipe/tasks/web/vision/core:mask", - "//mediapipe/tasks/web/vision/core:vision_task_options", "//mediapipe/tasks/web/vision/core:vision_task_runner", "//mediapipe/util:label_map_jspb_proto", "//mediapipe/web/graph_runner:graph_runner_ts", ], ) +mediapipe_ts_declaration( + name = "image_segmenter_types", + srcs = ["image_segmenter_options.d.ts"], + deps = ["//mediapipe/tasks/web/vision/core:vision_task_options"], +) + mediapipe_ts_library( name = "image_segmenter_test_lib", testonly = True, @@ -40,6 +45,7 @@ mediapipe_ts_library( ], deps = [ ":image_segmenter", + ":image_segmenter_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/tasks/web/core", "//mediapipe/tasks/web/core:task_runner_test_utils", diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.d.ts similarity index 93% rename from mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.ts rename to mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.d.ts index 5e7fe7a45..f3c3e3815 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_options.d.ts @@ -17,7 +17,7 @@ import {VisionTaskOptions} from '../../../../tasks/web/vision/core/vision_task_options'; /** Options to configure the MediaPipe Image Segmenter Task */ -export interface ImageSegmenterOptions extends VisionTaskOptions { +export declare interface ImageSegmenterOptions extends VisionTaskOptions { /** * The locale to use for display names specified through the TFLite Model * Metadata, if any. Defaults to English. diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/BUILD b/mediapipe/tasks/web/vision/interactive_segmenter/BUILD index c4216463f..76493c056 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/BUILD +++ b/mediapipe/tasks/web/vision/interactive_segmenter/BUILD @@ -1,6 +1,6 @@ # This contains the MediaPipe Interactive Segmenter Task. -load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_library") +load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_declaration", "mediapipe_ts_library") load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test") package(default_visibility = ["//mediapipe/tasks:internal"]) @@ -11,10 +11,10 @@ mediapipe_ts_library( name = "interactive_segmenter", srcs = [ "interactive_segmenter.ts", - "interactive_segmenter_options.ts", "interactive_segmenter_result.ts", ], deps = [ + ":interactive_segmenter_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/framework:calculator_options_jspb_proto", "//mediapipe/tasks/cc/core/proto:base_options_jspb_proto", @@ -26,7 +26,6 @@ mediapipe_ts_library( "//mediapipe/tasks/web/vision/core:image_processing_options", "//mediapipe/tasks/web/vision/core:mask", "//mediapipe/tasks/web/vision/core:types", - "//mediapipe/tasks/web/vision/core:vision_task_options", "//mediapipe/tasks/web/vision/core:vision_task_runner", "//mediapipe/util:color_jspb_proto", "//mediapipe/util:render_data_jspb_proto", @@ -34,6 +33,15 @@ mediapipe_ts_library( ], ) +mediapipe_ts_declaration( + name = "interactive_segmenter_types", + srcs = ["interactive_segmenter_options.d.ts"], + deps = [ + "//mediapipe/tasks/web/core", + "//mediapipe/tasks/web/vision/core:vision_task_options", + ], +) + mediapipe_ts_library( name = "interactive_segmenter_test_lib", testonly = True, diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.d.ts similarity index 92% rename from mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.ts rename to mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.d.ts index 952a5190a..551088cee 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_options.d.ts @@ -18,7 +18,7 @@ import {TaskRunnerOptions} from '../../../../tasks/web/core/task_runner_options'; /** Options to configure the MediaPipe Interactive Segmenter Task */ -export interface InteractiveSegmenterOptions extends TaskRunnerOptions { +export declare interface InteractiveSegmenterOptions extends TaskRunnerOptions { /** Whether to output confidence masks. Defaults to true. */ outputConfidenceMasks?: boolean|undefined; diff --git a/mediapipe/tasks/web/vision/object_detector/object_detector_options.d.ts b/mediapipe/tasks/web/vision/object_detector/object_detector_options.d.ts index d0ead197d..cfe604ed1 100644 --- a/mediapipe/tasks/web/vision/object_detector/object_detector_options.d.ts +++ b/mediapipe/tasks/web/vision/object_detector/object_detector_options.d.ts @@ -18,5 +18,5 @@ import {ClassifierOptions} from '../../../../tasks/web/core/classifier_options'; import {VisionTaskOptions} from '../../../../tasks/web/vision/core/vision_task_options'; /** Options to configure the MediaPipe Object Detector Task */ -export interface ObjectDetectorOptions extends VisionTaskOptions, - ClassifierOptions {} +export declare interface ObjectDetectorOptions extends VisionTaskOptions, + ClassifierOptions {} diff --git a/mediapipe/tasks/web/vision/pose_landmarker/BUILD b/mediapipe/tasks/web/vision/pose_landmarker/BUILD index 727f44407..ec4c0aeaf 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/BUILD +++ b/mediapipe/tasks/web/vision/pose_landmarker/BUILD @@ -3,7 +3,7 @@ # This task takes video frames and outputs synchronized frames along with # the detection results for one or more pose categories, using Pose Landmarker. -load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_library") +load("//mediapipe/framework/port:build_config.bzl", "mediapipe_ts_declaration", "mediapipe_ts_library") load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test") package(default_visibility = ["//mediapipe/tasks:internal"]) @@ -14,11 +14,11 @@ mediapipe_ts_library( name = "pose_landmarker", srcs = [ "pose_landmarker.ts", - "pose_landmarker_options.ts", "pose_landmarker_result.ts", ], visibility = ["//visibility:public"], deps = [ + ":pose_landmarker_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/framework:calculator_options_jspb_proto", "//mediapipe/framework/formats:landmark_jspb_proto", @@ -33,12 +33,17 @@ mediapipe_ts_library( "//mediapipe/tasks/web/vision/core:image_processing_options", "//mediapipe/tasks/web/vision/core:mask", "//mediapipe/tasks/web/vision/core:types", - "//mediapipe/tasks/web/vision/core:vision_task_options", "//mediapipe/tasks/web/vision/core:vision_task_runner", "//mediapipe/web/graph_runner:graph_runner_ts", ], ) +mediapipe_ts_declaration( + name = "pose_landmarker_types", + srcs = ["pose_landmarker_options.d.ts"], + deps = ["//mediapipe/tasks/web/vision/core:vision_task_options"], +) + mediapipe_ts_library( name = "pose_landmarker_test_lib", testonly = True, @@ -47,6 +52,7 @@ mediapipe_ts_library( ], deps = [ ":pose_landmarker", + ":pose_landmarker_types", "//mediapipe/framework:calculator_jspb_proto", "//mediapipe/tasks/web/components/processors:landmark_result", "//mediapipe/tasks/web/core", diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.d.ts similarity index 100% rename from mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.ts rename to mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_options.d.ts From bea5eb766dbbcefee1fb56f172a3fdbd97975c64 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Tue, 9 May 2023 14:50:26 -0700 Subject: [PATCH 255/753] Move Java Connections arrays to Task class PiperOrigin-RevId: 530719994 --- .../tasks/components/containers/BUILD | 9 ++++ .../components/containers/Connection.java | 29 +++++++++++++ .../com/google/mediapipe/tasks/vision/BUILD | 3 ++ .../vision/facelandmarker/FaceLandmarker.java | 42 +++++++++++++++++++ .../FaceLandmarksConnections.java | 36 ++++++---------- .../vision/handlandmarker/HandLandmarker.java | 29 +++++++++++++ .../HandLandmarksConnections.java | 30 ++++--------- .../vision/poselandmarker/PoseLandmarker.java | 5 +++ .../PoseLandmarksConnections.java | 18 ++------ 9 files changed, 141 insertions(+), 60 deletions(-) create mode 100644 mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Connection.java diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/BUILD index 2c76f9a0b..07106985d 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/BUILD @@ -80,6 +80,15 @@ android_library( ], ) +android_library( + name = "connection", + srcs = ["Connection.java"], + deps = [ + "//third_party:autovalue", + "@maven//:com_google_guava_guava", + ], +) + android_library( name = "landmark", srcs = ["Landmark.java"], diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Connection.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Connection.java new file mode 100644 index 000000000..99103c201 --- /dev/null +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers/Connection.java @@ -0,0 +1,29 @@ +// 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. + +package com.google.mediapipe.tasks.components.containers; + +import com.google.auto.value.AutoValue; + +/** Value class representing a landmark connection. */ +@AutoValue +public abstract class Connection { + public static Connection create(int start, int end) { + return new AutoValue_Connection(start, end); + } + + public abstract int start(); + + public abstract int end(); +} diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD index a2dbe351a..399156da3 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD @@ -198,6 +198,7 @@ android_library( "//mediapipe/tasks/cc/vision/pose_detector/proto:pose_detector_graph_options_java_proto_lite", "//mediapipe/tasks/cc/vision/pose_landmarker/proto:pose_landmarker_graph_options_java_proto_lite", "//mediapipe/tasks/cc/vision/pose_landmarker/proto:pose_landmarks_detector_graph_options_java_proto_lite", + "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:connection", "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:landmark", "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:normalized_landmark", "//mediapipe/tasks/java/com/google/mediapipe/tasks/core", @@ -232,6 +233,7 @@ android_library( "//mediapipe/tasks/cc/vision/hand_landmarker/proto:hand_landmarker_graph_options_java_proto_lite", "//mediapipe/tasks/cc/vision/hand_landmarker/proto:hand_landmarks_detector_graph_options_java_proto_lite", "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:category", + "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:connection", "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:landmark", "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:normalized_landmark", "//mediapipe/tasks/java/com/google/mediapipe/tasks/core", @@ -373,6 +375,7 @@ android_library( "//mediapipe/tasks/cc/vision/face_landmarker/proto:face_landmarker_graph_options_java_proto_lite", "//mediapipe/tasks/cc/vision/face_landmarker/proto:face_landmarks_detector_graph_options_java_proto_lite", "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:category", + "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:connection", "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:normalized_landmark", "//mediapipe/tasks/java/com/google/mediapipe/tasks/core", "//third_party:autovalue", diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarker.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarker.java index 6a10f52ed..f7792a1be 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarker.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarker.java @@ -25,6 +25,7 @@ import com.google.mediapipe.framework.Packet; import com.google.mediapipe.framework.PacketGetter; import com.google.mediapipe.framework.image.BitmapImageBuilder; import com.google.mediapipe.framework.image.MPImage; +import com.google.mediapipe.tasks.components.containers.Connection; import com.google.mediapipe.tasks.core.BaseOptions; import com.google.mediapipe.tasks.core.ErrorListener; import com.google.mediapipe.tasks.core.OutputHandler; @@ -49,6 +50,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.Set; /** * Performs face landmarks detection on images. @@ -223,6 +225,46 @@ public final class FaceLandmarker extends BaseVisionTaskApi { return new FaceLandmarker(runner, landmarkerOptions.runningMode()); } + @SuppressWarnings("ConstantCaseForConstants") + public static final Set FACE_LANDMARKS_LIPS = + FaceLandmarksConnections.FACE_LANDMARKS_LIPS; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set FACE_LANDMARKS_LEFT_EYE = + FaceLandmarksConnections.FACE_LANDMARKS_LEFT_EYE; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set FACE_LANDMARKS_LEFT_EYE_BROW = + FaceLandmarksConnections.FACE_LANDMARKS_LEFT_EYE_BROW; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set FACE_LANDMARKS_LEFT_IRIS = + FaceLandmarksConnections.FACE_LANDMARKS_LEFT_IRIS; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set FACE_LANDMARKS_RIGHT_EYE = + FaceLandmarksConnections.FACE_LANDMARKS_RIGHT_EYE; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set FACE_LANDMARKS_RIGHT_EYE_BROW = + FaceLandmarksConnections.FACE_LANDMARKS_RIGHT_EYE_BROW; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set FACE_LANDMARKS_RIGHT_IRIS = + FaceLandmarksConnections.FACE_LANDMARKS_RIGHT_IRIS; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set FACE_LANDMARKS_FACE_OVAL = + FaceLandmarksConnections.FACE_LANDMARKS_FACE_OVAL; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set FACE_LANDMARKS_CONNECTORS = + FaceLandmarksConnections.FACE_LANDMARKS_CONNECTORS; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set FACE_LANDMARKS_TESSELATION = + FaceLandmarksConnections.FACE_LANDMARKS_TESSELATION; + /** * Constructor to initialize an {@link FaceLandmarker} from a {@link TaskRunner} and a {@link * RunningMode}. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarksConnections.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarksConnections.java index ad996f369..63b142ced 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarksConnections.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/facelandmarker/FaceLandmarksConnections.java @@ -14,7 +14,7 @@ package com.google.mediapipe.tasks.vision.facelandmarker; -import com.google.auto.value.AutoValue; +import com.google.mediapipe.tasks.components.containers.Connection; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -23,22 +23,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; /** Face landmarks connection constants. */ -public final class FaceLandmarksConnections { - - /** Value class representing face landmarks connection. */ - @AutoValue - public abstract static class Connection { - static Connection create(int start, int end) { - return new AutoValue_FaceLandmarksConnections_Connection(start, end); - } - - public abstract int start(); - - public abstract int end(); - } +final class FaceLandmarksConnections { @SuppressWarnings("ConstantCaseForConstants") - public static final Set FACE_LANDMARKS_LIPS = + static final Set FACE_LANDMARKS_LIPS = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( @@ -84,7 +72,7 @@ public final class FaceLandmarksConnections { Connection.create(415, 308)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set FACE_LANDMARKS_LEFT_EYE = + static final Set FACE_LANDMARKS_LEFT_EYE = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( @@ -106,7 +94,7 @@ public final class FaceLandmarksConnections { Connection.create(398, 362)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set FACE_LANDMARKS_LEFT_EYE_BROW = + static final Set FACE_LANDMARKS_LEFT_EYE_BROW = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( @@ -120,7 +108,7 @@ public final class FaceLandmarksConnections { Connection.create(296, 336)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set FACE_LANDMARKS_LEFT_IRIS = + static final Set FACE_LANDMARKS_LEFT_IRIS = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( @@ -130,7 +118,7 @@ public final class FaceLandmarksConnections { Connection.create(477, 474)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set FACE_LANDMARKS_RIGHT_EYE = + static final Set FACE_LANDMARKS_RIGHT_EYE = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( @@ -152,7 +140,7 @@ public final class FaceLandmarksConnections { Connection.create(173, 133)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set FACE_LANDMARKS_RIGHT_EYE_BROW = + static final Set FACE_LANDMARKS_RIGHT_EYE_BROW = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( @@ -166,7 +154,7 @@ public final class FaceLandmarksConnections { Connection.create(66, 107)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set FACE_LANDMARKS_RIGHT_IRIS = + static final Set FACE_LANDMARKS_RIGHT_IRIS = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( @@ -176,7 +164,7 @@ public final class FaceLandmarksConnections { Connection.create(472, 469)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set FACE_LANDMARKS_FACE_OVAL = + static final Set FACE_LANDMARKS_FACE_OVAL = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( @@ -218,7 +206,7 @@ public final class FaceLandmarksConnections { Connection.create(109, 10)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set FACE_LANDMARKS_CONNECTORS = + static final Set FACE_LANDMARKS_CONNECTORS = Collections.unmodifiableSet( Stream.of( FACE_LANDMARKS_LIPS.stream(), @@ -231,7 +219,7 @@ public final class FaceLandmarksConnections { .collect(Collectors.toSet())); @SuppressWarnings("ConstantCaseForConstants") - public static final Set FACE_LANDMARKS_TESSELATION = + static final Set FACE_LANDMARKS_TESSELATION = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarker.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarker.java index 2af893128..8b02b15ad 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarker.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarker.java @@ -26,6 +26,7 @@ import com.google.mediapipe.framework.Packet; import com.google.mediapipe.framework.PacketGetter; import com.google.mediapipe.framework.image.BitmapImageBuilder; import com.google.mediapipe.framework.image.MPImage; +import com.google.mediapipe.tasks.components.containers.Connection; import com.google.mediapipe.tasks.core.BaseOptions; import com.google.mediapipe.tasks.core.ErrorListener; import com.google.mediapipe.tasks.core.OutputHandler; @@ -48,6 +49,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.Set; /** * Performs hand landmarks detection on images. @@ -195,6 +197,33 @@ public final class HandLandmarker extends BaseVisionTaskApi { return new HandLandmarker(runner, landmarkerOptions.runningMode()); } + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_PALM_CONNECTIONS = + HandLandmarksConnections.HAND_PALM_CONNECTIONS; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_THUMB_CONNECTIONS = + HandLandmarksConnections.HAND_THUMB_CONNECTIONS; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_INDEX_FINGER_CONNECTIONS = + HandLandmarksConnections.HAND_INDEX_FINGER_CONNECTIONS; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_MIDDLE_FINGER_CONNECTIONS = + HandLandmarksConnections.HAND_MIDDLE_FINGER_CONNECTIONS; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_RING_FINGER_CONNECTIONS = + HandLandmarksConnections.HAND_RING_FINGER_CONNECTIONS; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_PINKY_FINGER_CONNECTIONS = + HandLandmarksConnections.HAND_PINKY_FINGER_CONNECTIONS; + + @SuppressWarnings("ConstantCaseForConstants") + public static final Set HAND_CONNECTIONS = HandLandmarksConnections.HAND_CONNECTIONS; + /** * Constructor to initialize an {@link HandLandmarker} from a {@link TaskRunner} and a {@link * RunningMode}. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarksConnections.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarksConnections.java index c60923840..81b922557 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarksConnections.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/handlandmarker/HandLandmarksConnections.java @@ -14,7 +14,7 @@ package com.google.mediapipe.tasks.vision.handlandmarker; -import com.google.auto.value.AutoValue; +import com.google.mediapipe.tasks.components.containers.Connection; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -23,22 +23,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; /** Hand landmarks connection constants. */ -public final class HandLandmarksConnections { - - /** Value class representing hand landmarks connection. */ - @AutoValue - public abstract static class Connection { - static Connection create(int start, int end) { - return new AutoValue_HandLandmarksConnections_Connection(start, end); - } - - public abstract int start(); - - public abstract int end(); - } +final class HandLandmarksConnections { @SuppressWarnings("ConstantCaseForConstants") - public static final Set HAND_PALM_CONNECTIONS = + static final Set HAND_PALM_CONNECTIONS = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( @@ -50,28 +38,28 @@ public final class HandLandmarksConnections { Connection.create(0, 17)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set HAND_THUMB_CONNECTIONS = + static final Set HAND_THUMB_CONNECTIONS = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( Connection.create(1, 2), Connection.create(2, 3), Connection.create(3, 4)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set HAND_INDEX_FINGER_CONNECTIONS = + static final Set HAND_INDEX_FINGER_CONNECTIONS = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( Connection.create(5, 6), Connection.create(6, 7), Connection.create(7, 8)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set HAND_MIDDLE_FINGER_CONNECTIONS = + static final Set HAND_MIDDLE_FINGER_CONNECTIONS = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( Connection.create(9, 10), Connection.create(10, 11), Connection.create(11, 12)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set HAND_RING_FINGER_CONNECTIONS = + static final Set HAND_RING_FINGER_CONNECTIONS = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( @@ -80,7 +68,7 @@ public final class HandLandmarksConnections { Connection.create(15, 16)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set HAND_PINKY_FINGER_CONNECTIONS = + static final Set HAND_PINKY_FINGER_CONNECTIONS = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( @@ -89,7 +77,7 @@ public final class HandLandmarksConnections { Connection.create(19, 20)))); @SuppressWarnings("ConstantCaseForConstants") - public static final Set HAND_CONNECTIONS = + static final Set HAND_CONNECTIONS = Collections.unmodifiableSet( Stream.of( HAND_PALM_CONNECTIONS.stream(), diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java index fa2d3da17..d59448dac 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarker.java @@ -27,6 +27,7 @@ import com.google.mediapipe.framework.PacketGetter; import com.google.mediapipe.framework.image.BitmapImageBuilder; import com.google.mediapipe.framework.image.ByteBufferImageBuilder; import com.google.mediapipe.framework.image.MPImage; +import com.google.mediapipe.tasks.components.containers.Connection; import com.google.mediapipe.tasks.core.BaseOptions; import com.google.mediapipe.tasks.core.ErrorListener; import com.google.mediapipe.tasks.core.OutputHandler; @@ -49,6 +50,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.Set; /** * Performs pose landmarks detection on images. @@ -206,6 +208,9 @@ public final class PoseLandmarker extends BaseVisionTaskApi { return new PoseLandmarker(runner, landmarkerOptions.runningMode()); } + @SuppressWarnings("ConstantCaseForConstants") + public static final Set POSE_LANDMARKS = PoseLandmarksConnections.POSE_LANDMARKS; + /** * Constructor to initialize a {@link PoseLandmarker} from a {@link TaskRunner} and a {@link * RunningMode}. diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarksConnections.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarksConnections.java index 9be6a9aeb..21d3a74b7 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarksConnections.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/poselandmarker/PoseLandmarksConnections.java @@ -14,29 +14,17 @@ package com.google.mediapipe.tasks.vision.poselandmarker; -import com.google.auto.value.AutoValue; +import com.google.mediapipe.tasks.components.containers.Connection; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** Pose landmarks connection constants. */ -public final class PoseLandmarksConnections { - - /** Value class representing pose landmarks connection. */ - @AutoValue - public abstract static class Connection { - static Connection create(int start, int end) { - return new AutoValue_PoseLandmarksConnections_Connection(start, end); - } - - public abstract int start(); - - public abstract int end(); - } +final class PoseLandmarksConnections { @SuppressWarnings("ConstantCaseForConstants") - public static final Set POSE_LANDMARKS = + static final Set POSE_LANDMARKS = Collections.unmodifiableSet( new HashSet<>( Arrays.asList( From f77481f303c91e08a8cb5b7ecf81b7f69ddf5b7b Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 9 May 2023 15:55:20 -0700 Subject: [PATCH 256/753] 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 --- mediapipe/gpu/gl_context.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mediapipe/gpu/gl_context.cc b/mediapipe/gpu/gl_context.cc index 99b995dda..3244f22aa 100644 --- a/mediapipe/gpu/gl_context.cc +++ b/mediapipe/gpu/gl_context.cc @@ -340,7 +340,9 @@ absl::Status GlContext::FinishInitialization(bool create_thread) { } LOG(INFO) << "GL version: " << gl_major_version_ << "." << gl_minor_version_ - << " (" << version_string << ")"; + << " (" << version_string + << "), renderer: " << glGetString(GL_RENDERER); + { auto status = GetGlExtensions(); if (!status.ok()) { From dd1779840dce18932c62cd565b9852f679221392 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 9 May 2023 16:47:10 -0700 Subject: [PATCH 257/753] Update model_maker requirements.txt for release PiperOrigin-RevId: 530748415 --- mediapipe/model_maker/requirements.txt | 4 ++-- mediapipe/tasks/ios/vision/core/BUILD | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mediapipe/model_maker/requirements.txt b/mediapipe/model_maker/requirements.txt index 82474dba8..5c78dc582 100644 --- a/mediapipe/model_maker/requirements.txt +++ b/mediapipe/model_maker/requirements.txt @@ -1,8 +1,8 @@ absl-py -mediapipe==0.9.2.1 +mediapipe>=0.10.0 numpy opencv-python tensorflow>=2.10 tensorflow-datasets tensorflow-hub -tf-models-official>=2.11.5 +tf-models-official==2.11.6 diff --git a/mediapipe/tasks/ios/vision/core/BUILD b/mediapipe/tasks/ios/vision/core/BUILD index a97410e1a..328d9e892 100644 --- a/mediapipe/tasks/ios/vision/core/BUILD +++ b/mediapipe/tasks/ios/vision/core/BUILD @@ -62,5 +62,6 @@ objc_library( "//mediapipe/tasks/ios/core:MPPTaskRunner", "//third_party/apple_frameworks:UIKit", "@com_google_absl//absl/status:statusor", + "@ios_opencv//:OpencvFramework", ], ) From 6ff39c418c7d1ea852b930f11fa3366691db1dc6 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 9 May 2023 16:59:44 -0700 Subject: [PATCH 258/753] Internal change PiperOrigin-RevId: 530751097 --- .../java/com/google/mediapipe/tasks/core/TaskOptions.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskOptions.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskOptions.java index 9c6f1adca..11330ac0f 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskOptions.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/core/TaskOptions.java @@ -64,7 +64,9 @@ public abstract class TaskOptions { break; case GPU: accelerationBuilder.setGpu( - InferenceCalculatorProto.InferenceCalculatorOptions.Delegate.Gpu.getDefaultInstance()); + InferenceCalculatorProto.InferenceCalculatorOptions.Delegate.Gpu.newBuilder() + .setUseAdvancedGpuApi(true) + .build()); break; } return BaseOptionsProto.BaseOptions.newBuilder() From f95a78239910ee5e4d26918e621f7f2055b63256 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 9 May 2023 17:01:39 -0700 Subject: [PATCH 259/753] Internal change PiperOrigin-RevId: 530751565 --- .../java/com/google/mediapipe/tasks/mediapipe_tasks_aar.bzl | 1 + 1 file changed, 1 insertion(+) diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/mediapipe_tasks_aar.bzl b/mediapipe/tasks/java/com/google/mediapipe/tasks/mediapipe_tasks_aar.bzl index d5188ae55..9d4fd00f6 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/mediapipe_tasks_aar.bzl +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/mediapipe_tasks_aar.bzl @@ -330,6 +330,7 @@ def _mediapipe_tasks_aar(name, srcs, manifest, java_proto_lite_targets, native_l "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:category", "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:classificationresult", "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:classifications", + "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:connection", "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:embedding", "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:embeddingresult", "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:landmark", From e391c76433cf6e1b27365cde20983fe2e8457db8 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 9 May 2023 18:42:28 -0700 Subject: [PATCH 260/753] Include object_detector_metadata_schema.fbs and image_segmenter_metadata_schema.fbs PiperOrigin-RevId: 530769920 --- setup.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a073128e7..892c6dca7 100644 --- a/setup.py +++ b/setup.py @@ -313,7 +313,11 @@ class GenerateMetadataSchema(build_ext.build_ext): _copy_to_build_lib_dir( self.build_lib, 'mediapipe/tasks/metadata/' + target + '_generated.py') - schema_file = 'mediapipe/tasks/metadata/metadata_schema.fbs' + for schema_file in [ + 'mediapipe/tasks/metadata/metadata_schema.fbs', + 'mediapipe/tasks/metadata/object_detector_metadata_schema.fbs', + 'mediapipe/tasks/metadata/image_segmenter_metadata_schema.fbs', + ]: shutil.copyfile(schema_file, os.path.join(self.build_lib + '/', schema_file)) From f8244247001dad457902c44e70147cf6df385fa2 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 9 May 2023 18:57:57 -0700 Subject: [PATCH 261/753] When returning multiple output streams together, keep them alive until callback. PiperOrigin-RevId: 530771884 --- mediapipe/tasks/web/core/task_runner.ts | 37 +++++++++++++++++++ .../tasks/web/core/task_runner_test_utils.ts | 7 +++- .../vision/image_segmenter/image_segmenter.ts | 7 ++++ .../interactive_segmenter.ts | 7 ++++ .../vision/pose_landmarker/pose_landmarker.ts | 8 ++++ 5 files changed, 64 insertions(+), 2 deletions(-) diff --git a/mediapipe/tasks/web/core/task_runner.ts b/mediapipe/tasks/web/core/task_runner.ts index 91a38cd44..efeffbb87 100644 --- a/mediapipe/tasks/web/core/task_runner.ts +++ b/mediapipe/tasks/web/core/task_runner.ts @@ -28,9 +28,16 @@ import {WasmFileset} from './wasm_fileset'; // None of the MP Tasks ship bundle assets. const NO_ASSETS = undefined; +// Internal stream names for temporarily keeping memory alive, then freeing it. +const FREE_MEMORY_STREAM = 'free_memory'; +const UNUSED_STREAM_SUFFIX = '_unused_out'; + // tslint:disable-next-line:enforce-name-casing const CachedGraphRunnerType = SupportModelResourcesGraphService(GraphRunner); +// The OSS JS API does not support the builder pattern. +// tslint:disable:jspb-use-builder-pattern + /** * An implementation of the GraphRunner that exposes the resource graph * service. @@ -64,6 +71,7 @@ export abstract class TaskRunner { protected abstract baseOptions: BaseOptionsProto; private processingErrors: Error[] = []; private latestOutputTimestamp = 0; + private keepaliveNode?: CalculatorGraphConfig.Node; /** * Creates a new instance of a Mediapipe Task. Determines if SIMD is @@ -177,6 +185,7 @@ export abstract class TaskRunner { this.graphRunner.registerModelResourcesGraphService(); this.graphRunner.setGraph(graphData, isBinary); + this.keepaliveNode = undefined; this.handleErrors(); } @@ -257,8 +266,36 @@ export abstract class TaskRunner { this.baseOptions.setAcceleration(acceleration); } + /** + * Adds a node to the graph to temporarily keep certain streams alive. + * NOTE: To use this call, PassThroughCalculator must be included in your wasm + * dependencies. + */ + protected addKeepaliveNode(graphConfig: CalculatorGraphConfig) { + this.keepaliveNode = new CalculatorGraphConfig.Node(); + this.keepaliveNode.setCalculator('PassThroughCalculator'); + this.keepaliveNode.addInputStream(FREE_MEMORY_STREAM); + this.keepaliveNode.addOutputStream( + FREE_MEMORY_STREAM + UNUSED_STREAM_SUFFIX); + graphConfig.addInputStream(FREE_MEMORY_STREAM); + graphConfig.addNode(this.keepaliveNode); + } + + /** Adds streams to the keepalive node to be kept alive until callback. */ + protected keepStreamAlive(streamName: string) { + this.keepaliveNode!.addInputStream(streamName); + this.keepaliveNode!.addOutputStream(streamName + UNUSED_STREAM_SUFFIX); + } + + /** Frees any streams being kept alive by the keepStreamAlive callback. */ + protected freeKeepaliveStreams() { + this.graphRunner.addBoolToStream( + true, FREE_MEMORY_STREAM, this.latestOutputTimestamp); + } + /** Closes and cleans up the resources held by this task. */ close(): void { + this.keepaliveNode = undefined; this.graphRunner.closeGraph(); } } diff --git a/mediapipe/tasks/web/core/task_runner_test_utils.ts b/mediapipe/tasks/web/core/task_runner_test_utils.ts index edf1d0d32..1532eb2a5 100644 --- a/mediapipe/tasks/web/core/task_runner_test_utils.ts +++ b/mediapipe/tasks/web/core/task_runner_test_utils.ts @@ -37,7 +37,7 @@ export function createSpyWasmModule(): SpyWasmModule { '_attachProtoVectorListener', '_free', '_waitUntilIdle', '_addStringToInputStream', '_registerModelResourcesGraphService', '_configureAudio', '_malloc', '_addProtoToInputStream', '_getGraphConfig', - '_closeGraph' + '_closeGraph', '_addBoolToInputStream' ]); spyWasmModule._getGraphConfig.and.callFake(() => { (spyWasmModule.simpleListeners![CALCULATOR_GRAPH_CONFIG_LISTENER_NAME] as @@ -81,7 +81,10 @@ export function verifyGraph( expectedBaseOptions?: FieldPathToValue, ): void { expect(tasksFake.graph).toBeDefined(); - expect(tasksFake.graph!.getNodeList().length).toBe(1); + // Our graphs should have at least one node in them for processing, and + // sometimes one additional one for keeping alive certain streams in memory. + expect(tasksFake.graph!.getNodeList().length).toBeGreaterThanOrEqual(1); + expect(tasksFake.graph!.getNodeList().length).toBeLessThanOrEqual(2); const node = tasksFake.graph!.getNodeList()[0].toObject(); expect(node).toEqual( jasmine.objectContaining({calculator: tasksFake.calculatorName})); diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts index 39e57d94e..b12adb0df 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts @@ -383,6 +383,10 @@ export class ImageSegmenter extends VisionTaskRunner { if (this.userCallback) { this.userCallback(this.result); + + // Free the image memory, now that we've kept all streams alive long + // enough to be returned in our callbacks. + this.freeKeepaliveStreams(); } } @@ -403,11 +407,13 @@ export class ImageSegmenter extends VisionTaskRunner { segmenterNode.setOptions(calculatorOptions); graphConfig.addNode(segmenterNode); + this.addKeepaliveNode(graphConfig); if (this.outputConfidenceMasks) { graphConfig.addOutputStream(CONFIDENCE_MASKS_STREAM); segmenterNode.addOutputStream( 'CONFIDENCE_MASKS:' + CONFIDENCE_MASKS_STREAM); + this.keepStreamAlive(CONFIDENCE_MASKS_STREAM); this.graphRunner.attachImageVectorListener( CONFIDENCE_MASKS_STREAM, (masks, timestamp) => { @@ -428,6 +434,7 @@ export class ImageSegmenter extends VisionTaskRunner { if (this.outputCategoryMask) { graphConfig.addOutputStream(CATEGORY_MASK_STREAM); segmenterNode.addOutputStream('CATEGORY_MASK:' + CATEGORY_MASK_STREAM); + this.keepStreamAlive(CATEGORY_MASK_STREAM); this.graphRunner.attachImageListener( CATEGORY_MASK_STREAM, (mask, timestamp) => { diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts index 2a51a5fcf..e3f79d26d 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts @@ -297,6 +297,10 @@ export class InteractiveSegmenter extends VisionTaskRunner { if (this.userCallback) { this.userCallback(this.result); + + // Free the image memory, now that we've kept all streams alive long + // enough to be returned in our callbacks. + this.freeKeepaliveStreams(); } } @@ -319,11 +323,13 @@ export class InteractiveSegmenter extends VisionTaskRunner { segmenterNode.setOptions(calculatorOptions); graphConfig.addNode(segmenterNode); + this.addKeepaliveNode(graphConfig); if (this.outputConfidenceMasks) { graphConfig.addOutputStream(CONFIDENCE_MASKS_STREAM); segmenterNode.addOutputStream( 'CONFIDENCE_MASKS:' + CONFIDENCE_MASKS_STREAM); + this.keepStreamAlive(CONFIDENCE_MASKS_STREAM); this.graphRunner.attachImageVectorListener( CONFIDENCE_MASKS_STREAM, (masks, timestamp) => { @@ -344,6 +350,7 @@ export class InteractiveSegmenter extends VisionTaskRunner { if (this.outputCategoryMask) { graphConfig.addOutputStream(CATEGORY_MASK_STREAM); segmenterNode.addOutputStream('CATEGORY_MASK:' + CATEGORY_MASK_STREAM); + this.keepStreamAlive(CATEGORY_MASK_STREAM); this.graphRunner.attachImageListener( CATEGORY_MASK_STREAM, (mask, timestamp) => { diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts index 87fdacbc2..0d3181aa0 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts @@ -376,6 +376,9 @@ export class PoseLandmarker extends VisionTaskRunner { if (this.userCallback) { this.userCallback(this.result as Required); + + // Free the image memory, now that we've finished our callback. + this.freeKeepaliveStreams(); } } @@ -437,6 +440,9 @@ export class PoseLandmarker extends VisionTaskRunner { landmarkerNode.setOptions(calculatorOptions); graphConfig.addNode(landmarkerNode); + // We only need to keep alive the image stream, since the protos are being + // deep-copied anyways via serialization+deserialization. + this.addKeepaliveNode(graphConfig); this.graphRunner.attachProtoVectorListener( NORM_LANDMARKS_STREAM, (binaryProto, timestamp) => { @@ -467,6 +473,8 @@ export class PoseLandmarker extends VisionTaskRunner { if (this.outputSegmentationMasks) { landmarkerNode.addOutputStream( 'SEGMENTATION_MASK:' + SEGMENTATION_MASK_STREAM); + this.keepStreamAlive(SEGMENTATION_MASK_STREAM); + this.graphRunner.attachImageVectorListener( SEGMENTATION_MASK_STREAM, (masks, timestamp) => { this.result.segmentationMasks = masks.map( From ea1643f7f89759ce1d2f915311fcf44080e8d2f8 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 9 May 2023 19:45:18 -0700 Subject: [PATCH 262/753] Internal update PiperOrigin-RevId: 530777692 --- mediapipe/tasks/cc/vision/face_detector/BUILD | 4 ++-- mediapipe/tasks/cc/vision/face_landmarker/BUILD | 16 ++-------------- mediapipe/tasks/cc/vision/face_stylizer/BUILD | 1 + .../tasks/cc/vision/interactive_segmenter/BUILD | 1 + mediapipe/tasks/python/text/BUILD | 1 - mediapipe/tasks/python/vision/BUILD | 4 ---- 6 files changed, 6 insertions(+), 21 deletions(-) diff --git a/mediapipe/tasks/cc/vision/face_detector/BUILD b/mediapipe/tasks/cc/vision/face_detector/BUILD index 8fd171dab..fbfd94628 100644 --- a/mediapipe/tasks/cc/vision/face_detector/BUILD +++ b/mediapipe/tasks/cc/vision/face_detector/BUILD @@ -13,8 +13,7 @@ # limitations under the License. package(default_visibility = [ - # "//mediapipe/tasks:internal", - "//visibility:public", + "//mediapipe/tasks:internal", ]) licenses(["notice"]) @@ -63,6 +62,7 @@ cc_library( name = "face_detector", srcs = ["face_detector.cc"], hdrs = ["face_detector.h"], + visibility = ["//visibility:public"], deps = [ ":face_detector_graph", "//mediapipe/framework/api2:builder", diff --git a/mediapipe/tasks/cc/vision/face_landmarker/BUILD b/mediapipe/tasks/cc/vision/face_landmarker/BUILD index e4756aab1..16de2271a 100644 --- a/mediapipe/tasks/cc/vision/face_landmarker/BUILD +++ b/mediapipe/tasks/cc/vision/face_landmarker/BUILD @@ -123,6 +123,7 @@ cc_library( name = "face_landmarker_result", srcs = ["face_landmarker_result.cc"], hdrs = ["face_landmarker_result.h"], + visibility = ["//visibility:public"], deps = [ "//mediapipe/framework/formats:classification_cc_proto", "//mediapipe/framework/formats:landmark_cc_proto", @@ -137,6 +138,7 @@ cc_library( name = "face_landmarker", srcs = ["face_landmarker.cc"], hdrs = ["face_landmarker.h"], + visibility = ["//visibility:public"], deps = [ ":face_landmarker_graph", ":face_landmarker_result", @@ -164,20 +166,6 @@ cc_library( ], ) -cc_library( - name = "face_landmarker_result_cc", - srcs = ["face_landmarker_result.cc"], - hdrs = ["face_landmarker_result.h"], - deps = [ - "//mediapipe/framework/formats:classification_cc_proto", - "//mediapipe/framework/formats:landmark_cc_proto", - "//mediapipe/framework/formats:matrix", - "//mediapipe/framework/formats:matrix_data_cc_proto", - "//mediapipe/tasks/cc/components/containers:classification_result", - "//mediapipe/tasks/cc/components/containers:landmark", - ], -) - cc_library( name = "face_landmarker_graph", srcs = ["face_landmarker_graph.cc"], diff --git a/mediapipe/tasks/cc/vision/face_stylizer/BUILD b/mediapipe/tasks/cc/vision/face_stylizer/BUILD index afc348174..72182f0c5 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/BUILD +++ b/mediapipe/tasks/cc/vision/face_stylizer/BUILD @@ -61,6 +61,7 @@ cc_library( name = "face_stylizer", srcs = ["face_stylizer.cc"], hdrs = ["face_stylizer.h"], + visibility = ["//visibility:public"], deps = [ ":face_stylizer_graph", # buildcleaner:keep "//mediapipe/framework/api2:builder", diff --git a/mediapipe/tasks/cc/vision/interactive_segmenter/BUILD b/mediapipe/tasks/cc/vision/interactive_segmenter/BUILD index 0a91b97e6..d02b5db36 100644 --- a/mediapipe/tasks/cc/vision/interactive_segmenter/BUILD +++ b/mediapipe/tasks/cc/vision/interactive_segmenter/BUILD @@ -22,6 +22,7 @@ cc_library( name = "interactive_segmenter", srcs = ["interactive_segmenter.cc"], hdrs = ["interactive_segmenter.h"], + visibility = ["//visibility:public"], deps = [ ":interactive_segmenter_graph", "//mediapipe/framework:calculator_cc_proto", diff --git a/mediapipe/tasks/python/text/BUILD b/mediapipe/tasks/python/text/BUILD index fa5e70b63..27100b2b4 100644 --- a/mediapipe/tasks/python/text/BUILD +++ b/mediapipe/tasks/python/text/BUILD @@ -23,7 +23,6 @@ py_library( srcs = [ "text_classifier.py", ], - visibility = ["//mediapipe/tasks:users"], deps = [ "//mediapipe/python:packet_creator", "//mediapipe/python:packet_getter", diff --git a/mediapipe/tasks/python/vision/BUILD b/mediapipe/tasks/python/vision/BUILD index dcd28dcf5..958cf0e0d 100644 --- a/mediapipe/tasks/python/vision/BUILD +++ b/mediapipe/tasks/python/vision/BUILD @@ -158,10 +158,6 @@ py_library( srcs = [ "hand_landmarker.py", ], - visibility = [ - "//mediapipe/model_maker/python/vision/gesture_recognizer:__subpackages__", - "//mediapipe/tasks:internal", - ], deps = [ "//mediapipe/framework/formats:classification_py_pb2", "//mediapipe/framework/formats:landmark_py_pb2", From a7ede9235c95d30db4fb913b3e1efe8aeacad5fc Mon Sep 17 00:00:00 2001 From: Mark McDonald Date: Tue, 9 May 2023 22:31:46 -0700 Subject: [PATCH 263/753] Internal change PiperOrigin-RevId: 530806084 --- docs/build_java_api_docs.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/build_java_api_docs.py b/docs/build_java_api_docs.py index eaa380f87..c30426557 100644 --- a/docs/build_java_api_docs.py +++ b/docs/build_java_api_docs.py @@ -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', From 419701c615b95a98ca0ba0a4598edc7a5963820e Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 10 May 2023 13:09:44 +0530 Subject: [PATCH 264/753] Removed opencv dependency from MPPVIsionTaskRunner --- mediapipe/tasks/ios/vision/core/BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/mediapipe/tasks/ios/vision/core/BUILD b/mediapipe/tasks/ios/vision/core/BUILD index 328d9e892..a97410e1a 100644 --- a/mediapipe/tasks/ios/vision/core/BUILD +++ b/mediapipe/tasks/ios/vision/core/BUILD @@ -62,6 +62,5 @@ objc_library( "//mediapipe/tasks/ios/core:MPPTaskRunner", "//third_party/apple_frameworks:UIKit", "@com_google_absl//absl/status:statusor", - "@ios_opencv//:OpencvFramework", ], ) From 1666f3ed80206e805df08653a204db354b5e6735 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 10 May 2023 12:17:50 -0700 Subject: [PATCH 265/753] Add .close() method to ImageSegmenterResult/InteractiveSegmenterResult/PoseLandmarkerResult PiperOrigin-RevId: 530973944 --- .../vision/image_segmenter/image_segmenter.ts | 51 ++++++-------- .../image_segmenter/image_segmenter_result.ts | 34 ++++++---- .../image_segmenter/image_segmenter_test.ts | 6 +- .../interactive_segmenter.ts | 46 ++++++------- .../interactive_segmenter_result.ts | 34 ++++++---- .../interactive_segmenter_test.ts | 6 +- .../vision/pose_landmarker/pose_landmarker.ts | 67 ++++++++----------- .../pose_landmarker/pose_landmarker_result.ts | 21 +++--- .../pose_landmarker/pose_landmarker_test.ts | 6 +- 9 files changed, 133 insertions(+), 138 deletions(-) diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts index b12adb0df..ee9caaa1f 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts @@ -22,6 +22,7 @@ import {ImageSegmenterGraphOptions as ImageSegmenterGraphOptionsProto} from '../ import {SegmenterOptions as SegmenterOptionsProto} from '../../../../tasks/cc/vision/image_segmenter/proto/segmenter_options_pb'; import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; +import {MPMask} from '../../../../tasks/web/vision/core/mask'; import {VisionGraphRunner, VisionTaskRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; import {LabelMapItem} from '../../../../util/label_map_pb'; import {ImageSource, WasmModule} from '../../../../web/graph_runner/graph_runner'; @@ -58,7 +59,8 @@ export type ImageSegmenterCallback = (result: ImageSegmenterResult) => void; /** Performs image segmentation on images. */ export class ImageSegmenter extends VisionTaskRunner { - private result: ImageSegmenterResult = {}; + private categoryMask?: MPMask; + private confidenceMasks?: MPMask[]; private labels: string[] = []; private userCallback?: ImageSegmenterCallback; private outputCategoryMask = DEFAULT_OUTPUT_CATEGORY_MASK; @@ -265,10 +267,7 @@ export class ImageSegmenter extends VisionTaskRunner { this.reset(); this.processImageData(image, imageProcessingOptions); - - if (!this.userCallback) { - return this.result; - } + return this.processResults(); } /** @@ -347,10 +346,7 @@ export class ImageSegmenter extends VisionTaskRunner { this.reset(); this.processVideoData(videoFrame, imageProcessingOptions, timestamp); - - if (!this.userCallback) { - return this.result; - } + return this.processResults(); } /** @@ -369,21 +365,20 @@ export class ImageSegmenter extends VisionTaskRunner { } private reset(): void { - this.result = {}; + this.categoryMask = undefined; + this.confidenceMasks = undefined; } - /** Invokes the user callback once all data has been received. */ - private maybeInvokeCallback(): void { - if (this.outputConfidenceMasks && !('confidenceMasks' in this.result)) { - return; - } - if (this.outputCategoryMask && !('categoryMask' in this.result)) { - return; - } - - if (this.userCallback) { - this.userCallback(this.result); - + private processResults(): ImageSegmenterResult|void { + try { + const result = + new ImageSegmenterResult(this.confidenceMasks, this.categoryMask); + if (this.userCallback) { + this.userCallback(result); + } else { + return result; + } + } finally { // Free the image memory, now that we've kept all streams alive long // enough to be returned in our callbacks. this.freeKeepaliveStreams(); @@ -417,17 +412,15 @@ export class ImageSegmenter extends VisionTaskRunner { this.graphRunner.attachImageVectorListener( CONFIDENCE_MASKS_STREAM, (masks, timestamp) => { - this.result.confidenceMasks = masks.map( + this.confidenceMasks = masks.map( wasmImage => this.convertToMPMask( wasmImage, /* shouldCopyData= */ !this.userCallback)); this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( CONFIDENCE_MASKS_STREAM, timestamp => { - this.result.confidenceMasks = undefined; + this.confidenceMasks = []; this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); } @@ -438,16 +431,14 @@ export class ImageSegmenter extends VisionTaskRunner { this.graphRunner.attachImageListener( CATEGORY_MASK_STREAM, (mask, timestamp) => { - this.result.categoryMask = this.convertToMPMask( + this.categoryMask = this.convertToMPMask( mask, /* shouldCopyData= */ !this.userCallback); this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( CATEGORY_MASK_STREAM, timestamp => { - this.result.categoryMask = undefined; + this.categoryMask = undefined; this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); } diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.ts index 25962d57e..9107a5c80 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.ts @@ -17,18 +17,26 @@ import {MPMask} from '../../../../tasks/web/vision/core/mask'; /** The output result of ImageSegmenter. */ -export declare interface ImageSegmenterResult { - /** - * Multiple masks represented as `Float32Array` or `WebGLTexture`-backed - * `MPImage`s where, for each mask, each pixel represents the prediction - * confidence, usually in the [0, 1] range. - */ - confidenceMasks?: MPMask[]; +export class ImageSegmenterResult { + constructor( + /** + * Multiple masks represented as `Float32Array` or `WebGLTexture`-backed + * `MPImage`s where, for each mask, each pixel represents the prediction + * confidence, usually in the [0, 1] range. + */ + readonly confidenceMasks?: MPMask[], + /** + * A category mask represented as a `Uint8ClampedArray` or + * `WebGLTexture`-backed `MPImage` where each pixel represents the class + * which the pixel in the original image was predicted to belong to. + */ + readonly categoryMask?: MPMask) {} - /** - * A category mask represented as a `Uint8ClampedArray` or - * `WebGLTexture`-backed `MPImage` where each pixel represents the class which - * the pixel in the original image was predicted to belong to. - */ - categoryMask?: MPMask; + /** Frees the resources held by the category and confidence masks. */ + close(): void { + this.confidenceMasks?.forEach(m => { + m.close(); + }); + this.categoryMask?.close(); + } } diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts index f9172ecd3..10983b488 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts @@ -263,7 +263,7 @@ describe('ImageSegmenter', () => { }); }); - it('invokes listener once masks are available', async () => { + it('invokes listener after masks are available', async () => { const categoryMask = new Uint8Array([1]); const confidenceMask = new Float32Array([0.0]); let listenerCalled = false; @@ -282,7 +282,7 @@ describe('ImageSegmenter', () => { {data: confidenceMask, width: 1, height: 1}, ], 1337); - expect(listenerCalled).toBeTrue(); + expect(listenerCalled).toBeFalse(); }); return new Promise(resolve => { @@ -307,6 +307,6 @@ describe('ImageSegmenter', () => { const result = imageSegmenter.segment({} as HTMLImageElement); expect(result.confidenceMasks![0]).toBeInstanceOf(MPMask); - result.confidenceMasks![0].close(); + result.close(); }); }); diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts index e3f79d26d..16bf10eeb 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts @@ -21,6 +21,7 @@ import {ImageSegmenterGraphOptions as ImageSegmenterGraphOptionsProto} from '../ import {SegmenterOptions as SegmenterOptionsProto} from '../../../../tasks/cc/vision/image_segmenter/proto/segmenter_options_pb'; import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; +import {MPMask} from '../../../../tasks/web/vision/core/mask'; import {RegionOfInterest} from '../../../../tasks/web/vision/core/types'; import {VisionGraphRunner, VisionTaskRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; import {Color as ColorProto} from '../../../../util/color_pb'; @@ -83,7 +84,8 @@ export type InteractiveSegmenterCallback = * - batch is always 1 */ export class InteractiveSegmenter extends VisionTaskRunner { - private result: InteractiveSegmenterResult = {}; + private categoryMask?: MPMask; + private confidenceMasks?: MPMask[]; private outputCategoryMask = DEFAULT_OUTPUT_CATEGORY_MASK; private outputConfidenceMasks = DEFAULT_OUTPUT_CONFIDENCE_MASKS; private userCallback?: InteractiveSegmenterCallback; @@ -276,28 +278,24 @@ export class InteractiveSegmenter extends VisionTaskRunner { this.reset(); this.processRenderData(roi, this.getSynctheticTimestamp()); this.processImageData(image, imageProcessingOptions); - - if (!this.userCallback) { - return this.result; - } + return this.processResults(); } private reset(): void { - this.result = {}; + this.confidenceMasks = undefined; + this.categoryMask = undefined; } - /** Invokes the user callback once all data has been received. */ - private maybeInvokeCallback(): void { - if (this.outputConfidenceMasks && !('confidenceMasks' in this.result)) { - return; - } - if (this.outputCategoryMask && !('categoryMask' in this.result)) { - return; - } - - if (this.userCallback) { - this.userCallback(this.result); - + private processResults(): InteractiveSegmenterResult|void { + try { + const result = new InteractiveSegmenterResult( + this.confidenceMasks, this.categoryMask); + if (this.userCallback) { + this.userCallback(result); + } else { + return result; + } + } finally { // Free the image memory, now that we've kept all streams alive long // enough to be returned in our callbacks. this.freeKeepaliveStreams(); @@ -333,17 +331,15 @@ export class InteractiveSegmenter extends VisionTaskRunner { this.graphRunner.attachImageVectorListener( CONFIDENCE_MASKS_STREAM, (masks, timestamp) => { - this.result.confidenceMasks = masks.map( + this.confidenceMasks = masks.map( wasmImage => this.convertToMPMask( wasmImage, /* shouldCopyData= */ !this.userCallback)); this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( CONFIDENCE_MASKS_STREAM, timestamp => { - this.result.confidenceMasks = undefined; + this.confidenceMasks = []; this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); } @@ -354,16 +350,14 @@ export class InteractiveSegmenter extends VisionTaskRunner { this.graphRunner.attachImageListener( CATEGORY_MASK_STREAM, (mask, timestamp) => { - this.result.categoryMask = this.convertToMPMask( + this.categoryMask = this.convertToMPMask( mask, /* shouldCopyData= */ !this.userCallback); this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( CATEGORY_MASK_STREAM, timestamp => { - this.result.categoryMask = undefined; + this.categoryMask = undefined; this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); } diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.ts index e773b5e64..5da7e4df3 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.ts @@ -17,18 +17,26 @@ import {MPMask} from '../../../../tasks/web/vision/core/mask'; /** The output result of InteractiveSegmenter. */ -export declare interface InteractiveSegmenterResult { - /** - * Multiple masks represented as `Float32Array` or `WebGLTexture`-backed - * `MPImage`s where, for each mask, each pixel represents the prediction - * confidence, usually in the [0, 1] range. - */ - confidenceMasks?: MPMask[]; +export class InteractiveSegmenterResult { + constructor( + /** + * Multiple masks represented as `Float32Array` or `WebGLTexture`-backed + * `MPImage`s where, for each mask, each pixel represents the prediction + * confidence, usually in the [0, 1] range. + */ + readonly confidenceMasks?: MPMask[], + /** + * A category mask represented as a `Uint8ClampedArray` or + * `WebGLTexture`-backed `MPImage` where each pixel represents the class + * which the pixel in the original image was predicted to belong to. + */ + readonly categoryMask?: MPMask) {} - /** - * A category mask represented as a `Uint8ClampedArray` or - * `WebGLTexture`-backed `MPImage` where each pixel represents the class which - * the pixel in the original image was predicted to belong to. - */ - categoryMask?: MPMask; + /** Frees the resources held by the category and confidence masks. */ + close(): void { + this.confidenceMasks?.forEach(m => { + m.close(); + }); + this.categoryMask?.close(); + } } diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts index c5603c5c6..6550202e0 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts @@ -277,7 +277,7 @@ describe('InteractiveSegmenter', () => { }); }); - it('invokes listener once masks are avaiblae', async () => { + it('invokes listener after masks are avaiblae', async () => { const categoryMask = new Uint8Array([1]); const confidenceMask = new Float32Array([0.0]); let listenerCalled = false; @@ -296,7 +296,7 @@ describe('InteractiveSegmenter', () => { {data: confidenceMask, width: 1, height: 1}, ], 1337); - expect(listenerCalled).toBeTrue(); + expect(listenerCalled).toBeFalse(); }); return new Promise(resolve => { @@ -322,6 +322,6 @@ describe('InteractiveSegmenter', () => { const result = interactiveSegmenter.segment({} as HTMLImageElement, KEYPOINT); expect(result.confidenceMasks![0]).toBeInstanceOf(MPMask); - result.confidenceMasks![0].close(); + result.close(); }); }); diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts index 0d3181aa0..927b3c24b 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker.ts @@ -21,9 +21,11 @@ import {BaseOptions as BaseOptionsProto} from '../../../../tasks/cc/core/proto/b import {PoseDetectorGraphOptions} from '../../../../tasks/cc/vision/pose_detector/proto/pose_detector_graph_options_pb'; import {PoseLandmarkerGraphOptions} from '../../../../tasks/cc/vision/pose_landmarker/proto/pose_landmarker_graph_options_pb'; import {PoseLandmarksDetectorGraphOptions} from '../../../../tasks/cc/vision/pose_landmarker/proto/pose_landmarks_detector_graph_options_pb'; +import {Landmark, NormalizedLandmark} from '../../../../tasks/web/components/containers/landmark'; import {convertToLandmarks, convertToWorldLandmarks} from '../../../../tasks/web/components/processors/landmark_result'; import {WasmFileset} from '../../../../tasks/web/core/wasm_fileset'; import {ImageProcessingOptions} from '../../../../tasks/web/vision/core/image_processing_options'; +import {MPMask} from '../../../../tasks/web/vision/core/mask'; import {Connection} from '../../../../tasks/web/vision/core/types'; import {VisionGraphRunner, VisionTaskRunner} from '../../../../tasks/web/vision/core/vision_task_runner'; import {ImageSource, WasmModule} from '../../../../web/graph_runner/graph_runner'; @@ -61,7 +63,9 @@ export type PoseLandmarkerCallback = (result: PoseLandmarkerResult) => void; /** Performs pose landmarks detection on images. */ export class PoseLandmarker extends VisionTaskRunner { - private result: Partial = {}; + private landmarks: NormalizedLandmark[][] = []; + private worldLandmarks: Landmark[][] = []; + private segmentationMasks?: MPMask[]; private outputSegmentationMasks = false; private userCallback?: PoseLandmarkerCallback; private readonly options: PoseLandmarkerGraphOptions; @@ -268,10 +272,7 @@ export class PoseLandmarker extends VisionTaskRunner { this.resetResults(); this.processImageData(image, imageProcessingOptions); - - if (!this.userCallback) { - return this.result as PoseLandmarkerResult; - } + return this.processResults(); } /** @@ -352,31 +353,25 @@ export class PoseLandmarker extends VisionTaskRunner { this.resetResults(); this.processVideoData(videoFrame, imageProcessingOptions, timestamp); - - if (!this.userCallback) { - return this.result as PoseLandmarkerResult; - } + return this.processResults(); } private resetResults(): void { - this.result = {}; + this.landmarks = []; + this.worldLandmarks = []; + this.segmentationMasks = undefined; } - /** Invokes the user callback once all data has been received. */ - private maybeInvokeCallback(): void { - if (!('landmarks' in this.result)) { - return; - } - if (!('worldLandmarks' in this.result)) { - return; - } - if (this.outputSegmentationMasks && !('segmentationMasks' in this.result)) { - return; - } - - if (this.userCallback) { - this.userCallback(this.result as Required); - + private processResults(): PoseLandmarkerResult|void { + try { + const result = new PoseLandmarkerResult( + this.landmarks, this.worldLandmarks, this.segmentationMasks); + if (this.userCallback) { + this.userCallback(result); + } else { + return result; + } + } finally { // Free the image memory, now that we've finished our callback. this.freeKeepaliveStreams(); } @@ -396,11 +391,11 @@ export class PoseLandmarker extends VisionTaskRunner { * Converts raw data into a landmark, and adds it to our landmarks list. */ private addJsLandmarks(data: Uint8Array[]): void { - this.result.landmarks = []; + this.landmarks = []; for (const binaryProto of data) { const poseLandmarksProto = NormalizedLandmarkList.deserializeBinary(binaryProto); - this.result.landmarks.push(convertToLandmarks(poseLandmarksProto)); + this.landmarks.push(convertToLandmarks(poseLandmarksProto)); } } @@ -409,11 +404,11 @@ export class PoseLandmarker extends VisionTaskRunner { * worldLandmarks list. */ private adddJsWorldLandmarks(data: Uint8Array[]): void { - this.result.worldLandmarks = []; + this.worldLandmarks = []; for (const binaryProto of data) { const poseWorldLandmarksProto = LandmarkList.deserializeBinary(binaryProto); - this.result.worldLandmarks.push( + this.worldLandmarks.push( convertToWorldLandmarks(poseWorldLandmarksProto)); } } @@ -448,26 +443,22 @@ export class PoseLandmarker extends VisionTaskRunner { NORM_LANDMARKS_STREAM, (binaryProto, timestamp) => { this.addJsLandmarks(binaryProto); this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( NORM_LANDMARKS_STREAM, timestamp => { - this.result.landmarks = []; + this.landmarks = []; this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); this.graphRunner.attachProtoVectorListener( WORLD_LANDMARKS_STREAM, (binaryProto, timestamp) => { this.adddJsWorldLandmarks(binaryProto); this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( WORLD_LANDMARKS_STREAM, timestamp => { - this.result.worldLandmarks = []; + this.worldLandmarks = []; this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); if (this.outputSegmentationMasks) { @@ -477,17 +468,15 @@ export class PoseLandmarker extends VisionTaskRunner { this.graphRunner.attachImageVectorListener( SEGMENTATION_MASK_STREAM, (masks, timestamp) => { - this.result.segmentationMasks = masks.map( + this.segmentationMasks = masks.map( wasmImage => this.convertToMPMask( wasmImage, /* shouldCopyData= */ !this.userCallback)); this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); this.graphRunner.attachEmptyPacketListener( SEGMENTATION_MASK_STREAM, timestamp => { - this.result.segmentationMasks = []; + this.segmentationMasks = []; this.setLatestOutputTimestamp(timestamp); - this.maybeInvokeCallback(); }); } diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.ts index 96e698a85..92ba804d6 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_result.ts @@ -24,13 +24,18 @@ export {Category, Landmark, NormalizedLandmark}; * Represents the pose landmarks deection results generated by `PoseLandmarker`. * Each vector element represents a single pose detected in the image. */ -export declare interface PoseLandmarkerResult { - /** Pose landmarks of detected poses. */ - landmarks: NormalizedLandmark[][]; +export class PoseLandmarkerResult { + constructor(/** Pose landmarks of detected poses. */ + readonly landmarks: NormalizedLandmark[][], + /** Pose landmarks in world coordinates of detected poses. */ + readonly worldLandmarks: Landmark[][], + /** Segmentation mask for the detected pose. */ + readonly segmentationMasks?: MPMask[]) {} - /** Pose landmarks in world coordinates of detected poses. */ - worldLandmarks: Landmark[][]; - - /** Segmentation mask for the detected pose. */ - segmentationMasks?: MPMask[]; + /** Frees the resources held by the segmentation masks. */ + close(): void { + this.segmentationMasks?.forEach(m => { + m.close(); + }); + } } diff --git a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts index d4a49db97..9131b93ec 100644 --- a/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts +++ b/mediapipe/tasks/web/vision/pose_landmarker/pose_landmarker_test.ts @@ -287,7 +287,7 @@ describe('PoseLandmarker', () => { }); }); - it('invokes listener once masks are available', (done) => { + it('invokes listener after masks are available', (done) => { const landmarksProto = [createLandmarks().serializeBinary()]; const worldLandmarksProto = [createWorldLandmarks().serializeBinary()]; const masks = [ @@ -309,13 +309,12 @@ describe('PoseLandmarker', () => { expect(listenerCalled).toBeFalse(); expect(listenerCalled).toBeFalse(); poseLandmarker.listeners.get('segmentation_masks')!(masks, 1337); - expect(listenerCalled).toBeTrue(); - done(); }); // Invoke the pose landmarker poseLandmarker.detect({} as HTMLImageElement, () => { listenerCalled = true; + done(); }); }); @@ -336,5 +335,6 @@ describe('PoseLandmarker', () => { expect(poseLandmarker.fakeWasmModule._waitUntilIdle).toHaveBeenCalled(); expect(result.landmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); expect(result.worldLandmarks).toEqual([[{'x': 0, 'y': 0, 'z': 0}]]); + result.close(); }); }); From 64af91910766f05221a8fc237b76522433685fe2 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 10 May 2023 14:31:20 -0700 Subject: [PATCH 266/753] Internal change PiperOrigin-RevId: 531007009 --- mediapipe/model_maker/python/vision/gesture_recognizer/BUILD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mediapipe/model_maker/python/vision/gesture_recognizer/BUILD b/mediapipe/model_maker/python/vision/gesture_recognizer/BUILD index 27f8934b3..ecd2a7125 100644 --- a/mediapipe/model_maker/python/vision/gesture_recognizer/BUILD +++ b/mediapipe/model_maker/python/vision/gesture_recognizer/BUILD @@ -56,6 +56,7 @@ py_test( srcs = ["dataset_test.py"], data = [":testdata"], tags = [ + "not_run:arm", "notsan", "requires-net:external", ], @@ -141,6 +142,7 @@ py_test( data = [":testdata"], shard_count = 2, tags = [ + "not_run:arm", "notsan", "requires-net:external", ], From 4c32ff493eccaa0ae0c86b51d84297484c1831b9 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 11 May 2023 14:04:40 +0530 Subject: [PATCH 267/753] Fixed typo in MPPObjectDetectorOptions --- .../vision/object_detector/sources/MPPObjectDetectorOptions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h index c91e170c9..988cd4f2e 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h @@ -67,7 +67,7 @@ NS_SWIFT_NAME(ObjectDetectorOptions) /** * Running mode of the object detector task. Defaults to `MPPRunningModeImage`. - * `MPPImageClassifier` can be created with one of the following running modes: + * `MPPObjectDetector` can be created with one of the following running modes: * 1. `MPPRunningModeImage`: The mode for performing object detection on single image inputs. * 2. `MPPRunningModeVideo`: The mode for performing object detection on the decoded frames of a * video. From 12ba644393fecf676c8d9f16ce7cc93cd762049a Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Fri, 12 May 2023 12:55:07 -0700 Subject: [PATCH 268/753] Internal change PiperOrigin-RevId: 531582116 --- mediapipe/tasks/cc/text/text_classifier/BUILD | 1 + mediapipe/tasks/cc/text/text_embedder/BUILD | 1 + mediapipe/tasks/python/test/text/BUILD | 2 ++ mediapipe/tasks/python/test/vision/BUILD | 8 ++++++++ 4 files changed, 12 insertions(+) diff --git a/mediapipe/tasks/cc/text/text_classifier/BUILD b/mediapipe/tasks/cc/text/text_classifier/BUILD index 4b244c00d..28b5d709e 100644 --- a/mediapipe/tasks/cc/text/text_classifier/BUILD +++ b/mediapipe/tasks/cc/text/text_classifier/BUILD @@ -75,6 +75,7 @@ cc_test( "//mediapipe/tasks/testdata/text:bert_text_classifier_models", "//mediapipe/tasks/testdata/text:text_classifier_models", ], + tags = ["not_run:arm"], deps = [ ":text_classifier", ":text_classifier_test_utils", diff --git a/mediapipe/tasks/cc/text/text_embedder/BUILD b/mediapipe/tasks/cc/text/text_embedder/BUILD index e8deee241..76025b3cf 100644 --- a/mediapipe/tasks/cc/text/text_embedder/BUILD +++ b/mediapipe/tasks/cc/text/text_embedder/BUILD @@ -81,6 +81,7 @@ cc_test( "//mediapipe/tasks/testdata/text:regex_embedding_with_metadata", "//mediapipe/tasks/testdata/text:universal_sentence_encoder_qa", ], + tags = ["not_run:arm"], deps = [ ":text_embedder", "//mediapipe/framework/deps:file_path", diff --git a/mediapipe/tasks/python/test/text/BUILD b/mediapipe/tasks/python/test/text/BUILD index be352c84d..2ecbcb048 100644 --- a/mediapipe/tasks/python/test/text/BUILD +++ b/mediapipe/tasks/python/test/text/BUILD @@ -25,6 +25,7 @@ py_test( "//mediapipe/tasks/testdata/text:bert_text_classifier_models", "//mediapipe/tasks/testdata/text:text_classifier_models", ], + tags = ["not_run:arm"], deps = [ "//mediapipe/tasks/python/components/containers:category", "//mediapipe/tasks/python/components/containers:classification_result", @@ -42,6 +43,7 @@ py_test( "//mediapipe/tasks/testdata/text:regex_embedding_with_metadata", "//mediapipe/tasks/testdata/text:universal_sentence_encoder_qa", ], + tags = ["not_run:arm"], deps = [ "//mediapipe/tasks/python/components/containers:embedding_result", "//mediapipe/tasks/python/core:base_options", diff --git a/mediapipe/tasks/python/test/vision/BUILD b/mediapipe/tasks/python/test/vision/BUILD index d555402b8..9efec7f2a 100644 --- a/mediapipe/tasks/python/test/vision/BUILD +++ b/mediapipe/tasks/python/test/vision/BUILD @@ -25,6 +25,7 @@ py_test( "//mediapipe/tasks/testdata/vision:test_images", "//mediapipe/tasks/testdata/vision:test_models", ], + tags = ["not_run:arm"], deps = [ "//mediapipe/python:_framework_bindings", "//mediapipe/tasks/python/components/containers:bounding_box", @@ -45,6 +46,7 @@ py_test( "//mediapipe/tasks/testdata/vision:test_images", "//mediapipe/tasks/testdata/vision:test_models", ], + tags = ["not_run:arm"], deps = [ "//mediapipe/python:_framework_bindings", "//mediapipe/tasks/python/components/containers:category", @@ -65,6 +67,7 @@ py_test( "//mediapipe/tasks/testdata/vision:test_images", "//mediapipe/tasks/testdata/vision:test_models", ], + tags = ["not_run:arm"], deps = [ "//mediapipe/python:_framework_bindings", "//mediapipe/tasks/python/components/containers:embedding_result", @@ -84,6 +87,7 @@ py_test( "//mediapipe/tasks/testdata/vision:test_images", "//mediapipe/tasks/testdata/vision:test_models", ], + tags = ["not_run:arm"], deps = [ "//mediapipe/python:_framework_bindings", "//mediapipe/tasks/python/core:base_options", @@ -101,6 +105,7 @@ py_test( "//mediapipe/tasks/testdata/vision:test_models", "//mediapipe/tasks/testdata/vision:test_protos", ], + tags = ["not_run:arm"], deps = [ "//mediapipe/framework/formats:detection_py_pb2", "//mediapipe/python:_framework_bindings", @@ -124,6 +129,7 @@ py_test( "//mediapipe/tasks/testdata/vision:test_models", "//mediapipe/tasks/testdata/vision:test_protos", ], + tags = ["not_run:arm"], deps = [ "//mediapipe/framework/formats:classification_py_pb2", "//mediapipe/framework/formats:landmark_py_pb2", @@ -148,6 +154,7 @@ py_test( "//mediapipe/tasks/testdata/vision:test_models", "//mediapipe/tasks/testdata/vision:test_protos", ], + tags = ["not_run:arm"], deps = [ "//mediapipe/python:_framework_bindings", "//mediapipe/tasks/cc/components/containers/proto:landmarks_detection_result_py_pb2", @@ -171,6 +178,7 @@ py_test( "//mediapipe/tasks/testdata/vision:test_models", "//mediapipe/tasks/testdata/vision:test_protos", ], + tags = ["not_run:arm"], deps = [ "//mediapipe/python:_framework_bindings", "//mediapipe/tasks/cc/components/containers/proto:landmarks_detection_result_py_pb2", From fc9538533c16751ca5e8df754441aa54bb79a9e6 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Mon, 15 May 2023 05:53:16 -0700 Subject: [PATCH 269/753] 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 --- mediapipe/calculators/core/BUILD | 11 ++-- .../calculators/core/begin_loop_calculator.cc | 12 +++++ .../calculators/core/begin_loop_calculator.h | 54 +++++++++++-------- .../calculators/core/end_loop_calculator.cc | 8 +++ .../calculators/core/end_loop_calculator.h | 28 ++-------- 5 files changed, 62 insertions(+), 51 deletions(-) diff --git a/mediapipe/calculators/core/BUILD b/mediapipe/calculators/core/BUILD index d5ba6c74f..3294c0383 100644 --- a/mediapipe/calculators/core/BUILD +++ b/mediapipe/calculators/core/BUILD @@ -192,17 +192,18 @@ 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_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 +216,20 @@ 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/memory", + "@com_google_absl//absl/status", "@org_tensorflow//tensorflow/lite:framework", ], alwayslink = 1, diff --git a/mediapipe/calculators/core/begin_loop_calculator.cc b/mediapipe/calculators/core/begin_loop_calculator.cc index 441c66937..ac74bb382 100644 --- a/mediapipe/calculators/core/begin_loop_calculator.cc +++ b/mediapipe/calculators/core/begin_loop_calculator.cc @@ -17,10 +17,12 @@ #include #include "mediapipe/framework/formats/detection.pb.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 +62,14 @@ REGISTER_CALCULATOR(BeginLoopUint64tCalculator); typedef BeginLoopCalculator> BeginLoopTensorCalculator; REGISTER_CALCULATOR(BeginLoopTensorCalculator); +// A calculator to process std::vector. +typedef BeginLoopCalculator> + BeginLoopImageFrameCalculator; +REGISTER_CALCULATOR(BeginLoopImageFrameCalculator); + +// A calculator to process std::vector. +typedef BeginLoopCalculator> + BeginLoopGpuBufferCalculator; +REGISTER_CALCULATOR(BeginLoopGpuBufferCalculator); + } // namespace mediapipe diff --git a/mediapipe/calculators/core/begin_loop_calculator.h b/mediapipe/calculators/core/begin_loop_calculator.h index 81fff39da..c0b3022d4 100644 --- a/mediapipe/calculators/core/begin_loop_calculator.h +++ b/mediapipe/calculators/core/begin_loop_calculator.h @@ -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 and vector. +// First, instantiate specializations in the loop calculators' implementations +// if missing: +// BeginLoopInputTCalculator = BeginLoopCalculator +// EndLoopOutputTCalculator = EndLoopCalculator +// 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 class BeginLoopCalculator : public CalculatorBase { using ItemT = typename IterableT::value_type; diff --git a/mediapipe/calculators/core/end_loop_calculator.cc b/mediapipe/calculators/core/end_loop_calculator.cc index b3b889ecd..dea2b6cad 100644 --- a/mediapipe/calculators/core/end_loop_calculator.cc +++ b/mediapipe/calculators/core/end_loop_calculator.cc @@ -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,6 +70,12 @@ REGISTER_CALCULATOR(EndLoopMatrixCalculator); typedef EndLoopCalculator> EndLoopTensorCalculator; REGISTER_CALCULATOR(EndLoopTensorCalculator); +typedef EndLoopCalculator> EndLoopImageFrameCalculator; +REGISTER_CALCULATOR(EndLoopImageFrameCalculator); + +typedef EndLoopCalculator> EndLoopGpuBufferCalculator; +REGISTER_CALCULATOR(EndLoopGpuBufferCalculator); + typedef EndLoopCalculator> EndLoopImageCalculator; REGISTER_CALCULATOR(EndLoopImageCalculator); diff --git a/mediapipe/calculators/core/end_loop_calculator.h b/mediapipe/calculators/core/end_loop_calculator.h index 2598194e6..1e258f046 100644 --- a/mediapipe/calculators/core/end_loop_calculator.h +++ b/mediapipe/calculators/core/end_loop_calculator.h @@ -17,13 +17,11 @@ #include +#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 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(); if (item_ptr_or.ok()) { input_stream_collection_->push_back(std::move(*item_ptr_or.value())); From e0eef9791ebb84825197b49e09132d3643564ee2 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Mon, 15 May 2023 08:04:01 -0700 Subject: [PATCH 270/753] Internal change PiperOrigin-RevId: 532113907 --- mediapipe/calculators/image/BUILD | 7 ++++++- mediapipe/calculators/tensor/BUILD | 1 + mediapipe/framework/BUILD | 1 + mediapipe/framework/formats/BUILD | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/mediapipe/calculators/image/BUILD b/mediapipe/calculators/image/BUILD index 6de54189f..20e5ebda4 100644 --- a/mediapipe/calculators/image/BUILD +++ b/mediapipe/calculators/image/BUILD @@ -317,6 +317,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 +651,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 +773,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", diff --git a/mediapipe/calculators/tensor/BUILD b/mediapipe/calculators/tensor/BUILD index 5d52dda0f..4893b3b79 100644 --- a/mediapipe/calculators/tensor/BUILD +++ b/mediapipe/calculators/tensor/BUILD @@ -1052,6 +1052,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", diff --git a/mediapipe/framework/BUILD b/mediapipe/framework/BUILD index 126261c90..8224b73fc 100644 --- a/mediapipe/framework/BUILD +++ b/mediapipe/framework/BUILD @@ -1405,6 +1405,7 @@ cc_test( "calculator_graph_test.cc", ], linkstatic = 1, + tags = ["not_run:arm"], visibility = ["//visibility:public"], deps = [ ":calculator_framework", diff --git a/mediapipe/framework/formats/BUILD b/mediapipe/framework/formats/BUILD index 496094c5f..b23209f7d 100644 --- a/mediapipe/framework/formats/BUILD +++ b/mediapipe/framework/formats/BUILD @@ -481,6 +481,7 @@ cc_library( cc_test( name = "tensor_test", srcs = ["tensor_test.cc"], + tags = ["not_run:arm"], deps = [ ":tensor", "//mediapipe/framework/port:gtest_main", From d7fa4b95b550267b395eb52365e40168057ddead Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 16 May 2023 08:53:33 -0700 Subject: [PATCH 271/753] Internal change. PiperOrigin-RevId: 532474319 --- mediapipe/framework/formats/tensor.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/mediapipe/framework/formats/tensor.cc b/mediapipe/framework/formats/tensor.cc index 9d75bcbaf..0445712c5 100644 --- a/mediapipe/framework/formats/tensor.cc +++ b/mediapipe/framework/formats/tensor.cc @@ -117,8 +117,8 @@ MtlBufferView MtlBufferView::GetReadView(const Tensor& tensor, << "Tensor must be written prior to read from."; LOG_IF(FATAL, !(tensor.valid_ & (Tensor::kValidCpu | Tensor::kValidMetalBuffer))) - << "Tensor conversion between different GPU resources is not supported " - "yet."; + << "Tensor conversion between different GPU backing formats is not " + "supported yet."; auto lock(absl::make_unique(&tensor.view_mutex_)); tensor.valid_ |= Tensor::kValidMetalBuffer; AllocateMtlBuffer(tensor, [command_buffer device]); @@ -164,8 +164,8 @@ Tensor::OpenGlTexture2dView Tensor::GetOpenGlTexture2dReadView() const { LOG_IF(FATAL, valid_ == kValidNone) << "Tensor must be written prior to read from."; LOG_IF(FATAL, !(valid_ & (kValidCpu | kValidOpenGlTexture2d))) - << "Tensor conversion between different GPU resources is not supported " - "yet."; + << "Tensor conversion between different GPU backing formats is not " + "supported yet."; auto lock = absl::make_unique(&view_mutex_); AllocateOpenGlTexture2d(); if (!(valid_ & kValidOpenGlTexture2d)) { @@ -335,7 +335,8 @@ Tensor::OpenGlBufferView Tensor::GetOpenGlBufferReadView() const { kValidAHardwareBuffer | #endif // MEDIAPIPE_TENSOR_USE_AHWB kValidOpenGlBuffer))) - << "Tensor conversion between different GPU resources is not supported."; + << "Tensor conversion between different GPU backing formats is not " + "supported yet."; auto lock(absl::make_unique(&view_mutex_)); AllocateOpenGlBuffer(); if (!(valid_ & kValidOpenGlBuffer)) { From 8bf6c63e924236a1f28bd4cf121acbed4c95808e Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Tue, 16 May 2023 09:23:27 -0700 Subject: [PATCH 272/753] Write TFLite model to Wasm file system PiperOrigin-RevId: 532482502 --- mediapipe/tasks/web/core/BUILD | 1 + mediapipe/tasks/web/core/task_runner.ts | 27 +++++++++++--- mediapipe/tasks/web/core/task_runner_test.ts | 35 ++++++++++++++++--- .../tasks/web/core/task_runner_test_utils.ts | 10 +++--- mediapipe/web/graph_runner/graph_runner.ts | 8 +++++ 5 files changed, 68 insertions(+), 13 deletions(-) diff --git a/mediapipe/tasks/web/core/BUILD b/mediapipe/tasks/web/core/BUILD index a417d4d72..0c102a86a 100644 --- a/mediapipe/tasks/web/core/BUILD +++ b/mediapipe/tasks/web/core/BUILD @@ -57,6 +57,7 @@ mediapipe_ts_library( deps = [ ":core", ":task_runner", + ":task_runner_test_utils", "//mediapipe/calculators/tensor:inference_calculator_jspb_proto", "//mediapipe/tasks/cc/core/proto:base_options_jspb_proto", "//mediapipe/web/graph_runner:graph_runner_ts", diff --git a/mediapipe/tasks/web/core/task_runner.ts b/mediapipe/tasks/web/core/task_runner.ts index efeffbb87..8c6aae6cf 100644 --- a/mediapipe/tasks/web/core/task_runner.ts +++ b/mediapipe/tasks/web/core/task_runner.ts @@ -111,6 +111,7 @@ export abstract class TaskRunner { throw new Error( 'Cannot set both baseOptions.modelAssetPath and baseOptions.modelAssetBuffer'); } else if (!(this.baseOptions.getModelAsset()?.hasFileContent() || + this.baseOptions.getModelAsset()?.hasFileName() || options.baseOptions?.modelAssetBuffer || options.baseOptions?.modelAssetPath)) { throw new Error( @@ -131,7 +132,19 @@ export abstract class TaskRunner { } }) .then(buffer => { - this.setExternalFile(new Uint8Array(buffer)); + try { + // Try to delete file as we cannot overwite an existing file using + // our current API. + this.graphRunner.wasmModule.FS_unlink('/model.dat'); + } catch { + } + // TODO: Consider passing the model to the graph as an + // input side packet as this might reduce copies. + this.graphRunner.wasmModule.FS_createDataFile( + '/', 'model.dat', new Uint8Array(buffer), + /* canRead= */ true, /* canWrite= */ false, + /* canOwn= */ false); + this.setExternalFile('/model.dat'); this.refreshGraph(); this.onGraphRefreshed(); }); @@ -236,10 +249,16 @@ export abstract class TaskRunner { } /** Configures the `externalFile` option */ - private setExternalFile(modelAssetBuffer?: Uint8Array): void { + private setExternalFile(modelAssetPath?: string): void; + private setExternalFile(modelAssetBuffer?: Uint8Array): void; + private setExternalFile(modelAssetPathOrBuffer?: Uint8Array|string): void { const externalFile = this.baseOptions.getModelAsset() || new ExternalFile(); - if (modelAssetBuffer) { - externalFile.setFileContent(modelAssetBuffer); + if (typeof modelAssetPathOrBuffer === 'string') { + externalFile.setFileName(modelAssetPathOrBuffer); + externalFile.clearFileContent(); + } else if (modelAssetPathOrBuffer instanceof Uint8Array) { + externalFile.setFileContent(modelAssetPathOrBuffer); + externalFile.clearFileName(); } this.baseOptions.setModelAsset(externalFile); } diff --git a/mediapipe/tasks/web/core/task_runner_test.ts b/mediapipe/tasks/web/core/task_runner_test.ts index 873e6fea1..a68ba224a 100644 --- a/mediapipe/tasks/web/core/task_runner_test.ts +++ b/mediapipe/tasks/web/core/task_runner_test.ts @@ -19,11 +19,16 @@ import 'jasmine'; import {InferenceCalculatorOptions} from '../../../calculators/tensor/inference_calculator_pb'; import {BaseOptions as BaseOptionsProto} from '../../../tasks/cc/core/proto/base_options_pb'; import {TaskRunner} from '../../../tasks/web/core/task_runner'; +import {createSpyWasmModule, SpyWasmModule} from '../../../tasks/web/core/task_runner_test_utils'; import {ErrorListener} from '../../../web/graph_runner/graph_runner'; // Placeholder for internal dependency on trusted resource URL builder import {CachedGraphRunner} from './task_runner'; -import {TaskRunnerOptions} from './task_runner_options.d'; +import {TaskRunnerOptions} from './task_runner_options'; + +type Writeable = { + -readonly[P in keyof T]: T[P] +}; class TaskRunnerFake extends TaskRunner { private errorListener: ErrorListener|undefined; @@ -40,7 +45,8 @@ class TaskRunnerFake extends TaskRunner { 'setAutoRenderToScreen', 'setGraph', 'finishProcessing', 'registerModelResourcesGraphService', 'attachErrorListener' ])); - const graphRunner = this.graphRunner as jasmine.SpyObj; + const graphRunner = + this.graphRunner as jasmine.SpyObj>; expect(graphRunner.setAutoRenderToScreen).toHaveBeenCalled(); graphRunner.attachErrorListener.and.callFake(listener => { this.errorListener = listener; @@ -51,6 +57,11 @@ class TaskRunnerFake extends TaskRunner { graphRunner.finishProcessing.and.callFake(() => { this.throwErrors(); }); + graphRunner.wasmModule = createSpyWasmModule(); + } + + get wasmModule(): SpyWasmModule { + return this.graphRunner.wasmModule as SpyWasmModule; } enqueueError(message: string): void { @@ -117,6 +128,21 @@ describe('TaskRunner', () => { nnapi: undefined, }, }; + const mockFileResult = { + modelAsset: { + fileContent: '', + fileName: '/model.dat', + fileDescriptorMeta: undefined, + filePointerMeta: undefined, + }, + useStreamMode: false, + acceleration: { + xnnpack: undefined, + gpu: undefined, + tflite: {}, + nnapi: undefined, + }, + }; let fetchSpy: jasmine.Spy; let taskRunner: TaskRunnerFake; @@ -204,12 +230,13 @@ describe('TaskRunner', () => { }).not.toThrowError(); }); - it('downloads model', async () => { + it('writes model to file system', async () => { await taskRunner.setOptions( {baseOptions: {modelAssetPath: `foo`}}); expect(fetchSpy).toHaveBeenCalled(); - expect(taskRunner.baseOptions.toObject()).toEqual(mockBytesResult); + expect(taskRunner.wasmModule.FS_createDataFile).toHaveBeenCalled(); + expect(taskRunner.baseOptions.toObject()).toEqual(mockFileResult); }); it('does not download model when bytes are provided', async () => { diff --git a/mediapipe/tasks/web/core/task_runner_test_utils.ts b/mediapipe/tasks/web/core/task_runner_test_utils.ts index 1532eb2a5..777cb8704 100644 --- a/mediapipe/tasks/web/core/task_runner_test_utils.ts +++ b/mediapipe/tasks/web/core/task_runner_test_utils.ts @@ -33,11 +33,11 @@ export declare type SpyWasmModule = jasmine.SpyObj; */ export function createSpyWasmModule(): SpyWasmModule { const spyWasmModule = jasmine.createSpyObj([ - '_setAutoRenderToScreen', 'stringToNewUTF8', '_attachProtoListener', - '_attachProtoVectorListener', '_free', '_waitUntilIdle', - '_addStringToInputStream', '_registerModelResourcesGraphService', - '_configureAudio', '_malloc', '_addProtoToInputStream', '_getGraphConfig', - '_closeGraph', '_addBoolToInputStream' + 'FS_createDataFile', 'FS_unlink', '_addBoolToInputStream', + '_addProtoToInputStream', '_addStringToInputStream', '_attachProtoListener', + '_attachProtoVectorListener', '_closeGraph', '_configureAudio', '_free', + '_getGraphConfig', '_malloc', '_registerModelResourcesGraphService', + '_setAutoRenderToScreen', '_waitUntilIdle', 'stringToNewUTF8' ]); spyWasmModule._getGraphConfig.and.callFake(() => { (spyWasmModule.simpleListeners![CALCULATOR_GRAPH_CONFIG_LISTENER_NAME] as diff --git a/mediapipe/web/graph_runner/graph_runner.ts b/mediapipe/web/graph_runner/graph_runner.ts index 615971cb3..3444653f8 100644 --- a/mediapipe/web/graph_runner/graph_runner.ts +++ b/mediapipe/web/graph_runner/graph_runner.ts @@ -59,6 +59,14 @@ export declare interface WasmModule { HEAPU32: Uint32Array; HEAPF32: Float32Array; HEAPF64: Float64Array; + FS_createDataFile: + (parent: string, name: string, data: Uint8Array, canRead: boolean, + canWrite: boolean, canOwn: boolean) => void; + FS_createPath: + (parent: string, name: string, canRead: boolean, + canWrite: boolean) => void; + FS_unlink(path: string): void; + errorListener?: ErrorListener; _bindTextureToCanvas: () => boolean; _changeBinaryGraph: (size: number, dataPtr: number) => void; From d53fbf2aebc8c0239a2f432698bb0ea24119daad Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Tue, 16 May 2023 10:42:50 -0700 Subject: [PATCH 273/753] Update links in README.md PiperOrigin-RevId: 532506851 --- mediapipe/tasks/web/audio/README.md | 14 +++-- mediapipe/tasks/web/text/README.md | 24 ++++---- mediapipe/tasks/web/vision/README.md | 90 ++++++++++++++++++---------- 3 files changed, 80 insertions(+), 48 deletions(-) diff --git a/mediapipe/tasks/web/audio/README.md b/mediapipe/tasks/web/audio/README.md index ed2543c7a..c712a9c6f 100644 --- a/mediapipe/tasks/web/audio/README.md +++ b/mediapipe/tasks/web/audio/README.md @@ -2,30 +2,32 @@ This package contains the audio tasks for MediaPipe. -## Audio Classification +## Audio Classifier -The MediaPipe Audio Classification task performs classification on audio data. +The MediaPipe Audio Classifier task performs classification on audio data. ``` const audio = await FilesetResolver.forAudioTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-audio@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-audio/wasm" ); const audioClassifier = await AudioClassifier.createFromModelPath(audio, - "https://storage.googleapis.com/mediapipe-tasks/audio_classifier/yamnet_audio_classifier_with_metadata.tflite" + "https://storage.googleapis.com/mediapipe-models/audio_classifier/yamnet/float32/1/yamnet.tflite ); const classifications = audioClassifier.classify(audioData); ``` +For more information, refer to the [Audio Classifier](https://developers.google.com/mediapipe/solutions/audio/audio_classifier/web_js) documentation. + ## Audio Embedding The MediaPipe Audio Embedding task extracts embeddings from audio data. ``` const audio = await FilesetResolver.forAudioTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-audio@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-audio/wasm" ); const audioEmbedder = await AudioEmbedder.createFromModelPath(audio, - "model.tflite" + "https://storage.googleapis.com/mediapipe-assets/yamnet_embedding_metadata.tflite?generation=1668295071595506" ); const embeddings = audioEmbedder.embed(audioData); ``` diff --git a/mediapipe/tasks/web/text/README.md b/mediapipe/tasks/web/text/README.md index 4a26f5b9d..bec50ed92 100644 --- a/mediapipe/tasks/web/text/README.md +++ b/mediapipe/tasks/web/text/README.md @@ -2,47 +2,51 @@ This package contains the text tasks for MediaPipe. -## Language Detection +## Language Detector The MediaPipe Language Detector task predicts the language of an input text. ``` const text = await FilesetResolver.forTextTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-text@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-text/wasm" ); const languageDetector = await LanguageDetector.createFromModelPath(text, - "model.tflite" + "https://storage.googleapis.com/mediapipe-models/language_detector/language_detector/float32/1/language_detector.tflite ); const result = languageDetector.detect(textData); ``` -## Text Classification +For more information, refer to the [Language Detector](https://developers.google.com/mediapipe/solutions/text/language_detector/web_js) documentation. + +## Text Classifier The MediaPipe Text Classifier task lets you classify text into a set of defined categories, such as positive or negative sentiment. ``` const text = await FilesetResolver.forTextTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-text@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-text/wasm" ); const textClassifier = await TextClassifier.createFromModelPath(text, - "https://storage.googleapis.com/mediapipe-tasks/text_classifier/bert_text_classifier.tflite" + "https://storage.googleapis.com/mediapipe-models/text_classifier/bert_classifier/float32/1/bert_classifier.tflite" ); const classifications = textClassifier.classify(textData); ``` For more information, refer to the [Text Classification](https://developers.google.com/mediapipe/solutions/text/text_classifier/web_js) documentation. -## Text Embedding +## Text Embedder -The MediaPipe Text Embedding task extracts embeddings from text data. +The MediaPipe Text Embedder task extracts embeddings from text data. ``` const text = await FilesetResolver.forTextTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-text@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-text/wasm" ); const textEmbedder = await TextEmbedder.createFromModelPath(text, - "https://storage.googleapis.com/mediapipe-tasks/text_embedder/mobilebert_embedding_with_metadata.tflite" + "https://storage.googleapis.com/mediapipe-models/text_embedder/universal_sentence_encoder/float32/1/universal_sentence_encoder.tflite" ); const embeddings = textEmbedder.embed(textData); ``` + +For more information, refer to the [Text Embedder](https://developers.google.com/mediapipe/solutions/text/text_embedder/web_js) documentation. diff --git a/mediapipe/tasks/web/vision/README.md b/mediapipe/tasks/web/vision/README.md index a9e4e7147..816ef9e4f 100644 --- a/mediapipe/tasks/web/vision/README.md +++ b/mediapipe/tasks/web/vision/README.md @@ -2,23 +2,25 @@ This package contains the vision tasks for MediaPipe. -## Face Detection +## Face Detector The MediaPipe Face Detector task lets you detect the presence and location of faces within images or videos. ``` const vision = await FilesetResolver.forVisionTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm" ); const faceDetector = await FaceDetector.createFromModelPath(vision, - "https://storage.googleapis.com/mediapipe-tasks/face_detector/face_detection_short_range.tflite" + "https://storage.googleapis.com/mediapipe-models/face_detector/blaze_face_short_range/float16/1/blaze_face_short_range.tflite" ); const image = document.getElementById("image") as HTMLImageElement; const detections = faceDetector.detect(image); ``` -## Face Landmark Detection +For more information, refer to the [Face Detector](https://developers.google.com/mediapipe/solutions/vision/face_detector/web_js) documentation. + +## Face Landmarker The MediaPipe Face Landmarker task lets you detect the landmarks of faces in an image. You can use this Task to localize key points of a face and render @@ -26,31 +28,33 @@ visual effects over the faces. ``` const vision = await FilesetResolver.forVisionTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm" ); const faceLandmarker = await FaceLandmarker.createFromModelPath(vision, - "https://storage.googleapis.com/mediapipe-tasks/face_landmarker/face_landmarker.task" + "https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task`" ); const image = document.getElementById("image") as HTMLImageElement; const landmarks = faceLandmarker.detect(image); ``` +For more information, refer to the [Face Landmarker](https://developers.google.com/mediapipe/solutions/vision/face_landmarker/web_js) documentation. + ## Face Stylizer The MediaPipe Face Stylizer lets you perform face stylization on images. ``` const vision = await FilesetResolver.forVisionTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm" ); const faceStylizer = await FaceStylizer.createFromModelPath(vision, - "https://storage.googleapis.com/mediapipe-tasks/face_stylizer/face_stylizer_with_metadata.tflite" + "https://storage.googleapis.com/mediapipe-models/face_stylizer/blaze_face_stylizer/float32/1/blaze_face_stylizer.task" ); const image = document.getElementById("image") as HTMLImageElement; const stylizedImage = faceStylizer.stylize(image); ``` -## Gesture Recognition +## Gesture Recognizer The MediaPipe Gesture Recognizer task lets you recognize hand gestures in real time, and provides the recognized hand gesture results along with the landmarks @@ -59,16 +63,18 @@ from a user, and invoke application features that correspond to those gestures. ``` const vision = await FilesetResolver.forVisionTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm" ); const gestureRecognizer = await GestureRecognizer.createFromModelPath(vision, - "https://storage.googleapis.com/mediapipe-tasks/gesture_recognizer/gesture_recognizer.task" + "hhttps://storage.googleapis.com/mediapipe-models/gesture_recognizer/gesture_recognizer/float16/1/gesture_recognizer.task" ); const image = document.getElementById("image") as HTMLImageElement; const recognitions = gestureRecognizer.recognize(image); ``` -## Hand Landmark Detection +For more information, refer to the [Gesture Recognizer](https://developers.google.com/mediapipe/solutions/vision/gesture_recognizer/web_js) documentation. + +## Hand Landmarker The MediaPipe Hand Landmarker task lets you detect the landmarks of the hands in an image. You can use this Task to localize key points of the hands and render @@ -76,18 +82,18 @@ visual effects over the hands. ``` const vision = await FilesetResolver.forVisionTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm" ); const handLandmarker = await HandLandmarker.createFromModelPath(vision, - "https://storage.googleapis.com/mediapipe-tasks/hand_landmarker/hand_landmarker.task" + "https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task" ); const image = document.getElementById("image") as HTMLImageElement; const landmarks = handLandmarker.detect(image); ``` -For more information, refer to the [Handlandmark Detection](https://developers.google.com/mediapipe/solutions/vision/hand_landmarker/web_js) documentation. +For more information, refer to the [Hand Landmarker](https://developers.google.com/mediapipe/solutions/vision/hand_landmarker/web_js) documentation. -## Image Classification +## Image Classifier The MediaPipe Image Classifier task lets you perform classification on images. You can use this task to identify what an image represents among a set of @@ -95,27 +101,42 @@ categories defined at training time. ``` const vision = await FilesetResolver.forVisionTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm" ); const imageClassifier = await ImageClassifier.createFromModelPath(vision, - "https://storage.googleapis.com/mediapipe-tasks/image_classifier/efficientnet_lite0_uint8.tflite" + "https://storage.googleapis.com/mediapipe-models/image_classifier/efficientnet_lite0/float32/1/efficientnet_lite0.tflite" ); const image = document.getElementById("image") as HTMLImageElement; const classifications = imageClassifier.classify(image); ``` -For more information, refer to the [Image Classification](https://developers.google.com/mediapipe/solutions/vision/image_classifier/web_js) documentation. +For more information, refer to the [Image Classifier](https://developers.google.com/mediapipe/solutions/vision/image_classifier/web_js) documentation. -## Image Segmentation +## Image Embedder + +The MediaPipe Image Embedder extracts embeddings from an image. + +``` +const vision = await FilesetResolver.forVisionTasks( + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm" +); +const imageEmbedder = await ImageEmbedder.createFromModelPath(vision, + "https://storage.googleapis.com/mediapipe-models/image_embedder/mobilenet_v3_small/float32/1/mobilenet_v3_small.tflite" +); +const image = document.getElementById("image") as HTMLImageElement; +const embeddings = imageSegmenter.embed(image); +``` + +## Image Segmenter The MediaPipe Image Segmenter lets you segment an image into categories. ``` const vision = await FilesetResolver.forVisionTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm" ); const imageSegmenter = await ImageSegmenter.createFromModelPath(vision, - "https://storage.googleapis.com/mediapipe-tasks/image_segmenter/selfie_segmentation.tflite" + "https://storage.googleapis.com/mediapipe-models/image_segmenter/deeplab_v3/float32/1/deeplab_v3.tflite" ); const image = document.getElementById("image") as HTMLImageElement; imageSegmenter.segment(image, (masks, width, height) => { @@ -123,18 +144,20 @@ imageSegmenter.segment(image, (masks, width, height) => { }); ``` -## Interactive Segmentation +For more information, refer to the [Image Segmenter](https://developers.google.com/mediapipe/solutions/vision/image_segmenter/web_js) documentation. + +## Interactive Segmenter The MediaPipe Interactive Segmenter lets you select a region of interest to segment an image by. ``` const vision = await FilesetResolver.forVisionTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm" ); const interactiveSegmenter = await InteractiveSegmenter.createFromModelPath( vision, - "https://storage.googleapis.com/mediapipe-tasks/interactive_segmenter/ptm_512_hdt_ptm_woid.tflite + "https://storage.googleapis.com/mediapipe-models/interactive_segmenter/magic_touch/float32/1/magic_touch.tflite" ); const image = document.getElementById("image") as HTMLImageElement; interactiveSegmenter.segment(image, { keypoint: { x: 0.1, y: 0.2 } }, @@ -142,17 +165,19 @@ interactiveSegmenter.segment(image, { keypoint: { x: 0.1, y: 0.2 } }, ); ``` -## Object Detection +For more information, refer to the [Interactive Segmenter](https://developers.google.com/mediapipe/solutions/vision/interactive_segmenter/web_js) documentation. + +## Object Detector The MediaPipe Object Detector task lets you detect the presence and location of multiple classes of objects within images or videos. ``` const vision = await FilesetResolver.forVisionTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm" ); const objectDetector = await ObjectDetector.createFromModelPath(vision, - "https://storage.googleapis.com/mediapipe-tasks/object_detector/efficientdet_lite0_uint8.tflite" + "https://storage.googleapis.com/mediapipe-models/object_detector/efficientdet_lite0/float16/1/efficientdet_lite0.tflite" ); const image = document.getElementById("image") as HTMLImageElement; const detections = objectDetector.detect(image); @@ -160,8 +185,7 @@ const detections = objectDetector.detect(image); For more information, refer to the [Object Detector](https://developers.google.com/mediapipe/solutions/vision/object_detector/web_js) documentation. - -## Pose Landmark Detection +## Pose Landmarker The MediaPipe Pose Landmarker task lets you detect the landmarks of body poses in an image. You can use this Task to localize key points of a pose and render @@ -169,11 +193,13 @@ visual effects over the body. ``` const vision = await FilesetResolver.forVisionTasks( - "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm" + "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm" ); const poseLandmarker = await PoseLandmarker.createFromModelPath(vision, - "model.task" + "https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task ); const image = document.getElementById("image") as HTMLImageElement; const landmarks = poseLandmarker.detect(image); ``` + +For more information, refer to the [Pose Landmarker](https://developers.google.com/mediapipe/solutions/vision/pose_landmarker/web_js) documentation. From 024f782cd9c26951dd72cacf4aaf57d59550c55e Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Tue, 16 May 2023 10:44:01 -0700 Subject: [PATCH 274/753] Warn users that do not invoke "close()" PiperOrigin-RevId: 532507235 --- mediapipe/tasks/web/vision/core/image.ts | 23 +++++++++++++++++++- mediapipe/tasks/web/vision/core/mask.ts | 27 +++++++++++++++++++++--- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index 4a7b6dce7..3b067bd78 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -16,6 +16,9 @@ import {assertNotNull, MPImageShaderContext} from '../../../../tasks/web/vision/core/image_shader_context'; +/** Number of instances a user can keep alive before we raise a warning. */ +const INSTANCE_COUNT_WARNING_THRESHOLD = 250; + /** The underlying type of the image. */ enum MPImageType { /** Represents the native `ImageData` type. */ @@ -52,6 +55,12 @@ export type MPImageContainer = ImageData|ImageBitmap|WebGLTexture; export class MPImage { private gl?: WebGL2RenderingContext; + /** + * A counter to track the number of instances of MPImage that own resources.. + * This is used to raise a warning if the user does not close the instances. + */ + private static instancesBeforeWarning = INSTANCE_COUNT_WARNING_THRESHOLD; + /** @hideconstructor */ constructor( private readonly containers: MPImageContainer[], @@ -64,7 +73,16 @@ export class MPImage { readonly width: number, /** Returns the height of the image. */ readonly height: number, - ) {} + ) { + if (this.ownsImageBitmap || this.ownsWebGLTexture) { + --MPImage.instancesBeforeWarning; + if (MPImage.instancesBeforeWarning === 0) { + console.error( + 'You seem to be creating MPImage instances without invoking ' + + '.close(). This leaks resources.'); + } + } + } /** Returns whether this `MPImage` contains a mask of type `ImageData`. */ hasImageData(): boolean { @@ -391,6 +409,9 @@ export class MPImage { const gl = this.getGL(); gl.deleteTexture(this.getContainer(MPImageType.WEBGL_TEXTURE)!); } + + // User called close(). We no longer issue warning. + MPImage.instancesBeforeWarning = -1; } } diff --git a/mediapipe/tasks/web/vision/core/mask.ts b/mediapipe/tasks/web/vision/core/mask.ts index 13deab3fc..d7cf59e5f 100644 --- a/mediapipe/tasks/web/vision/core/mask.ts +++ b/mediapipe/tasks/web/vision/core/mask.ts @@ -16,6 +16,9 @@ import {assertNotNull, MPImageShaderContext} from '../../../../tasks/web/vision/core/image_shader_context'; +/** Number of instances a user can keep alive before we raise a warning. */ +const INSTANCE_COUNT_WARNING_THRESHOLD = 250; + /** The underlying type of the image. */ enum MPMaskType { /** Represents the native `UInt8Array` type. */ @@ -47,6 +50,12 @@ export type MPMaskContainer = Uint8Array|Float32Array|WebGLTexture; export class MPMask { private gl?: WebGL2RenderingContext; + /** + * A counter to track the number of instances of MPMask that own resources. + * This is used to raise a warning if the user does not close the instances. + */ + private static instancesBeforeWarning = INSTANCE_COUNT_WARNING_THRESHOLD; + /** @hideconstructor */ constructor( private readonly containers: MPMaskContainer[], @@ -58,7 +67,16 @@ export class MPMask { readonly width: number, /** Returns the height of the mask. */ readonly height: number, - ) {} + ) { + if (this.ownsWebGLTexture) { + --MPMask.instancesBeforeWarning; + if (MPMask.instancesBeforeWarning === 0) { + console.error( + 'You seem to be creating MPMask instances without invoking ' + + '.close(). This leaks resources.'); + } + } + } /** Returns whether this `MPMask` contains a mask of type `Uint8Array`. */ hasUint8Array(): boolean { @@ -88,8 +106,8 @@ export class MPMask { /** * Returns the underlying mask as a single channel `Float32Array`. Note that - * this involves an expensive GPU to CPU transfer if the current mask is only - * available as a `WebGLTexture`. + * this involves an expensive GPU to CPU transfer if the current mask is + * only available as a `WebGLTexture`. * * @return The current mask as a Float32Array. */ @@ -311,6 +329,9 @@ export class MPMask { const gl = this.getGL(); gl.deleteTexture(this.getContainer(MPMaskType.WEBGL_TEXTURE)!); } + + // User called close(). We no longer issue warning. + MPMask.instancesBeforeWarning = -1; } } From 609a57f167b0a39bac24a342e80f76a4ce02bbcc Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 16 May 2023 15:52:52 -0700 Subject: [PATCH 275/753] Internal change PiperOrigin-RevId: 532597768 --- mediapipe/framework/mediapipe_cc_test.bzl | 1 + 1 file changed, 1 insertion(+) diff --git a/mediapipe/framework/mediapipe_cc_test.bzl b/mediapipe/framework/mediapipe_cc_test.bzl index fe0d44e0c..0fc0a462d 100644 --- a/mediapipe/framework/mediapipe_cc_test.bzl +++ b/mediapipe/framework/mediapipe_cc_test.bzl @@ -20,6 +20,7 @@ def mediapipe_cc_test( open_gl_driver = None, emulator_mini_boot = True, requires_full_emulation = True, + android_devices = {}, # wasm_web_test arguments browsers = None, **kwargs): From 5af496201b9c4bb4502d03fd891a1e36d20b0efc Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 16 May 2023 16:06:17 -0700 Subject: [PATCH 276/753] internal updating of flatbuffers PiperOrigin-RevId: 532601578 --- .../flatbuffers_lib/flatbuffers_lib.cc | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/mediapipe/tasks/python/metadata/flatbuffers_lib/flatbuffers_lib.cc b/mediapipe/tasks/python/metadata/flatbuffers_lib/flatbuffers_lib.cc index aa61ec910..0c251c69e 100644 --- a/mediapipe/tasks/python/metadata/flatbuffers_lib/flatbuffers_lib.cc +++ b/mediapipe/tasks/python/metadata/flatbuffers_lib/flatbuffers_lib.cc @@ -42,17 +42,17 @@ PYBIND11_MODULE(_pywrap_flatbuffers, m) { contents.length()); }); m.def("generate_text_file", &flatbuffers::GenerateTextFile); - m.def( - "generate_text", - [](const flatbuffers::Parser& parser, - const std::string& buffer) -> std::string { - std::string text; - if (!flatbuffers::GenerateText( - parser, reinterpret_cast(buffer.c_str()), &text)) { - return ""; - } - return text; - }); + m.def("generate_text", + [](const flatbuffers::Parser& parser, + const std::string& buffer) -> std::string { + std::string text; + const char* result = flatbuffers::GenerateText( + parser, reinterpret_cast(buffer.c_str()), &text); + if (result) { + return ""; + } + return text; + }); } } // namespace support From 4f8520af1073ef7b78f446111eb332397d7fb03a Mon Sep 17 00:00:00 2001 From: vrabaud Date: Tue, 16 May 2023 16:46:39 -0700 Subject: [PATCH 277/753] Internal change PiperOrigin-RevId: 532611846 --- mediapipe/util/tracking/region_flow_computation.cc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/mediapipe/util/tracking/region_flow_computation.cc b/mediapipe/util/tracking/region_flow_computation.cc index b6704cc61..7f67c3934 100644 --- a/mediapipe/util/tracking/region_flow_computation.cc +++ b/mediapipe/util/tracking/region_flow_computation.cc @@ -2096,12 +2096,6 @@ bool RegionFlowComputation::GainCorrectFrame(const cv::Mat& reference_frame, void RegionFlowComputation::WideBaselineMatchFeatures( FrameTrackingData* from_data_ptr, FrameTrackingData* to_data_ptr, TrackedFeatureList* results) { -#if (defined(__ANDROID__) || defined(__APPLE__) || defined(__EMSCRIPTEN__)) && \ - !defined(CV_WRAPPER_3X) - LOG(FATAL) << "Supported on only with OpenCV 3.0. " - << "Use bazel build flag : --define CV_WRAPPER=3X"; -#else // (defined(__ANDROID__) || defined(__APPLE__) || - // defined(__EMSCRIPTEN__)) && !defined(CV_WRAPPER_3X) results->clear(); const auto& frame1 = from_data_ptr->frame; @@ -2174,8 +2168,6 @@ void RegionFlowComputation::WideBaselineMatchFeatures( results->push_back(tracked_feature); } } -#endif // (defined(__ANDROID__) || defined(__APPLE__) || - // defined(__EMSCRIPTEN__)) && !defined(CV_WRAPPER_3X) } void RegionFlowComputation::RemoveAbsentFeatures( From 45addac249b065c5dd0bdf4b348990f9a981b101 Mon Sep 17 00:00:00 2001 From: kinaryml Date: Wed, 17 May 2023 10:55:40 +0530 Subject: [PATCH 278/753] Testing MediaPipe Python with GPU support --- mediapipe/tasks/python/core/BUILD | 2 + mediapipe/tasks/python/core/base_options.py | 27 ++++-- setup.py | 102 +++++++++++++++----- 3 files changed, 96 insertions(+), 35 deletions(-) diff --git a/mediapipe/tasks/python/core/BUILD b/mediapipe/tasks/python/core/BUILD index f90826354..c0abefdde 100644 --- a/mediapipe/tasks/python/core/BUILD +++ b/mediapipe/tasks/python/core/BUILD @@ -34,6 +34,8 @@ py_library( ], deps = [ ":optional_dependencies", + "//mediapipe/calculators/tensor/inference_calculator_py_pb2", + "//mediapipe/tasks/cc/core/proto:acceleration_py_pb2", "//mediapipe/tasks/cc/core/proto:base_options_py_pb2", "//mediapipe/tasks/cc/core/proto:external_file_py_pb2", ], diff --git a/mediapipe/tasks/python/core/base_options.py b/mediapipe/tasks/python/core/base_options.py index 90ef045b8..8247f15bd 100644 --- a/mediapipe/tasks/python/core/base_options.py +++ b/mediapipe/tasks/python/core/base_options.py @@ -14,13 +14,18 @@ """Base options for MediaPipe Task APIs.""" import dataclasses +import enum import os from typing import Any, Optional +from mediapipe.calculators.tensor import inference_calculator_pb2 +from mediapipe.tasks.cc.core.proto import acceleration_pb2 from mediapipe.tasks.cc.core.proto import base_options_pb2 from mediapipe.tasks.cc.core.proto import external_file_pb2 from mediapipe.tasks.python.core.optional_dependencies import doc_controls +_DelegateProto = inference_calculator_pb2.InferenceCalculatorOptions.Delegate +_AccelerationProto = acceleration_pb2.Acceleration _BaseOptionsProto = base_options_pb2.BaseOptions _ExternalFileProto = external_file_pb2.ExternalFile @@ -42,10 +47,13 @@ class BaseOptions: model_asset_path: Path to the model asset file. model_asset_buffer: The model asset file contents as bytes. """ + class Delegate(enum.Enum): + CPU = 0 + GPU = 1 model_asset_path: Optional[str] = None model_asset_buffer: Optional[bytes] = None - # TODO: Allow Python API to specify acceleration settings. + delegate: Optional[Delegate] = None @doc_controls.do_not_generate_docs def to_pb2(self) -> _BaseOptionsProto: @@ -55,17 +63,16 @@ class BaseOptions: else: full_path = None + if self.delegate == BaseOptions.Delegate.GPU: + acceleration_proto = _AccelerationProto(gpu=_DelegateProto.Gpu()) + else: + acceleration_proto = _AccelerationProto(tflite=_DelegateProto.TfLite()) + return _BaseOptionsProto( model_asset=_ExternalFileProto( - file_name=full_path, file_content=self.model_asset_buffer)) - - @classmethod - @doc_controls.do_not_generate_docs - def create_from_pb2(cls, pb2_obj: _BaseOptionsProto) -> 'BaseOptions': - """Creates a `BaseOptions` object from the given protobuf object.""" - return BaseOptions( - model_asset_path=pb2_obj.model_asset.file_name, - model_asset_buffer=pb2_obj.model_asset.file_content) + file_name=full_path, file_content=self.model_asset_buffer), + acceleration=acceleration_proto + ) def __eq__(self, other: Any) -> bool: """Checks if this object is equal to the given object. diff --git a/setup.py b/setup.py index 892c6dca7..0712a95b0 100644 --- a/setup.py +++ b/setup.py @@ -245,15 +245,28 @@ class BuildModules(build_ext.build_ext): sys.stderr.write('downloading file: %s\n' % external_file) self._download_external_file(external_file) + # CPU binary graphs + # binary_graphs = [ + # 'face_detection/face_detection_short_range_cpu', + # 'face_detection/face_detection_full_range_cpu', + # 'face_landmark/face_landmark_front_cpu', + # 'hand_landmark/hand_landmark_tracking_cpu', + # 'holistic_landmark/holistic_landmark_cpu', 'objectron/objectron_cpu', + # 'pose_landmark/pose_landmark_cpu', + # 'selfie_segmentation/selfie_segmentation_cpu' + # ] + + # GPU binary graphs binary_graphs = [ - 'face_detection/face_detection_short_range_cpu', - 'face_detection/face_detection_full_range_cpu', - 'face_landmark/face_landmark_front_cpu', - 'hand_landmark/hand_landmark_tracking_cpu', - 'holistic_landmark/holistic_landmark_cpu', 'objectron/objectron_cpu', - 'pose_landmark/pose_landmark_cpu', - 'selfie_segmentation/selfie_segmentation_cpu' + 'face_detection/face_detection_short_range_gpu', + 'face_detection/face_detection_full_range_gpu', + 'face_landmark/face_landmark_front_gpu', + 'hand_landmark/hand_landmark_tracking_gpu', + 'holistic_landmark/holistic_landmark_gpu', 'objectron/objectron_gpu', + 'pose_landmark/pose_landmark_gpu', + 'selfie_segmentation/selfie_segmentation_gpu' ] + for elem in binary_graphs: binary_graph = os.path.join('mediapipe/modules/', elem) sys.stderr.write('generating binarypb: %s\n' % binary_graph) @@ -271,23 +284,42 @@ class BuildModules(build_ext.build_ext): sys.exit(-1) _copy_to_build_lib_dir(self.build_lib, external_file) - def _generate_binary_graph(self, binary_graph_target): - """Generate binary graph for a particular MediaPipe binary graph target.""" + # def _generate_binary_graph(self, binary_graph_target): + # """Generate binary graph for a particular MediaPipe binary graph target.""" + # + # bazel_command = [ + # 'bazel', + # 'build', + # '--compilation_mode=opt', + # '--copt=-DNDEBUG', + # '--define=MEDIAPIPE_DISABLE_GPU=1', + # '--action_env=PYTHON_BIN_PATH=' + _normalize_path(sys.executable), + # binary_graph_target, + # ] + # if not self.link_opencv and not IS_WINDOWS: + # bazel_command.append('--define=OPENCV=source') + # if subprocess.call(bazel_command) != 0: + # sys.exit(-1) + # _copy_to_build_lib_dir(self.build_lib, binary_graph_target + '.binarypb') - bazel_command = [ - 'bazel', - 'build', - '--compilation_mode=opt', - '--copt=-DNDEBUG', - '--define=MEDIAPIPE_DISABLE_GPU=1', - '--action_env=PYTHON_BIN_PATH=' + _normalize_path(sys.executable), - binary_graph_target, - ] - if not self.link_opencv and not IS_WINDOWS: - bazel_command.append('--define=OPENCV=source') - if subprocess.call(bazel_command) != 0: - sys.exit(-1) - _copy_to_build_lib_dir(self.build_lib, binary_graph_target + '.binarypb') + def _generate_binary_graph(self, binary_graph_target): + """Generate binary graph for a particular MediaPipe binary graph target.""" + + bazel_command = [ + 'bazel', + 'build', + '--compilation_mode=opt', + '--copt=-DNDEBUG', + '--copt=-DMESA_EGL_NO_X11_HEADERS', + '--copt=-DEGL_NO_X11', + '--action_env=PYTHON_BIN_PATH=' + _normalize_path(sys.executable), + binary_graph_target, + ] + if not self.link_opencv and not IS_WINDOWS: + bazel_command.append('--define=OPENCV=source') + if subprocess.call(bazel_command) != 0: + sys.exit(-1) + _copy_to_build_lib_dir(self.build_lib, binary_graph_target + '.binarypb') class GenerateMetadataSchema(build_ext.build_ext): @@ -300,11 +332,21 @@ class GenerateMetadataSchema(build_ext.build_ext): 'object_detector_metadata_schema_py', 'schema_py', ]: + # bazel_command = [ + # 'bazel', + # 'build', + # '--compilation_mode=opt', + # '--define=MEDIAPIPE_DISABLE_GPU=1', + # '--action_env=PYTHON_BIN_PATH=' + _normalize_path(sys.executable), + # '//mediapipe/tasks/metadata:' + target, + # ] + bazel_command = [ 'bazel', 'build', '--compilation_mode=opt', - '--define=MEDIAPIPE_DISABLE_GPU=1', + '--copt=-DMESA_EGL_NO_X11_HEADERS', + '--copt=-DEGL_NO_X11', '--action_env=PYTHON_BIN_PATH=' + _normalize_path(sys.executable), '//mediapipe/tasks/metadata:' + target, ] @@ -385,12 +427,22 @@ class BuildExtension(build_ext.build_ext): def _build_binary(self, ext, extra_args=None): if not os.path.exists(self.build_temp): os.makedirs(self.build_temp) + # bazel_command = [ + # 'bazel', + # 'build', + # '--compilation_mode=opt', + # '--copt=-DNDEBUG', + # '--define=MEDIAPIPE_DISABLE_GPU=1', + # '--action_env=PYTHON_BIN_PATH=' + _normalize_path(sys.executable), + # str(ext.bazel_target + '.so'), + # ] bazel_command = [ 'bazel', 'build', '--compilation_mode=opt', '--copt=-DNDEBUG', - '--define=MEDIAPIPE_DISABLE_GPU=1', + '--copt=-DMESA_EGL_NO_X11_HEADERS', + '--copt=-DEGL_NO_X11', '--action_env=PYTHON_BIN_PATH=' + _normalize_path(sys.executable), str(ext.bazel_target + '.so'), ] From ae2901459dcfb9775c7e41468129d4a468a19abe Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 17 May 2023 21:50:11 +0530 Subject: [PATCH 279/753] Updated property types in MPPGestureRecognizerResult --- .../sources/MPPGestureRecognizerResult.h | 12 ++++++------ .../sources/MPPGestureRecognizerResult.m | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerResult.h b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerResult.h index 68a31c834..d56df2855 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerResult.h +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerResult.h @@ -25,7 +25,7 @@ NS_SWIFT_NAME(GestureRecognizerResult) @interface MPPGestureRecognizerResult : MPPTaskResult /** Hand landmarks of detected hands. */ -@property(nonatomic, readonly) NSArray *> *landmarks; +@property(nonatomic, readonly) NSArray *> *landmarks; /** Hand landmarks in world coordniates of detected hands. */ @property(nonatomic, readonly) NSArray *> *worldLandmarks; @@ -54,11 +54,11 @@ NS_SWIFT_NAME(GestureRecognizerResult) * landmarks, handedness and gestures. * */ -- (instancetype)initWithLandmarks:(NSArray *> *)landmarks - worldLandmarks:(NSArray *> *)worldLandmarks - handedness:(NSArray *> *)handedness - gestures:(NSArray *> *)gestures - timestampInMilliseconds:(NSInteger)timestampInMilliseconds; +- (instancetype)initWithGestures:(NSArray *> *)gestures + handedness:(NSArray *> *)handedness + landmarks:(NSArray *> *)landmarks + worldLandmarks:(NSArray *> *)worldLandmarks + timestampInMilliseconds:(NSInteger)timestampInMilliseconds; @end diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerResult.m b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerResult.m index 3ffb15392..f9ea738de 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerResult.m +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerResult.m @@ -16,10 +16,10 @@ @implementation MPPGestureRecognizerResult -- (instancetype)initWithLandmarks:(NSArray *> *)landmarks +- (instancetype)initWithGestures:(NSArray *> *)gestures + handedness:(NSArray *> *)handedness + landmarks:(NSArray *> *)landmarks worldLandmarks:(NSArray *> *)worldLandmarks - handedness:(NSArray *> *)handedness - gestures:(NSArray *> *)gestures timestampInMilliseconds:(NSInteger)timestampInMilliseconds { self = [super initWithTimestampInMilliseconds:timestampInMilliseconds]; if (self) { From a4c280310b51d51548466509ad8fabb86638699c Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 17 May 2023 21:50:53 +0530 Subject: [PATCH 280/753] Added delegates in iOS gesture recognizer options --- .../sources/MPPGestureRecognizerOptions.h | 63 +++++++++++++++++-- .../sources/MPPGestureRecognizerOptions.m | 6 +- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h index 002c77892..421073d45 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h @@ -21,22 +21,73 @@ NS_ASSUME_NONNULL_BEGIN +@class MPPGestureRecognizer; + +/** + * This protocol defines an interface for the delegates of `MPPGestureRecognizer` object to receive + * results of performing asynchronous gesture recognition on images (i.e, when `runningMode` = + * `MPPRunningModeLiveStream`). + * + * The delegate of `MPPGestureRecognizer` must adopt `MPPGestureRecognizerLiveStreamDelegate` + * protocol. The methods in this protocol are optional. + */ +NS_SWIFT_NAME(GestureRecognizerLiveStreamDelegate) +@protocol MPPGestureRecognizerLiveStreamDelegate + +@optional + +/** + * This method notifies a delegate that the results of asynchronous object detection of + * an image submitted to the `MPPGestureRecognizer` is available. + * + * This method is called on a private serial dispatch queue created by the `MPPGestureRecognizer` + * for performing the asynchronous delegates calls. + * + * @param gestureRecognizer The gesture recognizer which performed the gesture recognition. + * This is useful to test equality when there are multiple instances of `MPPGestureRecognizer`. + * @param result The `MPPGestureRecognizerResult` object that contains a list of detections, each + * detection has a bounding box that is expressed in the unrotated input frame of reference + * coordinates system, i.e. in `[0,image_width) x [0,image_height)`, which are the dimensions of the + * underlying image data. + * @param timestampInMilliseconds The timestamp (in milliseconds) which indicates when the input + * image was sent to the object detector. + * @param error An optional error parameter populated when there is an error in performing object + * detection on the input live stream image data. + * + */ +- (void)gestureRecognizer:(MPPGestureRecognizer *)gestureRecognizer + didFinishRecognitionWithResult:(nullable MPPGestureRecognizerResult *)result + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(nullable NSError *)error + NS_SWIFT_NAME(gestureRecognizer(_:didFinishGestureRecognition:timestampInMilliseconds:error:)); +@end + /** Options for setting up a `MPPGestureRecognizer`. */ NS_SWIFT_NAME(GestureRecognizerOptions) @interface MPPGestureRecognizerOptions : MPPTaskOptions +/** + * Running mode of the gesture recognizer task. Defaults to `MPPRunningModeImage`. + * `MPPGestureRecognizer` can be created with one of the following running modes: + * 1. `MPPRunningModeImage`: The mode for performing object detection on single image inputs. + * 2. `MPPRunningModeVideo`: The mode for performing object detection on the decoded frames of a + * video. + * 3. `MPPRunningModeLiveStream`: The mode for performing object detection on a live stream of + * input data, such as from the camera. + */ @property(nonatomic) MPPRunningMode runningMode; /** - * The user-defined result callback for processing live stream data. The result callback should only - * be specified when the running mode is set to the live stream mode. - * TODO: Add parameter `MPPImage` in the callback. + * An object that confirms to `MPPGestureRecognizerLiveStreamDelegate` protocol. This object must + * implement `gestureRecognizer:didFinishRecognitionWithResult:timestampInMilliseconds:error:` to + * receive the results of performing asynchronous gesture recognition on images (i.e, when + * `runningMode` = `MPPRunningModeLiveStream`). */ -@property(nonatomic, copy) void (^completion) - (MPPGestureRecognizerResult *result, NSInteger timestampMs, NSError *error); +@property(nonatomic, weak, nullable) id + gestureRecognizerLiveStreamDelegate; /** Sets the maximum number of hands can be detected by the GestureRecognizer. */ -@property(nonatomic) NSInteger numHands; +@property(nonatomic) NSInteger numberOfHands; /** Sets minimum confidence score for the hand detection to be considered successful */ @property(nonatomic) float minHandDetectionConfidence; diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.m b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.m index 720385f33..7f874c8fd 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.m +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.m @@ -19,7 +19,7 @@ - (instancetype)init { self = [super init]; if (self) { - _numHands = 1; + _numberOfHands = 1; _minHandDetectionConfidence = 0.5f; _minHandPresenceConfidence = 0.5f; _minTrackingConfidence = 0.5f; @@ -31,8 +31,8 @@ MPPGestureRecognizerOptions *gestureRecognizerOptions = [super copyWithZone:zone]; gestureRecognizerOptions.runningMode = self.runningMode; - gestureRecognizerOptions.completion = self.completion; - gestureRecognizerOptions.numHands = self.numHands; + gestureRecognizerOptions.gestureRecognizerLiveStreamDelegate = self.gestureRecognizerLiveStreamDelegate; + gestureRecognizerOptions.numberOfHands = self.numberOfHands; gestureRecognizerOptions.minHandDetectionConfidence = self.minHandDetectionConfidence; gestureRecognizerOptions.minHandPresenceConfidence = self.minHandPresenceConfidence; gestureRecognizerOptions.minTrackingConfidence = self.minTrackingConfidence; From ebd154550621dad536ba702e15e2ffd5965a670c Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 17 May 2023 21:51:40 +0530 Subject: [PATCH 281/753] Added MPPGestureRecognizerOptionsHelpers --- .../ios/vision/gesture_recognizer/utils/BUILD | 33 ++++++++ .../MPPGestureRecognizerOptions+Helpers.h | 32 +++++++ .../MPPGestureRecognizerOptions+Helpers.mm | 83 +++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 mediapipe/tasks/ios/vision/gesture_recognizer/utils/BUILD create mode 100644 mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.h create mode 100644 mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.mm diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/BUILD b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/BUILD new file mode 100644 index 000000000..f643c83f5 --- /dev/null +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/BUILD @@ -0,0 +1,33 @@ +# 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. + +package(default_visibility = ["//mediapipe/tasks:internal"]) + +licenses(["notice"]) + +objc_library( + name = "MPPGestureRecognizerOptionsHelpers", + srcs = ["sources/MPPGestureRecognizerOptions+Helpers.mm"], + hdrs = ["sources/MPPGestureRecognizerOptions+Helpers.h"], + deps = [ + "//mediapipe/framework:calculator_options_cc_proto", + "//mediapipe/tasks/cc/vision/gesture_recognizer/proto:gesture_recognizer_graph_options_cc_proto", + "//mediapipe/tasks/ios/common/utils:NSStringHelpers", + "//mediapipe/tasks/ios/components/processors/utils:MPPClassifierOptionsHelpers", + "//mediapipe/tasks/ios/core:MPPTaskOptionsProtocol", + "//mediapipe/tasks/ios/core/utils:MPPBaseOptionsHelpers", + "//mediapipe/tasks/ios/vision/gesture_recognizer:MPPGestureRecognizerOptions", + ], +) + diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.h b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.h new file mode 100644 index 000000000..505bbd515 --- /dev/null +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.h @@ -0,0 +1,32 @@ +// 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/framework/calculator_options.pb.h" +#import "mediapipe/tasks/ios/core/sources/MPPTaskOptionsProtocol.h" +#import "mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MPPGestureRecognizerOptions (Helpers) + +/** + * Populates the provided `CalculatorOptions` proto container with the current settings. + * + * @param optionsProto The `CalculatorOptions` proto object to copy the settings to. + */ +- (void)copyToProto:(::mediapipe::CalculatorOptions *)optionsProto; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.mm b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.mm new file mode 100644 index 000000000..111dabab2 --- /dev/null +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.mm @@ -0,0 +1,83 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.h" + +#import "mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h" +#import "mediapipe/tasks/ios/components/processors/utils/sources/MPPClassifierOptions+Helpers.h" +#import "mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.h" + +#include "mediapipe/tasks/cc/vision/gesture_recognizer/proto/gesture_recognizer_graph_options.pb.h" + +namespace { +using CalculatorOptionsProto = mediapipe::CalculatorOptions; +using GestureClassifierGraphOptionsProto = + ::mediapipe::tasks::vision::gesture_recognizer::proto::GestureClassifierGraphOptions; +using GestureRecognizerGraphOptionsProto = + ::mediapipe::tasks::vision::gesture_recognizer::proto::GestureRecognizerGraphOptions; +using HandGestureRecognizerGraphOptionsProto = + ::mediapipe::tasks::vision::gesture_recognizer::proto::HandGestureRecognizerGraphOptions; +using HandLandmarkerGraphOptionsProto = + ::mediapipe::tasks::vision::hand_landmarker::proto::HandLandmarkerGraphOptions; +using HandDetectorGraphOptionsProto = + ::mediapipe::tasks::vision::hand_detector::proto::HandDetectorGraphOptions; +using HandLandmarksDetectorGraphOptionsProto = + ::mediapipe::tasks::vision::hand_landmarker::proto::HandLandmarksDetectorGraphOptions; +using ClassifierOptionsProto = ::mediapipe::tasks::components::processors::proto::ClassifierOptions; +} // namespace + +@implementation MPPGestureRecognizerOptions (Helpers) + +- (void)copyToProto:(CalculatorOptionsProto *)optionsProto { + GestureRecognizerGraphOptionsProto *gestureRecognizerGraphOptionsProto = + optionsProto->MutableExtension(GestureRecognizerGraphOptionsProto::ext); + + [self.baseOptions copyToProto:gestureRecognizerGraphOptionsProto->mutable_base_options() + withUseStreamMode:self.runningMode != MPPRunningModeImage]; + + HandLandmarkerGraphOptionsProto *handLandmarkerGraphOptionsProto = + gestureRecognizerGraphOptionsProto->mutable_hand_landmarker_graph_options(); + handLandmarkerGraphOptionsProto->set_min_tracking_confidence(self.minTrackingConfidence); + + HandDetectorGraphOptionsProto *handDetectorGraphOptionsProto = + handLandmarkerGraphOptionsProto->mutable_hand_detector_graph_options(); + handDetectorGraphOptionsProto->Clear(); + handDetectorGraphOptionsProto->set_num_hands(self.numberOfHands); + handDetectorGraphOptionsProto->set_min_detection_confidence(self.minHandDetectionConfidence); + + HandLandmarksDetectorGraphOptionsProto *handLandmarksDetectorGraphOptionsProto = + handLandmarkerGraphOptionsProto->mutable_hand_landmarks_detector_graph_options(); + handLandmarksDetectorGraphOptionsProto->Clear(); + handLandmarksDetectorGraphOptionsProto->set_min_detection_confidence( + self.minHandPresenceConfidence); + + HandGestureRecognizerGraphOptionsProto *handGestureRecognizerGraphOptionsProto = + gestureRecognizerGraphOptionsProto->mutable_hand_gesture_recognizer_graph_options(); + + if (self.cannedGesturesClassifierOptions) { + GestureClassifierGraphOptionsProto *cannedGesturesClassifierOptionsProto = + handGestureRecognizerGraphOptionsProto->mutable_canned_gesture_classifier_graph_options(); + [self.cannedGesturesClassifierOptions + copyToProto:cannedGesturesClassifierOptionsProto->mutable_classifier_options()]; + } + + if (self.customGesturesClassifierOptions) { + GestureClassifierGraphOptionsProto *customGesturesClassifierOptionsProto = + handGestureRecognizerGraphOptionsProto->mutable_custom_gesture_classifier_graph_options(); + [self.customGesturesClassifierOptions + copyToProto:customGesturesClassifierOptionsProto->mutable_classifier_options()]; + } +} + +@end From 501b4bbc7b46d50139d269c00db0014f0f99b1de Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 17 May 2023 21:52:05 +0530 Subject: [PATCH 282/753] Added MPPGestureRecognizerResultHelpers --- .../ios/vision/gesture_recognizer/utils/BUILD | 13 ++ .../MPPGestureRecognizerResult+Helpers.h | 46 +++++++ .../MPPGestureRecognizerResult+Helpers.mm | 128 ++++++++++++++++++ 3 files changed, 187 insertions(+) create mode 100644 mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.h create mode 100644 mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.mm diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/BUILD b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/BUILD index f643c83f5..8db5a63db 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/BUILD +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/BUILD @@ -31,3 +31,16 @@ objc_library( ], ) +objc_library( + name = "MPPGestureRecognizerResultHelpers", + srcs = ["sources/MPPGestureRecognizerResult+Helpers.mm"], + hdrs = ["sources/MPPGestureRecognizerResult+Helpers.h"], + deps = [ + "//mediapipe/framework:packet", + "//mediapipe/framework/formats:classification_cc_proto", + "//mediapipe/framework/formats:landmark_cc_proto", + "//mediapipe/tasks/ios/components/containers/utils:MPPCategoryHelpers", + "//mediapipe/tasks/ios/components/containers/utils:MPPLandmarkHelpers", + "//mediapipe/tasks/ios/vision/gesture_recognizer:MPPGestureRecognizerResult", + ], +) diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.h b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.h new file mode 100644 index 000000000..649c11c8a --- /dev/null +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.h @@ -0,0 +1,46 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerResult.h" + +#include "mediapipe/framework/packet.h" + +NS_ASSUME_NONNULL_BEGIN + +static const int kMicroSecondsPerMilliSecond = 1000; + +@interface MPPGestureRecognizerResult (Helpers) + +/** + * Creates an `MPPGestureRecognizerResult` from hand gestures, handedness, hand landmarks and world + * landmarks packets. + * + * @param handGesturesPacket a MediaPipe packet wrapping a`std::vector`. + * @param handednessPacket a MediaPipe packet wrapping a`std::vector`. + * @param handLandmarksPacket a MediaPipe packet wrapping + * a`std::vector`. + * @param handLandmarksPacket a MediaPipe packet wrapping a`std::vector`. + * + * @return An `MPPGestureRecognizerResult` object that contains the hand gesture recognition + * results. + */ ++ (MPPGestureRecognizerResult *) + gestureRecognizerResultWithHandGesturesPacket:(const mediapipe::Packet &)handGesturesPacket + handednessPacket:(const mediapipe::Packet &)handednessPacket + handLandmarksPacket:(const mediapipe::Packet &)handLandmarksPacket + worldLandmarksPacket:(const mediapipe::Packet &)worldLandmarksPacket; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.mm b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.mm new file mode 100644 index 000000000..d125ad26f --- /dev/null +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.mm @@ -0,0 +1,128 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.h" + +#import "mediapipe/tasks/ios/components/containers/utils/sources/MPPCategory+Helpers.h" +#import "mediapipe/tasks/ios/components/containers/utils/sources/MPPLandmark+Helpers.h" + +#include "mediapipe/framework/formats/classification.pb.h" +#include "mediapipe/framework/formats/landmark.pb.h" +#include "mediapipe/framework/packet.h" + +namespace { +using ClassificationListProto = ::mediapipe::ClassificationList; +using LandmarkListProto = ::mediapipe::LandmarkList; +using NormalizedLandmarkListProto = ::mediapipe::NormalizedLandmarkList; +using ::mediapipe::Packet; +} // namespace + +@implementation MPPGestureRecognizerResult (Helpers) + ++ (MPPGestureRecognizerResult *) + gestureRecognizerResultWithHandGesturesPacket:(const Packet &)handGesturesPacket + handednessPacket:(const Packet &)handednessPacket + handLandmarksPacket:(const Packet &)handLandmarksPacket + worldLandmarksPacket:(const Packet &)worldLandmarksPacket { + NSInteger timestampInMilliseconds = + (NSInteger)(handGesturesPacket.Timestamp().Value() / kMicroSecondsPerMilliSecond); + + if (handGesturesPacket.IsEmpty()) { + return [[MPPGestureRecognizerResult alloc] initWithGestures:@[] + handedness:@[] + landmarks:@[] + worldLandmarks:@[] + timestampInMilliseconds:timestampInMilliseconds]; + } + + if (!handGesturesPacket.ValidateAsType>().ok() || + !handednessPacket.ValidateAsType>().ok() || + !handLandmarksPacket.ValidateAsType>().ok() || + !worldLandmarksPacket.ValidateAsType>().ok()) { + return nil; + } + + const std::vector &handGesturesClassificationListProtos = + handGesturesPacket.Get>(); + NSMutableArray *> *multiHandGestures = + [NSMutableArray arrayWithCapacity:(NSUInteger)handGesturesClassificationListProtos.size()]; + + for (const auto &classificationListProto : handGesturesClassificationListProtos) { + NSMutableArray *gestures = [NSMutableArray + arrayWithCapacity:(NSUInteger)classificationListProto.classification().size()]; + for (const auto &classificationProto : classificationListProto.classification()) { + MPPCategory *category = [MPPCategory categoryWithProto:classificationProto]; + [gestures addObject:category]; + } + [multiHandGestures addObject:[gestures copy]]; + } + + const std::vector &handednessClassificationListProtos = + handednessPacket.Get>(); + NSMutableArray *> *multiHandHandedness = + [NSMutableArray arrayWithCapacity:(NSUInteger)handednessClassificationListProtos.size()]; + + for (const auto &classificationListProto : handednessClassificationListProtos) { + NSMutableArray *handedness = [NSMutableArray + arrayWithCapacity:(NSUInteger)classificationListProto.classification().size()]; + for (const auto &classificationProto : classificationListProto.classification()) { + MPPCategory *category = [MPPCategory categoryWithProto:classificationProto]; + [handedness addObject:category]; + } + [multiHandHandedness addObject:[handedness copy]]; + } + + const std::vector &handLandmarkListProtos = + handLandmarksPacket.Get>(); + NSMutableArray *> *multiHandLandmarks = + [NSMutableArray arrayWithCapacity:(NSUInteger)handLandmarkListProtos.size()]; + + for (const auto &handLandmarkListProto : handLandmarkListProtos) { + NSMutableArray *handLandmarks = + [NSMutableArray arrayWithCapacity:(NSUInteger)handLandmarkListProto.landmark().size()]; + for (const auto &normalizedLandmarkProto : handLandmarkListProto.landmark()) { + MPPNormalizedLandmark *normalizedLandmark = + [MPPNormalizedLandmark normalizedLandmarkWithProto:normalizedLandmarkProto]; + [handLandmarks addObject:normalizedLandmark]; + } + [multiHandLandmarks addObject:[handLandmarks copy]]; + } + + const std::vector &worldLandmarkListProtos = + worldLandmarksPacket.Get>(); + NSMutableArray *> *multiHandWorldLandmarks = + [NSMutableArray arrayWithCapacity:(NSUInteger)worldLandmarkListProtos.size()]; + + for (const auto &worldLandmarkListProto : worldLandmarkListProtos) { + NSMutableArray *worldLandmarks = + [NSMutableArray arrayWithCapacity:(NSUInteger)worldLandmarkListProto.landmark().size()]; + for (const auto &landmarkProto : worldLandmarkListProto.landmark()) { + MPPLandmark *landmark = + [MPPLandmark landmarkWithProto:landmarkProto]; + [worldLandmarks addObject:landmark]; + } + [multiHandWorldLandmarks addObject:[worldLandmarks copy]]; + } + + MPPGestureRecognizerResult *gestureRecognizerResult = + [[MPPGestureRecognizerResult alloc] initWithGestures:[multiHandGestures copy] + handedness:[multiHandHandedness copy] + landmarks:[multiHandLandmarks copy] + worldLandmarks:[multiHandWorldLandmarks copy] + timestampInMilliseconds:timestampInMilliseconds]; + + return gestureRecognizerResult; +} + +@end From dcb0414d4b6ef1b82d054487df8fc524220932dd Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 17 May 2023 21:53:25 +0530 Subject: [PATCH 283/753] Added MPPGestureRecognizer header --- .../tasks/ios/vision/gesture_recognizer/BUILD | 19 ++ .../sources/MPPGestureRecognizer.h | 274 ++++++++++++++++++ 2 files changed, 293 insertions(+) create mode 100644 mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizer.h diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/BUILD b/mediapipe/tasks/ios/vision/gesture_recognizer/BUILD index 26fa4d6cf..a9a62d720 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/BUILD +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/BUILD @@ -38,3 +38,22 @@ objc_library( "//mediapipe/tasks/ios/vision/core:MPPRunningMode", ], ) + +objc_library( + name = "MPPGestureRecognizer", + srcs = ["sources/MPPGestureRecognizer.mm"], + hdrs = ["sources/MPPGestureRecognizer.h"], + copts = [ + "-ObjC++", + "-std=c++17", + "-x objective-c++", + ], + module_name = "MPPGestureRecognizer", + deps = [ + ":MPPGestureRecognizerOptions", + ":MPPGestureRecognizerResult", + "//mediapipe/tasks/ios/core:MPPTaskOptions", + "//mediapipe/tasks/ios/vision/core:MPPImage", + ], +) + diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizer.h b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizer.h new file mode 100644 index 000000000..2e3ca937b --- /dev/null +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizer.h @@ -0,0 +1,274 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +#import "mediapipe/tasks/ios/core/sources/MPPTaskOptions.h" +#import "mediapipe/tasks/ios/vision/core/sources/MPPImage.h" +#import "mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h" +#import "mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerResult.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * @brief Performs gesture recognition on images. + * + * This API expects a pre-trained TFLite hand gesture recognizer model or a custom one created using + * MediaPipe Solutions Model Maker. See + * https://developers.google.com/mediapipe/solutions/model_maker. + */ +NS_SWIFT_NAME(GestureRecognizer) +@interface MPPGestureRecognizer : NSObject + +/** + * Creates a new instance of `MPPGestureRecognizer` from an absolute path to a TensorFlow Lite model + * file stored locally on the device and the default `MPPGestureRecognizerOptions`. + * + * @param modelPath An absolute path to a TensorFlow Lite model file stored locally on the device. + * @param error An optional error parameter populated when there is an error in initializing the + * gesture recognizer. + * + * @return A new instance of `MPPGestureRecognizer` with the given model path. `nil` if there is an + * error in initializing the gesture recognizer. + */ +- (nullable instancetype)initWithModelPath:(NSString *)modelPath error:(NSError **)error; + +/** + * Creates a new instance of `MPPGestureRecognizer` from the given `MPPGestureRecognizerOptions`. + * + * @param options The options of type `MPPGestureRecognizerOptions` to use for configuring the + * `MPPGestureRecognizer`. + * @param error An optional error parameter populated when there is an error in initializing the + * gesture recognizer. + * + * @return A new instance of `MPPGestureRecognizer` with the given options. `nil` if there is an + * error in initializing the gesture recognizer. + */ +- (nullable instancetype)initWithOptions:(MPPGestureRecognizerOptions *)options + error:(NSError **)error NS_DESIGNATED_INITIALIZER; + +/** + * Performs gesture recognition on the provided MPPImage using the whole image as region of + * interest. Rotation will be applied according to the `orientation` property of the provided + * `MPPImage`. Only use this method when the `MPPGestureRecognizer` is created with + * `MPPRunningModeImage`. + * This method supports gesture recognition of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is + * RGB with an Alpha channel. + * + * @param image The `MPPImage` on which gesture recognition is to be performed. + * @param error An optional error parameter populated when there is an error in performing gesture + * recognition on the input image. + * + * @return An `MPPGestureRecognizerResult` object that contains the hand gesture recognition + * results. + */ +- (nullable MPPGestureRecognizerResult *)recognizeImage:(MPPImage *)image + error:(NSError **)error + NS_SWIFT_NAME(recognize(image:)); + +/** + * Performs gesture recognition on the provided `MPPImage` cropped to the specified region of + * interest. Rotation will be applied on the cropped image according to the `orientation` property + * of the provided `MPPImage`. Only use this method when the `MPPGestureRecognizer` is created with + * `MPPRunningModeImage`. + * + * This method supports gesture recognition of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is + * RGB with an Alpha channel. + * + * @param image The `MPPImage` on which gesture recognition is to be performed. + * @param roi A `CGRect` specifying the region of interest within the given `MPPImage`, on which + * gesture recognition should be performed. + * @param error An optional error parameter populated when there is an error in performing gesture + * recognition on the input image. + * + * @return An `MPPGestureRecognizerResult` object that contains the hand gesture recognition + * results. + */ +- (nullable MPPGestureRecognizerResult *)recognizeImage:(MPPImage *)image + regionOfInterest:(CGRect)roi + error:(NSError **)error + NS_SWIFT_NAME(recognize(image:regionOfInterest:)); + +/** + * Performs gesture recognition on the provided video frame of type `MPPImage` using the whole + * image as region of interest. Rotation will be applied according to the `orientation` property of + * the provided `MPPImage`. Only use this method when the `MPPGestureRecognizer` is created with + * `MPPRunningModeVideo`. + * + * It's required to provide the video frame's timestamp (in milliseconds). The input timestamps must + * be monotonically increasing. + * + * This method supports gesture recognition of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is + * RGB with an Alpha channel. + * + * @param image The `MPPImage` on which gesture recognition is to be performed. + * @param timestampInMilliseconds The video frame's timestamp (in milliseconds). The input + * timestamps must be monotonically increasing. + * @param error An optional error parameter populated when there is an error in performing gesture + * recognition on the input video frame. + * + * @return An `MPPGestureRecognizerResult` object that contains the hand gesture recognition + * results. + */ +- (nullable MPPGestureRecognizerResult *)recognizeVideoFrame:(MPPImage *)image + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(NSError **)error + NS_SWIFT_NAME(recognize(videoFrame:timestampInMilliseconds:)); + +/** + * Performs gesture recognition on the provided video frame of type `MPPImage` cropped to the + * specified region of interest. Rotation will be applied according to the `orientation` property of + * the provided `MPPImage`. Only use this method when the `MPPGestureRecognizer` is created with + * `MPPRunningModeVideo`. + * + * It's required to provide the video frame's timestamp (in milliseconds). The input timestamps must + * be monotonically increasing. + * + * This method supports gesture recognition of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is + * RGB with an Alpha channel. + * + * @param image A live stream image data of type `MPPImage` on which gesture recognition is to be + * performed. + * @param timestampInMilliseconds The video frame's timestamp (in milliseconds). The input + * timestamps must be monotonically increasing. + * @param roi A `CGRect` specifying the region of interest within the video frame of type + * `MPPImage`, on which gesture recognition should be performed. + * @param error An optional error parameter populated when there is an error in performing gesture + * recognition on the input video frame. + * + * @return An `MPPGestureRecognizerResult` object that contains the hand gesture recognition + * results. + */ +- (nullable MPPGestureRecognizerResult *)recognizeVideoFrame:(MPPImage *)image + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + regionOfInterest:(CGRect)roi + error:(NSError **)error + NS_SWIFT_NAME(recognize(videoFrame:timestampInMilliseconds:regionOfInterest:)); + +/** + * Sends live stream image data of type `MPPImage` to perform gesture recognition using the whole + * image as region of interest. Rotation will be applied according to the `orientation` property of + * the provided `MPPImage`. Only use this method when the `MPPGestureRecognizer` is created with + * `MPPRunningModeLiveStream`. + * + * The object which needs to be continuously notified of the available results of gesture + * recognition must confirm to `MPPGestureRecognizerLiveStreamDelegate` protocol and implement the + * `gestureRecognizer:didFinishRecognitionWithResult:timestampInMilliseconds:error:` + * delegate method. + * + * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent + * to the gesture recognizer. The input timestamps must be monotonically increasing. + * + * This method supports gesture recognition of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If the input `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color + * space is RGB with an Alpha channel. + * + * If this method is used for performing gesture recognition on live camera frames using + * `AVFoundation`, ensure that you request `AVCaptureVideoDataOutput` to output frames in + * `kCMPixelFormat_32RGBA` using its `videoSettings` property. + * + * @param image A live stream image data of type `MPPImage` on which gesture recognition is to be + * performed. + * @param timestampInMilliseconds The timestamp (in milliseconds) which indicates when the input + * image is sent to the gesture recognizer. The input timestamps must be monotonically increasing. + * @param error An optional error parameter populated when there is an error in performing gesture + * recognition on the input live stream image data. + * + * @return `YES` if the image was sent to the task successfully, otherwise `NO`. + */ +- (BOOL)recognizeAsyncImage:(MPPImage *)image + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(NSError **)error + NS_SWIFT_NAME(recognizeAsync(image:timestampInMilliseconds:)); + +/** + * Sends live stream image data of type `MPPImage` to perform gesture recognition, cropped to the + * specified region of interest.. Rotation will be applied according to the `orientation` property + * of the provided `MPPImage`. Only use this method when the `MPPGestureRecognizer` is created with + * `MPPRunningModeLiveStream`. + * + * The object which needs to be continuously notified of the available results of gesture + * recognition must confirm to `MPPGestureRecognizerLiveStreamDelegate` protocol and implement the + * `gestureRecognizer:didFinishRecognitionWithResult:timestampInMilliseconds:error:` delegate + * method. + * + * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent + * to the gesture recognizer. The input timestamps must be monotonically increasing. + * + * This method supports gesture recognition of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If the input `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color + * space is RGB with an Alpha channel. + * + * If this method is used for preforming gesture recognition on live camera frames using + * `AVFoundation`, ensure that you request `AVCaptureVideoDataOutput` to output frames in + * `kCMPixelFormat_32RGBA` using its `videoSettings` property. + * + * @param image A live stream image data of type `MPPImage` on which gesture recognition is to be + * performed. + * @param timestampInMilliseconds The timestamp (in milliseconds) which indicates when the input + * image is sent to the gesture recognizer. The input timestamps must be monotonically increasing. + * @param roi A `CGRect` specifying the region of interest within the given live stream image data + * of type `MPPImage`, on which gesture recognition should be performed. + * @param error An optional error parameter populated when there is an error in performing gesture + * recognition on the input live stream image data. + * + * @return `YES` if the image was sent to the task successfully, otherwise `NO`. + */ +- (BOOL)recognizeAsyncImage:(MPPImage *)image + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + regionOfInterest:(CGRect)roi + error:(NSError **)error + NS_SWIFT_NAME(recognizeAsync(image:timestampInMilliseconds:regionOfInterest:)); + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END From 36b7514b19156a599a25b391c238582a7e25d248 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 17 May 2023 21:56:31 +0530 Subject: [PATCH 284/753] Removed srcs in MPPGestureRecognizer target --- mediapipe/tasks/ios/vision/gesture_recognizer/BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/BUILD b/mediapipe/tasks/ios/vision/gesture_recognizer/BUILD index a9a62d720..c44e89d67 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/BUILD +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/BUILD @@ -41,7 +41,6 @@ objc_library( objc_library( name = "MPPGestureRecognizer", - srcs = ["sources/MPPGestureRecognizer.mm"], hdrs = ["sources/MPPGestureRecognizer.h"], copts = [ "-ObjC++", From d6d5a948451b39d7f1357568025dfbe975f26052 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 17 May 2023 21:59:26 +0530 Subject: [PATCH 285/753] Reverted copy of gesture recognizer result containers --- .../MPPGestureRecognizerResult+Helpers.mm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.mm b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.mm index d125ad26f..ecb0e7831 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.mm +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerResult+Helpers.mm @@ -65,7 +65,7 @@ using ::mediapipe::Packet; MPPCategory *category = [MPPCategory categoryWithProto:classificationProto]; [gestures addObject:category]; } - [multiHandGestures addObject:[gestures copy]]; + [multiHandGestures addObject:gestures]; } const std::vector &handednessClassificationListProtos = @@ -80,7 +80,7 @@ using ::mediapipe::Packet; MPPCategory *category = [MPPCategory categoryWithProto:classificationProto]; [handedness addObject:category]; } - [multiHandHandedness addObject:[handedness copy]]; + [multiHandHandedness addObject:handedness]; } const std::vector &handLandmarkListProtos = @@ -96,7 +96,7 @@ using ::mediapipe::Packet; [MPPNormalizedLandmark normalizedLandmarkWithProto:normalizedLandmarkProto]; [handLandmarks addObject:normalizedLandmark]; } - [multiHandLandmarks addObject:[handLandmarks copy]]; + [multiHandLandmarks addObject:handLandmarks]; } const std::vector &worldLandmarkListProtos = @@ -112,14 +112,14 @@ using ::mediapipe::Packet; [MPPLandmark landmarkWithProto:landmarkProto]; [worldLandmarks addObject:landmark]; } - [multiHandWorldLandmarks addObject:[worldLandmarks copy]]; + [multiHandWorldLandmarks addObject:worldLandmarks]; } MPPGestureRecognizerResult *gestureRecognizerResult = - [[MPPGestureRecognizerResult alloc] initWithGestures:[multiHandGestures copy] - handedness:[multiHandHandedness copy] - landmarks:[multiHandLandmarks copy] - worldLandmarks:[multiHandWorldLandmarks copy] + [[MPPGestureRecognizerResult alloc] initWithGestures:multiHandGestures + handedness:multiHandHandedness + landmarks:multiHandLandmarks + worldLandmarks:multiHandWorldLandmarks timestampInMilliseconds:timestampInMilliseconds]; return gestureRecognizerResult; From dc7c018b3994e42143542a2da898096a9aa951dd Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 17 May 2023 22:03:10 +0530 Subject: [PATCH 286/753] Added clearing of all graph options protos in MPPGestureRecognizerOptions Helpers --- .../utils/sources/MPPGestureRecognizerOptions+Helpers.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.mm b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.mm index 111dabab2..60af976f1 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.mm +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.mm @@ -42,12 +42,14 @@ using ClassifierOptionsProto = ::mediapipe::tasks::components::processors::proto - (void)copyToProto:(CalculatorOptionsProto *)optionsProto { GestureRecognizerGraphOptionsProto *gestureRecognizerGraphOptionsProto = optionsProto->MutableExtension(GestureRecognizerGraphOptionsProto::ext); + gestureRecognizerGraphOptionsProto->Clear(); [self.baseOptions copyToProto:gestureRecognizerGraphOptionsProto->mutable_base_options() withUseStreamMode:self.runningMode != MPPRunningModeImage]; HandLandmarkerGraphOptionsProto *handLandmarkerGraphOptionsProto = gestureRecognizerGraphOptionsProto->mutable_hand_landmarker_graph_options(); + handLandmarkerGraphOptionsProto->Clear(); handLandmarkerGraphOptionsProto->set_min_tracking_confidence(self.minTrackingConfidence); HandDetectorGraphOptionsProto *handDetectorGraphOptionsProto = @@ -68,6 +70,7 @@ using ClassifierOptionsProto = ::mediapipe::tasks::components::processors::proto if (self.cannedGesturesClassifierOptions) { GestureClassifierGraphOptionsProto *cannedGesturesClassifierOptionsProto = handGestureRecognizerGraphOptionsProto->mutable_canned_gesture_classifier_graph_options(); + cannedGesturesClassifierOptionsProto->Clear(); [self.cannedGesturesClassifierOptions copyToProto:cannedGesturesClassifierOptionsProto->mutable_classifier_options()]; } @@ -75,6 +78,7 @@ using ClassifierOptionsProto = ::mediapipe::tasks::components::processors::proto if (self.customGesturesClassifierOptions) { GestureClassifierGraphOptionsProto *customGesturesClassifierOptionsProto = handGestureRecognizerGraphOptionsProto->mutable_custom_gesture_classifier_graph_options(); + customGesturesClassifierOptionsProto->Clear(); [self.customGesturesClassifierOptions copyToProto:customGesturesClassifierOptionsProto->mutable_classifier_options()]; } From a4d0e68bee18b11d06af266fb96eae438c4725cc Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 17 May 2023 13:34:46 -0700 Subject: [PATCH 287/753] Internal change PiperOrigin-RevId: 532890317 --- third_party/flatbuffers/BUILD.bazel | 3 +-- third_party/flatbuffers/workspace.bzl | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/third_party/flatbuffers/BUILD.bazel b/third_party/flatbuffers/BUILD.bazel index d5264a026..8b814f8af 100644 --- a/third_party/flatbuffers/BUILD.bazel +++ b/third_party/flatbuffers/BUILD.bazel @@ -42,16 +42,15 @@ filegroup( "include/flatbuffers/allocator.h", "include/flatbuffers/array.h", "include/flatbuffers/base.h", - "include/flatbuffers/bfbs_generator.h", "include/flatbuffers/buffer.h", "include/flatbuffers/buffer_ref.h", "include/flatbuffers/code_generator.h", "include/flatbuffers/code_generators.h", "include/flatbuffers/default_allocator.h", "include/flatbuffers/detached_buffer.h", + "include/flatbuffers/file_manager.h", "include/flatbuffers/flatbuffer_builder.h", "include/flatbuffers/flatbuffers.h", - "include/flatbuffers/flatc.h", "include/flatbuffers/flex_flat_util.h", "include/flatbuffers/flexbuffers.h", "include/flatbuffers/grpc.h", diff --git a/third_party/flatbuffers/workspace.bzl b/third_party/flatbuffers/workspace.bzl index 02247268b..0edb7a6f6 100644 --- a/third_party/flatbuffers/workspace.bzl +++ b/third_party/flatbuffers/workspace.bzl @@ -5,11 +5,11 @@ load("//third_party:repo.bzl", "third_party_http_archive") def repo(): third_party_http_archive( name = "flatbuffers", - strip_prefix = "flatbuffers-23.1.21", - sha256 = "d84cb25686514348e615163b458ae0767001b24b42325f426fd56406fd384238", + strip_prefix = "flatbuffers-23.5.8", + sha256 = "55b75dfa5b6f6173e4abf9c35284a10482ba65db886b39db511eba6c244f1e88", urls = [ - "https://storage.googleapis.com/mirror.tensorflow.org/github.com/google/flatbuffers/archive/v23.1.21.tar.gz", - "https://github.com/google/flatbuffers/archive/v23.1.21.tar.gz", + "https://github.com/google/flatbuffers/archive/v23.5.8.tar.gz", + "https://github.com/google/flatbuffers/archive/v23.5.8.tar.gz", ], build_file = "//third_party/flatbuffers:BUILD.bazel", delete = ["build_defs.bzl", "BUILD.bazel"], From 1fb98f5ebd006f92e4061265dbdf7ce92a6990e5 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 17 May 2023 15:47:36 -0700 Subject: [PATCH 288/753] Don't double build ARM64 arch on M1 Macs PiperOrigin-RevId: 532934646 --- setup.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 892c6dca7..b61e5c296 100644 --- a/setup.py +++ b/setup.py @@ -357,7 +357,10 @@ class BuildExtension(build_ext.build_ext): for ext in self.extensions: target_name = self.get_ext_fullpath(ext.name) # Build x86 - self._build_binary(ext) + self._build_binary( + ext, + ['--cpu=darwin', '--ios_multi_cpus=i386,x86_64,armv7,arm64'], + ) x86_name = self.get_ext_fullpath(ext.name) # Build Arm64 ext.name = ext.name + '.arm64' From 02230f65d1005203fa066259220db53c0d75b225 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 17 May 2023 15:48:18 -0700 Subject: [PATCH 289/753] Internal change PiperOrigin-RevId: 532934867 --- mediapipe/framework/BUILD | 1 + mediapipe/framework/graph_service.h | 23 ++++++++++++++++--- .../framework/graph_service_manager_test.cc | 2 +- mediapipe/framework/graph_service_test.cc | 14 +++++++---- mediapipe/framework/test_service.cc | 9 -------- mediapipe/framework/test_service.h | 12 ++++++---- 6 files changed, 40 insertions(+), 21 deletions(-) diff --git a/mediapipe/framework/BUILD b/mediapipe/framework/BUILD index 8224b73fc..a7d9e0a63 100644 --- a/mediapipe/framework/BUILD +++ b/mediapipe/framework/BUILD @@ -1099,6 +1099,7 @@ cc_library( "//mediapipe/framework/port:ret_check", "//mediapipe/framework/port:status", ], + alwayslink = True, # Defines TestServiceCalculator ) cc_library( diff --git a/mediapipe/framework/graph_service.h b/mediapipe/framework/graph_service.h index 51caf31f2..12b2ccb3a 100644 --- a/mediapipe/framework/graph_service.h +++ b/mediapipe/framework/graph_service.h @@ -44,7 +44,6 @@ class GraphServiceBase { constexpr GraphServiceBase(const char* key) : key(key) {} - virtual ~GraphServiceBase() = default; inline virtual absl::StatusOr CreateDefaultObject() const { return DefaultInitializationUnsupported(); } @@ -52,14 +51,32 @@ class GraphServiceBase { const char* key; protected: + // `GraphService` objects, deriving `GraphServiceBase` are designed to be + // global constants and not ever deleted through `GraphServiceBase`. Hence, + // protected and non-virtual destructor which helps to make `GraphService` + // trivially destructible and properly defined as global constants. + // + // A class with any virtual functions should have a destructor that is either + // public and virtual or else protected and non-virtual. + // https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-dtor-virtual + ~GraphServiceBase() = default; + absl::Status DefaultInitializationUnsupported() const { return absl::UnimplementedError(absl::StrCat( "Graph service '", key, "' does not support default initialization")); } }; +// A global constant to refer a service: +// - Requesting `CalculatorContract::UseService` from calculator +// - Accessing `Calculator/SubgraphContext::Service`from calculator/subgraph +// - Setting before graph initialization `CalculatorGraph::SetServiceObject` +// +// NOTE: In headers, define your graph service reference safely as following: +// `inline constexpr GraphService kYourService("YourService");` +// template -class GraphService : public GraphServiceBase { +class GraphService final : public GraphServiceBase { public: using type = T; using packet_type = std::shared_ptr; @@ -68,7 +85,7 @@ class GraphService : public GraphServiceBase { kDisallowDefaultInitialization) : GraphServiceBase(my_key), default_init_(default_init) {} - absl::StatusOr CreateDefaultObject() const override { + absl::StatusOr CreateDefaultObject() const final { if (default_init_ != kAllowDefaultInitialization) { return DefaultInitializationUnsupported(); } diff --git a/mediapipe/framework/graph_service_manager_test.cc b/mediapipe/framework/graph_service_manager_test.cc index 1895a6f70..23d4af0df 100644 --- a/mediapipe/framework/graph_service_manager_test.cc +++ b/mediapipe/framework/graph_service_manager_test.cc @@ -7,7 +7,7 @@ namespace mediapipe { namespace { -const GraphService kIntService("mediapipe::IntService"); +constexpr GraphService kIntService("mediapipe::IntService"); } // namespace TEST(GraphServiceManager, SetGetServiceObject) { diff --git a/mediapipe/framework/graph_service_test.cc b/mediapipe/framework/graph_service_test.cc index 69992f212..0556aac63 100644 --- a/mediapipe/framework/graph_service_test.cc +++ b/mediapipe/framework/graph_service_test.cc @@ -14,6 +14,8 @@ #include "mediapipe/framework/graph_service.h" +#include + #include "mediapipe/framework/calculator_contract.h" #include "mediapipe/framework/calculator_framework.h" #include "mediapipe/framework/port/canonical_errors.h" @@ -159,7 +161,7 @@ TEST_F(GraphServiceTest, CreateDefault) { struct TestServiceData {}; -const GraphService kTestServiceAllowDefaultInitialization( +constexpr GraphService kTestServiceAllowDefaultInitialization( "kTestServiceAllowDefaultInitialization", GraphServiceBase::kAllowDefaultInitialization); @@ -272,9 +274,13 @@ TEST(AllowDefaultInitializationGraphServiceTest, HasSubstr("Service is unavailable."))); } -const GraphService kTestServiceDisallowDefaultInitialization( - "kTestServiceDisallowDefaultInitialization", - GraphServiceBase::kDisallowDefaultInitialization); +constexpr GraphService + kTestServiceDisallowDefaultInitialization( + "kTestServiceDisallowDefaultInitialization", + GraphServiceBase::kDisallowDefaultInitialization); + +static_assert(std::is_trivially_destructible_v>, + "GraphService is not trivially destructible"); class FailOnUnavailableOptionalDisallowDefaultInitServiceCalculator : public CalculatorBase { diff --git a/mediapipe/framework/test_service.cc b/mediapipe/framework/test_service.cc index 4bafaf28c..e7233ebf9 100644 --- a/mediapipe/framework/test_service.cc +++ b/mediapipe/framework/test_service.cc @@ -16,15 +16,6 @@ namespace mediapipe { -const GraphService kTestService( - "test_service", GraphServiceBase::kDisallowDefaultInitialization); -const GraphService kAnotherService( - "another_service", GraphServiceBase::kAllowDefaultInitialization); -const GraphService kNoDefaultService( - "no_default_service", GraphServiceBase::kAllowDefaultInitialization); -const GraphService kNeedsCreateService( - "needs_create_service", GraphServiceBase::kAllowDefaultInitialization); - absl::Status TestServiceCalculator::GetContract(CalculatorContract* cc) { cc->Inputs().Index(0).Set(); cc->Outputs().Index(0).SetSameAs(&cc->Inputs().Index(0)); diff --git a/mediapipe/framework/test_service.h b/mediapipe/framework/test_service.h index 2ff5a384a..42ebd8df8 100644 --- a/mediapipe/framework/test_service.h +++ b/mediapipe/framework/test_service.h @@ -22,14 +22,17 @@ namespace mediapipe { using TestServiceObject = std::map; -extern const GraphService kTestService; -extern const GraphService kAnotherService; +inline constexpr GraphService kTestService( + "test_service", GraphServiceBase::kDisallowDefaultInitialization); +inline constexpr GraphService kAnotherService( + "another_service", GraphServiceBase::kAllowDefaultInitialization); class NoDefaultConstructor { public: NoDefaultConstructor() = delete; }; -extern const GraphService kNoDefaultService; +inline constexpr GraphService kNoDefaultService( + "no_default_service", GraphServiceBase::kAllowDefaultInitialization); class NeedsCreateMethod { public: @@ -40,7 +43,8 @@ class NeedsCreateMethod { private: NeedsCreateMethod() = default; }; -extern const GraphService kNeedsCreateService; +inline constexpr GraphService kNeedsCreateService( + "needs_create_service", GraphServiceBase::kAllowDefaultInitialization); // Use a service. class TestServiceCalculator : public CalculatorBase { From 25458138a99132dc8444b5f54270d1b2f5eeb242 Mon Sep 17 00:00:00 2001 From: Rachel Hornung Date: Wed, 17 May 2023 17:08:38 -0700 Subject: [PATCH 290/753] #MediaPipe Add ConcatenateStringVectorCalculator. PiperOrigin-RevId: 532956844 --- .../core/concatenate_vector_calculator.cc | 4 +++ .../concatenate_vector_calculator_test.cc | 25 ++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/mediapipe/calculators/core/concatenate_vector_calculator.cc b/mediapipe/calculators/core/concatenate_vector_calculator.cc index 0079aa98d..4d0d66206 100644 --- a/mediapipe/calculators/core/concatenate_vector_calculator.cc +++ b/mediapipe/calculators/core/concatenate_vector_calculator.cc @@ -55,6 +55,10 @@ MEDIAPIPE_REGISTER_NODE(ConcatenateUInt64VectorCalculator); typedef ConcatenateVectorCalculator ConcatenateBoolVectorCalculator; MEDIAPIPE_REGISTER_NODE(ConcatenateBoolVectorCalculator); +typedef ConcatenateVectorCalculator + ConcatenateStringVectorCalculator; +MEDIAPIPE_REGISTER_NODE(ConcatenateStringVectorCalculator); + // Example config: // node { // calculator: "ConcatenateTfLiteTensorVectorCalculator" diff --git a/mediapipe/calculators/core/concatenate_vector_calculator_test.cc b/mediapipe/calculators/core/concatenate_vector_calculator_test.cc index 5510b98a3..3fccf58fd 100644 --- a/mediapipe/calculators/core/concatenate_vector_calculator_test.cc +++ b/mediapipe/calculators/core/concatenate_vector_calculator_test.cc @@ -30,13 +30,15 @@ namespace mediapipe { typedef ConcatenateVectorCalculator TestConcatenateIntVectorCalculator; MEDIAPIPE_REGISTER_NODE(TestConcatenateIntVectorCalculator); -void AddInputVector(int index, const std::vector& input, int64_t timestamp, +template +void AddInputVector(int index, const std::vector& input, int64_t timestamp, CalculatorRunner* runner) { runner->MutableInputs()->Index(index).packets.push_back( - MakePacket>(input).At(Timestamp(timestamp))); + MakePacket>(input).At(Timestamp(timestamp))); } -void AddInputVectors(const std::vector>& inputs, +template +void AddInputVectors(const std::vector>& 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> inputs = { + {"a", "b"}, {"c"}, {"d", "e", "f"}}; + AddInputVectors(inputs, /*timestamp=*/1, &runner); + MP_ASSERT_OK(runner.Run()); + + const std::vector& outputs = runner.Outputs().Index(0).packets; + EXPECT_EQ(1, outputs.size()); + EXPECT_EQ(Timestamp(1), outputs[0].Timestamp()); + std::vector expected_vector = {"a", "b", "c", "d", "e", "f"}; + EXPECT_EQ(expected_vector, outputs[0].Get>()); +} + typedef ConcatenateVectorCalculator> TestConcatenateUniqueIntPtrCalculator; MEDIAPIPE_REGISTER_NODE(TestConcatenateUniqueIntPtrCalculator); From e905a9fe39637d709785ae76ec3afb98ce971e9f Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 18 May 2023 09:52:23 +0530 Subject: [PATCH 291/753] Removed roi methods from MPPGestureRecognizer --- .../sources/MPPGestureRecognizer.h | 109 ------------------ 1 file changed, 109 deletions(-) diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizer.h b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizer.h index 2e3ca937b..ed8ff30f9 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizer.h +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizer.h @@ -83,35 +83,6 @@ NS_SWIFT_NAME(GestureRecognizer) error:(NSError **)error NS_SWIFT_NAME(recognize(image:)); -/** - * Performs gesture recognition on the provided `MPPImage` cropped to the specified region of - * interest. Rotation will be applied on the cropped image according to the `orientation` property - * of the provided `MPPImage`. Only use this method when the `MPPGestureRecognizer` is created with - * `MPPRunningModeImage`. - * - * This method supports gesture recognition of RGBA images. If your `MPPImage` has a source type of - * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer - * must have one of the following pixel format types: - * 1. kCVPixelFormatType_32BGRA - * 2. kCVPixelFormatType_32RGBA - * - * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is - * RGB with an Alpha channel. - * - * @param image The `MPPImage` on which gesture recognition is to be performed. - * @param roi A `CGRect` specifying the region of interest within the given `MPPImage`, on which - * gesture recognition should be performed. - * @param error An optional error parameter populated when there is an error in performing gesture - * recognition on the input image. - * - * @return An `MPPGestureRecognizerResult` object that contains the hand gesture recognition - * results. - */ -- (nullable MPPGestureRecognizerResult *)recognizeImage:(MPPImage *)image - regionOfInterest:(CGRect)roi - error:(NSError **)error - NS_SWIFT_NAME(recognize(image:regionOfInterest:)); - /** * Performs gesture recognition on the provided video frame of type `MPPImage` using the whole * image as region of interest. Rotation will be applied according to the `orientation` property of @@ -144,42 +115,6 @@ NS_SWIFT_NAME(GestureRecognizer) error:(NSError **)error NS_SWIFT_NAME(recognize(videoFrame:timestampInMilliseconds:)); -/** - * Performs gesture recognition on the provided video frame of type `MPPImage` cropped to the - * specified region of interest. Rotation will be applied according to the `orientation` property of - * the provided `MPPImage`. Only use this method when the `MPPGestureRecognizer` is created with - * `MPPRunningModeVideo`. - * - * It's required to provide the video frame's timestamp (in milliseconds). The input timestamps must - * be monotonically increasing. - * - * This method supports gesture recognition of RGBA images. If your `MPPImage` has a source type of - * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer - * must have one of the following pixel format types: - * 1. kCVPixelFormatType_32BGRA - * 2. kCVPixelFormatType_32RGBA - * - * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is - * RGB with an Alpha channel. - * - * @param image A live stream image data of type `MPPImage` on which gesture recognition is to be - * performed. - * @param timestampInMilliseconds The video frame's timestamp (in milliseconds). The input - * timestamps must be monotonically increasing. - * @param roi A `CGRect` specifying the region of interest within the video frame of type - * `MPPImage`, on which gesture recognition should be performed. - * @param error An optional error parameter populated when there is an error in performing gesture - * recognition on the input video frame. - * - * @return An `MPPGestureRecognizerResult` object that contains the hand gesture recognition - * results. - */ -- (nullable MPPGestureRecognizerResult *)recognizeVideoFrame:(MPPImage *)image - timestampInMilliseconds:(NSInteger)timestampInMilliseconds - regionOfInterest:(CGRect)roi - error:(NSError **)error - NS_SWIFT_NAME(recognize(videoFrame:timestampInMilliseconds:regionOfInterest:)); - /** * Sends live stream image data of type `MPPImage` to perform gesture recognition using the whole * image as region of interest. Rotation will be applied according to the `orientation` property of @@ -221,50 +156,6 @@ NS_SWIFT_NAME(GestureRecognizer) error:(NSError **)error NS_SWIFT_NAME(recognizeAsync(image:timestampInMilliseconds:)); -/** - * Sends live stream image data of type `MPPImage` to perform gesture recognition, cropped to the - * specified region of interest.. Rotation will be applied according to the `orientation` property - * of the provided `MPPImage`. Only use this method when the `MPPGestureRecognizer` is created with - * `MPPRunningModeLiveStream`. - * - * The object which needs to be continuously notified of the available results of gesture - * recognition must confirm to `MPPGestureRecognizerLiveStreamDelegate` protocol and implement the - * `gestureRecognizer:didFinishRecognitionWithResult:timestampInMilliseconds:error:` delegate - * method. - * - * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent - * to the gesture recognizer. The input timestamps must be monotonically increasing. - * - * This method supports gesture recognition of RGBA images. If your `MPPImage` has a source type of - * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer - * must have one of the following pixel format types: - * 1. kCVPixelFormatType_32BGRA - * 2. kCVPixelFormatType_32RGBA - * - * If the input `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color - * space is RGB with an Alpha channel. - * - * If this method is used for preforming gesture recognition on live camera frames using - * `AVFoundation`, ensure that you request `AVCaptureVideoDataOutput` to output frames in - * `kCMPixelFormat_32RGBA` using its `videoSettings` property. - * - * @param image A live stream image data of type `MPPImage` on which gesture recognition is to be - * performed. - * @param timestampInMilliseconds The timestamp (in milliseconds) which indicates when the input - * image is sent to the gesture recognizer. The input timestamps must be monotonically increasing. - * @param roi A `CGRect` specifying the region of interest within the given live stream image data - * of type `MPPImage`, on which gesture recognition should be performed. - * @param error An optional error parameter populated when there is an error in performing gesture - * recognition on the input live stream image data. - * - * @return `YES` if the image was sent to the task successfully, otherwise `NO`. - */ -- (BOOL)recognizeAsyncImage:(MPPImage *)image - timestampInMilliseconds:(NSInteger)timestampInMilliseconds - regionOfInterest:(CGRect)roi - error:(NSError **)error - NS_SWIFT_NAME(recognizeAsync(image:timestampInMilliseconds:regionOfInterest:)); - - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; From bb5fcc2d6426cec83d1b6ab70bafe8c10b409198 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Thu, 18 May 2023 10:00:31 +0530 Subject: [PATCH 292/753] Fixed Typos --- .../sources/MPPGestureRecognizerOptions.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h index 421073d45..925d5610b 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h @@ -37,7 +37,7 @@ NS_SWIFT_NAME(GestureRecognizerLiveStreamDelegate) @optional /** - * This method notifies a delegate that the results of asynchronous object detection of + * This method notifies a delegate that the results of asynchronous gesture recognition of * an image submitted to the `MPPGestureRecognizer` is available. * * This method is called on a private serial dispatch queue created by the `MPPGestureRecognizer` @@ -50,9 +50,9 @@ NS_SWIFT_NAME(GestureRecognizerLiveStreamDelegate) * coordinates system, i.e. in `[0,image_width) x [0,image_height)`, which are the dimensions of the * underlying image data. * @param timestampInMilliseconds The timestamp (in milliseconds) which indicates when the input - * image was sent to the object detector. - * @param error An optional error parameter populated when there is an error in performing object - * detection on the input live stream image data. + * image was sent to the gesture recognizer. + * @param error An optional error parameter populated when there is an error in performing gesture + * recognition on the input live stream image data. * */ - (void)gestureRecognizer:(MPPGestureRecognizer *)gestureRecognizer @@ -69,10 +69,10 @@ NS_SWIFT_NAME(GestureRecognizerOptions) /** * Running mode of the gesture recognizer task. Defaults to `MPPRunningModeImage`. * `MPPGestureRecognizer` can be created with one of the following running modes: - * 1. `MPPRunningModeImage`: The mode for performing object detection on single image inputs. - * 2. `MPPRunningModeVideo`: The mode for performing object detection on the decoded frames of a + * 1. `MPPRunningModeImage`: The mode for performing gesture recognition on single image inputs. + * 2. `MPPRunningModeVideo`: The mode for performing gesture recognition on the decoded frames of a * video. - * 3. `MPPRunningModeLiveStream`: The mode for performing object detection on a live stream of + * 3. `MPPRunningModeLiveStream`: The mode for performing gesture recognition on a live stream of * input data, such as from the camera. */ @property(nonatomic) MPPRunningMode runningMode; From 126df20658c11e6ef97f7c64bd781b9b3d768e9b Mon Sep 17 00:00:00 2001 From: Kinar R <42828719+kinaryml@users.noreply.github.com> Date: Thu, 18 May 2023 11:00:12 +0530 Subject: [PATCH 293/753] Included CPU binary graphs in setup.py --- setup.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/setup.py b/setup.py index 0712a95b0..ce162b594 100644 --- a/setup.py +++ b/setup.py @@ -246,18 +246,18 @@ class BuildModules(build_ext.build_ext): self._download_external_file(external_file) # CPU binary graphs - # binary_graphs = [ - # 'face_detection/face_detection_short_range_cpu', - # 'face_detection/face_detection_full_range_cpu', - # 'face_landmark/face_landmark_front_cpu', - # 'hand_landmark/hand_landmark_tracking_cpu', - # 'holistic_landmark/holistic_landmark_cpu', 'objectron/objectron_cpu', - # 'pose_landmark/pose_landmark_cpu', - # 'selfie_segmentation/selfie_segmentation_cpu' - # ] + binary_graphs = [ + 'face_detection/face_detection_short_range_cpu', + 'face_detection/face_detection_full_range_cpu', + 'face_landmark/face_landmark_front_cpu', + 'hand_landmark/hand_landmark_tracking_cpu', + 'holistic_landmark/holistic_landmark_cpu', 'objectron/objectron_cpu', + 'pose_landmark/pose_landmark_cpu', + 'selfie_segmentation/selfie_segmentation_cpu' + ] # GPU binary graphs - binary_graphs = [ + binary_graphs += [ 'face_detection/face_detection_short_range_gpu', 'face_detection/face_detection_full_range_gpu', 'face_landmark/face_landmark_front_gpu', From 620ff3508a1331c192a3103622da55b71fb37d6d Mon Sep 17 00:00:00 2001 From: Kinar R <42828719+kinaryml@users.noreply.github.com> Date: Thu, 18 May 2023 12:51:08 +0530 Subject: [PATCH 294/753] Update BUILD --- third_party/BUILD | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/third_party/BUILD b/third_party/BUILD index f6107106d..041812b74 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -167,6 +167,8 @@ cmake_external( "BUILD_PERF_TESTS": "OFF", "BUILD_EXAMPLES": "OFF", "BUILD_SHARED_LIBS": "ON" if OPENCV_SHARED_LIBS else "OFF", + # Disable IPP + "WITH_IPP": "OFF", "WITH_ITT": "OFF", "WITH_JASPER": "OFF", "WITH_JPEG": "ON", @@ -174,6 +176,9 @@ cmake_external( "WITH_TIFF": "ON", "WITH_OPENCL": "OFF", "WITH_WEBP": "OFF", + # Disable carotene_o4t + "ENABLE_NEON": "OFF", + "WITH_TENGINE": "OFF", # Optimization flags "CV_ENABLE_INTRINSICS": "ON", "WITH_EIGEN": "ON", From 14dba421c4406115f7dc059ca71c93a40cf91bf4 Mon Sep 17 00:00:00 2001 From: Kinar R <42828719+kinaryml@users.noreply.github.com> Date: Thu, 18 May 2023 13:23:44 +0530 Subject: [PATCH 295/753] Update BUILD --- third_party/BUILD | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/third_party/BUILD b/third_party/BUILD index 041812b74..68f203ccf 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -150,7 +150,7 @@ OPENCV_MODULES = [ # still only builds the shared libraries, so we have to choose one or the # other. We build shared libraries by default, but this variable can be used # to switch to static libraries. -OPENCV_SHARED_LIBS = True +OPENCV_SHARED_LIBS = False OPENCV_SO_VERSION = "3.4" @@ -168,7 +168,7 @@ cmake_external( "BUILD_EXAMPLES": "OFF", "BUILD_SHARED_LIBS": "ON" if OPENCV_SHARED_LIBS else "OFF", # Disable IPP - "WITH_IPP": "OFF", + # "WITH_IPP": "OFF", "WITH_ITT": "OFF", "WITH_JASPER": "OFF", "WITH_JPEG": "ON", @@ -177,8 +177,8 @@ cmake_external( "WITH_OPENCL": "OFF", "WITH_WEBP": "OFF", # Disable carotene_o4t - "ENABLE_NEON": "OFF", - "WITH_TENGINE": "OFF", + # "ENABLE_NEON": "OFF", + # "WITH_TENGINE": "OFF", # Optimization flags "CV_ENABLE_INTRINSICS": "ON", "WITH_EIGEN": "ON", From b5072c59e79fa2d8c9b24dd875ef928f1884144c Mon Sep 17 00:00:00 2001 From: Kinar R <42828719+kinaryml@users.noreply.github.com> Date: Thu, 18 May 2023 15:41:08 +0530 Subject: [PATCH 296/753] Update BUILD --- third_party/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/BUILD b/third_party/BUILD index 68f203ccf..6250088a8 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -168,7 +168,7 @@ cmake_external( "BUILD_EXAMPLES": "OFF", "BUILD_SHARED_LIBS": "ON" if OPENCV_SHARED_LIBS else "OFF", # Disable IPP - # "WITH_IPP": "OFF", + "WITH_IPP": "OFF", "WITH_ITT": "OFF", "WITH_JASPER": "OFF", "WITH_JPEG": "ON", From f63baaf8d24bb0b48715ff57944bb5a057a8cfb4 Mon Sep 17 00:00:00 2001 From: Kinar R <42828719+kinaryml@users.noreply.github.com> Date: Thu, 18 May 2023 18:08:04 +0530 Subject: [PATCH 297/753] Update BUILD --- third_party/BUILD | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/third_party/BUILD b/third_party/BUILD index 6250088a8..fbec0b351 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -150,7 +150,7 @@ OPENCV_MODULES = [ # still only builds the shared libraries, so we have to choose one or the # other. We build shared libraries by default, but this variable can be used # to switch to static libraries. -OPENCV_SHARED_LIBS = False +OPENCV_SHARED_LIBS = True OPENCV_SO_VERSION = "3.4" @@ -167,8 +167,6 @@ cmake_external( "BUILD_PERF_TESTS": "OFF", "BUILD_EXAMPLES": "OFF", "BUILD_SHARED_LIBS": "ON" if OPENCV_SHARED_LIBS else "OFF", - # Disable IPP - "WITH_IPP": "OFF", "WITH_ITT": "OFF", "WITH_JASPER": "OFF", "WITH_JPEG": "ON", @@ -176,6 +174,9 @@ cmake_external( "WITH_TIFF": "ON", "WITH_OPENCL": "OFF", "WITH_WEBP": "OFF", + # Disable IPP + "WITH_IPP": "OFF", + "WITH_OPENEXR": "OFF", # Disable carotene_o4t # "ENABLE_NEON": "OFF", # "WITH_TENGINE": "OFF", From 6100f0e76eb6667521ebf423ae7750e1cbe6dbf5 Mon Sep 17 00:00:00 2001 From: Kinar R <42828719+kinaryml@users.noreply.github.com> Date: Thu, 18 May 2023 18:09:39 +0530 Subject: [PATCH 298/753] Update base_options.py --- mediapipe/tasks/python/core/base_options.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/python/core/base_options.py b/mediapipe/tasks/python/core/base_options.py index 8247f15bd..2d74b16eb 100644 --- a/mediapipe/tasks/python/core/base_options.py +++ b/mediapipe/tasks/python/core/base_options.py @@ -16,6 +16,7 @@ import dataclasses import enum import os +import platform from typing import Any, Optional from mediapipe.calculators.tensor import inference_calculator_pb2 @@ -63,10 +64,22 @@ class BaseOptions: else: full_path = None - if self.delegate == BaseOptions.Delegate.GPU: - acceleration_proto = _AccelerationProto(gpu=_DelegateProto.Gpu()) + platform = platform.system() + + if self.delegate is not None: + if platform == "Linux": + if self.delegate == BaseOptions.Delegate.GPU: + acceleration_proto = _AccelerationProto(gpu=_DelegateProto.Gpu()) + else: + acceleration_proto = _AccelerationProto(tflite=_DelegateProto.TfLite()) + elif platform == "Windows": + raise Exception("Delegate is unsupported for Windows.") + elif platform == "Darwin": + raise Exception("Delegate is unsupported for MacOS.") + else: + raise Exception("Unidentified system") else: - acceleration_proto = _AccelerationProto(tflite=_DelegateProto.TfLite()) + acceleration_proto = None return _BaseOptionsProto( model_asset=_ExternalFileProto( From 01fdeaf1e18e74c352d18ed65e5213eec4845f29 Mon Sep 17 00:00:00 2001 From: Kinar R <42828719+kinaryml@users.noreply.github.com> Date: Thu, 18 May 2023 18:29:22 +0530 Subject: [PATCH 299/753] Update Dockerfile --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 03b335823..c7c459190 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,8 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM ubuntu:20.04 - +FROM nvidia/cudagl:11.3.0-devel-ubuntu20.04 MAINTAINER WORKDIR /io From b5148c8ce36701a6ecd1df65b5823cde21fa6399 Mon Sep 17 00:00:00 2001 From: Kinar R <42828719+kinaryml@users.noreply.github.com> Date: Thu, 18 May 2023 18:32:45 +0530 Subject: [PATCH 300/753] Update setup.py --- setup.py | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/setup.py b/setup.py index ce162b594..c49169191 100644 --- a/setup.py +++ b/setup.py @@ -284,24 +284,6 @@ class BuildModules(build_ext.build_ext): sys.exit(-1) _copy_to_build_lib_dir(self.build_lib, external_file) - # def _generate_binary_graph(self, binary_graph_target): - # """Generate binary graph for a particular MediaPipe binary graph target.""" - # - # bazel_command = [ - # 'bazel', - # 'build', - # '--compilation_mode=opt', - # '--copt=-DNDEBUG', - # '--define=MEDIAPIPE_DISABLE_GPU=1', - # '--action_env=PYTHON_BIN_PATH=' + _normalize_path(sys.executable), - # binary_graph_target, - # ] - # if not self.link_opencv and not IS_WINDOWS: - # bazel_command.append('--define=OPENCV=source') - # if subprocess.call(bazel_command) != 0: - # sys.exit(-1) - # _copy_to_build_lib_dir(self.build_lib, binary_graph_target + '.binarypb') - def _generate_binary_graph(self, binary_graph_target): """Generate binary graph for a particular MediaPipe binary graph target.""" @@ -332,14 +314,6 @@ class GenerateMetadataSchema(build_ext.build_ext): 'object_detector_metadata_schema_py', 'schema_py', ]: - # bazel_command = [ - # 'bazel', - # 'build', - # '--compilation_mode=opt', - # '--define=MEDIAPIPE_DISABLE_GPU=1', - # '--action_env=PYTHON_BIN_PATH=' + _normalize_path(sys.executable), - # '//mediapipe/tasks/metadata:' + target, - # ] bazel_command = [ 'bazel', @@ -427,15 +401,6 @@ class BuildExtension(build_ext.build_ext): def _build_binary(self, ext, extra_args=None): if not os.path.exists(self.build_temp): os.makedirs(self.build_temp) - # bazel_command = [ - # 'bazel', - # 'build', - # '--compilation_mode=opt', - # '--copt=-DNDEBUG', - # '--define=MEDIAPIPE_DISABLE_GPU=1', - # '--action_env=PYTHON_BIN_PATH=' + _normalize_path(sys.executable), - # str(ext.bazel_target + '.so'), - # ] bazel_command = [ 'bazel', 'build', From 03b901a443f5635210590e941e8d1d8436f68ffd Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 18 May 2023 09:14:06 -0700 Subject: [PATCH 301/753] Internal change PiperOrigin-RevId: 533150010 --- mediapipe/tasks/python/test/vision/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/mediapipe/tasks/python/test/vision/BUILD b/mediapipe/tasks/python/test/vision/BUILD index 9efec7f2a..ae3d53d61 100644 --- a/mediapipe/tasks/python/test/vision/BUILD +++ b/mediapipe/tasks/python/test/vision/BUILD @@ -201,6 +201,7 @@ py_test( "//mediapipe/tasks/testdata/vision:test_images", "//mediapipe/tasks/testdata/vision:test_models", ], + tags = ["not_run:arm"], deps = [ "//mediapipe/python:_framework_bindings", "//mediapipe/tasks/python/components/containers:rect", From a1755044ea8ef5a4161065e59e5c0dd010c105b6 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 18 May 2023 11:08:13 -0700 Subject: [PATCH 302/753] Internal change PiperOrigin-RevId: 533187060 --- mediapipe/gpu/gpu_buffer_format.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mediapipe/gpu/gpu_buffer_format.cc b/mediapipe/gpu/gpu_buffer_format.cc index a820f04d6..00ee9e248 100644 --- a/mediapipe/gpu/gpu_buffer_format.cc +++ b/mediapipe/gpu/gpu_buffer_format.cc @@ -28,6 +28,12 @@ namespace mediapipe { #define GL_HALF_FLOAT 0x140B #endif // GL_HALF_FLOAT +#ifdef __EMSCRIPTEN__ +#ifndef GL_HALF_FLOAT_OES +#define GL_HALF_FLOAT_OES 0x8D61 +#endif // GL_HALF_FLOAT_OES +#endif // __EMSCRIPTEN__ + #if !MEDIAPIPE_DISABLE_GPU #ifdef GL_ES_VERSION_2_0 static void AdaptGlTextureInfoForGLES2(GlTextureInfo* info) { @@ -48,6 +54,12 @@ static void AdaptGlTextureInfoForGLES2(GlTextureInfo* info) { case GL_RG8: info->gl_internal_format = info->gl_format = GL_RG_EXT; return; +#ifdef __EMSCRIPTEN__ + case GL_RGBA16F: + info->gl_internal_format = GL_RGBA; + info->gl_type = GL_HALF_FLOAT_OES; + return; +#endif // __EMSCRIPTEN__ default: return; } From c248525eeb17da110346ec76a9865de5a20d4c4d Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 18 May 2023 11:37:13 -0700 Subject: [PATCH 303/753] internal update PiperOrigin-RevId: 533197055 --- .../tensors_to_segmentation_calculator.cc | 32 ++++++++++++++--- .../vision/image_segmenter/image_segmenter.cc | 18 ++++++++-- .../image_segmenter/image_segmenter_graph.cc | 36 ++++++++++++------- .../image_segmenter/image_segmenter_result.h | 4 +++ .../interactive_segmenter.cc | 8 ++++- .../interactive_segmenter_graph.cc | 3 ++ .../vision/imagesegmenter/ImageSegmenter.java | 14 ++++++-- .../imagesegmenter/ImageSegmenterResult.java | 15 ++++++-- .../InteractiveSegmenter.java | 13 +++++++ 9 files changed, 119 insertions(+), 24 deletions(-) diff --git a/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.cc b/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.cc index 660dc59b7..f77855587 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/calculators/tensors_to_segmentation_calculator.cc @@ -291,8 +291,11 @@ class TensorsToSegmentationCalculator : public Node { static constexpr Output::Multiple kConfidenceMaskOut{ "CONFIDENCE_MASK"}; static constexpr Output::Optional kCategoryMaskOut{"CATEGORY_MASK"}; + static constexpr Output>::Optional kQualityScoresOut{ + "QUALITY_SCORES"}; MEDIAPIPE_NODE_CONTRACT(kTensorsIn, kOutputSizeIn, kSegmentationOut, - kConfidenceMaskOut, kCategoryMaskOut); + kConfidenceMaskOut, kCategoryMaskOut, + kQualityScoresOut); static absl::Status UpdateContract(CalculatorContract* cc); @@ -345,12 +348,33 @@ absl::Status TensorsToSegmentationCalculator::Open( absl::Status TensorsToSegmentationCalculator::Process( mediapipe::CalculatorContext* cc) { - RET_CHECK_EQ(kTensorsIn(cc).Get().size(), 1) - << "Expect a vector of single Tensor."; - const auto& input_tensor = kTensorsIn(cc).Get()[0]; + const auto& input_tensors = kTensorsIn(cc).Get(); + if (input_tensors.size() != 1 && input_tensors.size() != 2) { + return absl::InvalidArgumentError( + "Expect input tensor vector of size 1 or 2."); + } + const auto& input_tensor = *input_tensors.rbegin(); ASSIGN_OR_RETURN(const Shape input_shape, GetImageLikeTensorShape(input_tensor)); + // TODO: should use tensor signature to get the correct output + // tensor. + if (input_tensors.size() == 2) { + const auto& quality_tensor = input_tensors[0]; + const float* quality_score_buffer = + quality_tensor.GetCpuReadView().buffer(); + const std::vector quality_scores( + quality_score_buffer, + quality_score_buffer + + (quality_tensor.bytes() / quality_tensor.element_size())); + kQualityScoresOut(cc).Send(quality_scores); + } else { + // If the input_tensors don't contain quality scores, send the default + // quality scores as 1. + const std::vector quality_scores(input_shape.channels, 1.0f); + kQualityScoresOut(cc).Send(quality_scores); + } + // Category mask does not require activation function. if (options_.segmenter_options().output_type() == SegmenterOptions::CONFIDENCE_MASK && diff --git a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.cc b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.cc index a67843258..99faa1064 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter.cc @@ -46,6 +46,8 @@ constexpr char kImageOutStreamName[] = "image_out"; constexpr char kImageTag[] = "IMAGE"; constexpr char kNormRectStreamName[] = "norm_rect_in"; constexpr char kNormRectTag[] = "NORM_RECT"; +constexpr char kQualityScoresStreamName[] = "quality_scores"; +constexpr char kQualityScoresTag[] = "QUALITY_SCORES"; constexpr char kSubgraphTypeName[] = "mediapipe.tasks.vision.image_segmenter.ImageSegmenterGraph"; constexpr int kMicroSecondsPerMilliSecond = 1000; @@ -77,6 +79,8 @@ CalculatorGraphConfig CreateGraphConfig( task_subgraph.Out(kCategoryMaskTag).SetName(kCategoryMaskStreamName) >> graph.Out(kCategoryMaskTag); } + task_subgraph.Out(kQualityScoresTag).SetName(kQualityScoresStreamName) >> + graph.Out(kQualityScoresTag); task_subgraph.Out(kImageTag).SetName(kImageOutStreamName) >> graph.Out(kImageTag); if (enable_flow_limiting) { @@ -172,9 +176,13 @@ absl::StatusOr> ImageSegmenter::Create( category_mask = status_or_packets.value()[kCategoryMaskStreamName].Get(); } + const std::vector& quality_scores = + status_or_packets.value()[kQualityScoresStreamName] + .Get>(); Packet image_packet = status_or_packets.value()[kImageOutStreamName]; result_callback( - {{confidence_masks, category_mask}}, image_packet.Get(), + {{confidence_masks, category_mask, quality_scores}}, + image_packet.Get(), image_packet.Timestamp().Value() / kMicroSecondsPerMilliSecond); }; } @@ -227,7 +235,9 @@ absl::StatusOr ImageSegmenter::Segment( if (output_category_mask_) { category_mask = output_packets[kCategoryMaskStreamName].Get(); } - return {{confidence_masks, category_mask}}; + const std::vector& quality_scores = + output_packets[kQualityScoresStreamName].Get>(); + return {{confidence_masks, category_mask, quality_scores}}; } absl::StatusOr ImageSegmenter::SegmentForVideo( @@ -260,7 +270,9 @@ absl::StatusOr ImageSegmenter::SegmentForVideo( if (output_category_mask_) { category_mask = output_packets[kCategoryMaskStreamName].Get(); } - return {{confidence_masks, category_mask}}; + const std::vector& quality_scores = + output_packets[kQualityScoresStreamName].Get>(); + return {{confidence_masks, category_mask, quality_scores}}; } absl::Status ImageSegmenter::SegmentAsync( diff --git a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_graph.cc b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_graph.cc index 6ecfa3685..0ae47ffd1 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_graph.cc +++ b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_graph.cc @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ +#include #include #include #include @@ -81,6 +82,7 @@ constexpr char kImageGpuTag[] = "IMAGE_GPU"; constexpr char kNormRectTag[] = "NORM_RECT"; constexpr char kTensorsTag[] = "TENSORS"; constexpr char kOutputSizeTag[] = "OUTPUT_SIZE"; +constexpr char kQualityScoresTag[] = "QUALITY_SCORES"; constexpr char kSegmentationMetadataName[] = "SEGMENTER_METADATA"; // Struct holding the different output streams produced by the image segmenter @@ -90,6 +92,7 @@ struct ImageSegmenterOutputs { std::optional>> confidence_masks; std::optional> category_mask; // The same as the input image, mainly used for live stream mode. + std::optional>> quality_scores; Source image; }; @@ -191,19 +194,12 @@ absl::Status ConfigureTensorsToSegmentationCalculator( "Segmentation tflite models are assumed to have a single subgraph.", MediaPipeTasksStatus::kInvalidArgumentError); } - const auto* primary_subgraph = (*model.subgraphs())[0]; - if (primary_subgraph->outputs()->size() != 1) { - return CreateStatusWithPayload( - absl::StatusCode::kInvalidArgument, - "Segmentation tflite models are assumed to have a single output.", - MediaPipeTasksStatus::kInvalidArgumentError); - } - ASSIGN_OR_RETURN( *options->mutable_label_items(), - GetLabelItemsIfAny(*metadata_extractor, - *metadata_extractor->GetOutputTensorMetadata()->Get(0), - segmenter_option.display_names_locale())); + GetLabelItemsIfAny( + *metadata_extractor, + **metadata_extractor->GetOutputTensorMetadata()->crbegin(), + segmenter_option.display_names_locale())); return absl::OkStatus(); } @@ -213,10 +209,16 @@ absl::StatusOr GetOutputTensor( const tflite::Model& model = *model_resources.GetTfLiteModel(); const auto* primary_subgraph = (*model.subgraphs())[0]; const auto* output_tensor = - (*primary_subgraph->tensors())[(*primary_subgraph->outputs())[0]]; + (*primary_subgraph->tensors())[*(*primary_subgraph->outputs()).rbegin()]; return output_tensor; } +uint32_t GetOutputTensorsSize(const core::ModelResources& model_resources) { + const tflite::Model& model = *model_resources.GetTfLiteModel(); + const auto* primary_subgraph = (*model.subgraphs())[0]; + return primary_subgraph->outputs()->size(); +} + // Get the input tensor from the tflite model of given model resources. absl::StatusOr GetInputTensor( const core::ModelResources& model_resources) { @@ -433,6 +435,10 @@ class ImageSegmenterGraph : public core::ModelTaskGraph { *output_streams.category_mask >> graph[Output(kCategoryMaskTag)]; } } + if (output_streams.quality_scores) { + *output_streams.quality_scores >> + graph[Output>::Optional(kQualityScoresTag)]; + } output_streams.image >> graph[Output(kImageTag)]; return graph.GetConfig(); } @@ -530,9 +536,12 @@ class ImageSegmenterGraph : public core::ModelTaskGraph { tensor_to_images[Output::Multiple(kSegmentationTag)][i])); } } + auto quality_scores = + tensor_to_images[Output>(kQualityScoresTag)]; return ImageSegmenterOutputs{/*segmented_masks=*/segmented_masks, /*confidence_masks=*/std::nullopt, /*category_mask=*/std::nullopt, + /*quality_scores=*/quality_scores, /*image=*/image_and_tensors.image}; } else { std::optional>> confidence_masks; @@ -552,9 +561,12 @@ class ImageSegmenterGraph : public core::ModelTaskGraph { if (output_category_mask_) { category_mask = tensor_to_images[Output(kCategoryMaskTag)]; } + auto quality_scores = + tensor_to_images[Output>(kQualityScoresTag)]; return ImageSegmenterOutputs{/*segmented_masks=*/std::nullopt, /*confidence_masks=*/confidence_masks, /*category_mask=*/category_mask, + /*quality_scores=*/quality_scores, /*image=*/image_and_tensors.image}; } } diff --git a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_result.h b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_result.h index 1e7968ebd..a203718f4 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_result.h +++ b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_result.h @@ -33,6 +33,10 @@ struct ImageSegmenterResult { // A category mask of uint8 image in GRAY8 format where each pixel represents // the class which the pixel in the original image was predicted to belong to. std::optional category_mask; + // The quality scores of the result masks, in the range of [0, 1]. Default to + // `1` if the model doesn't output quality scores. Each element corresponds to + // the score of the category in the model outputs. + std::vector quality_scores; }; } // namespace image_segmenter diff --git a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc index c0d89c87d..38bbf3baf 100644 --- a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc +++ b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter.cc @@ -51,12 +51,14 @@ constexpr char kImageInStreamName[] = "image_in"; constexpr char kImageOutStreamName[] = "image_out"; constexpr char kRoiStreamName[] = "roi_in"; constexpr char kNormRectStreamName[] = "norm_rect_in"; +constexpr char kQualityScoresStreamName[] = "quality_scores"; constexpr absl::string_view kConfidenceMasksTag{"CONFIDENCE_MASKS"}; constexpr absl::string_view kCategoryMaskTag{"CATEGORY_MASK"}; constexpr absl::string_view kImageTag{"IMAGE"}; constexpr absl::string_view kRoiTag{"ROI"}; constexpr absl::string_view kNormRectTag{"NORM_RECT"}; +constexpr absl::string_view kQualityScoresTag{"QUALITY_SCORES"}; constexpr absl::string_view kSubgraphTypeName{ "mediapipe.tasks.vision.interactive_segmenter.InteractiveSegmenterGraph"}; @@ -91,6 +93,8 @@ CalculatorGraphConfig CreateGraphConfig( task_subgraph.Out(kCategoryMaskTag).SetName(kCategoryMaskStreamName) >> graph.Out(kCategoryMaskTag); } + task_subgraph.Out(kQualityScoresTag).SetName(kQualityScoresStreamName) >> + graph.Out(kQualityScoresTag); task_subgraph.Out(kImageTag).SetName(kImageOutStreamName) >> graph.Out(kImageTag); graph.In(kImageTag) >> task_subgraph.In(kImageTag); @@ -201,7 +205,9 @@ absl::StatusOr InteractiveSegmenter::Segment( if (output_category_mask_) { category_mask = output_packets[kCategoryMaskStreamName].Get(); } - return {{confidence_masks, category_mask}}; + const std::vector& quality_scores = + output_packets[kQualityScoresStreamName].Get>(); + return {{confidence_masks, category_mask, quality_scores}}; } } // namespace interactive_segmenter diff --git a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_graph.cc b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_graph.cc index a765997d8..5bb3e8ece 100644 --- a/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_graph.cc +++ b/mediapipe/tasks/cc/vision/interactive_segmenter/interactive_segmenter_graph.cc @@ -58,6 +58,7 @@ constexpr absl::string_view kAlphaTag{"ALPHA"}; constexpr absl::string_view kAlphaGpuTag{"ALPHA_GPU"}; constexpr absl::string_view kNormRectTag{"NORM_RECT"}; constexpr absl::string_view kRoiTag{"ROI"}; +constexpr absl::string_view kQualityScoresTag{"QUALITY_SCORES"}; // Updates the graph to return `roi` stream which has same dimension as // `image`, and rendered with `roi`. If `use_gpu` is true, returned `Source` is @@ -200,6 +201,8 @@ class InteractiveSegmenterGraph : public core::ModelTaskGraph { graph[Output(kCategoryMaskTag)]; } } + image_segmenter.Out(kQualityScoresTag) >> + graph[Output>::Optional(kQualityScoresTag)]; image_segmenter.Out(kImageTag) >> graph[Output(kImageTag)]; return graph.GetConfig(); diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java index 3d6df3022..f977c0159 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenter.java @@ -115,6 +115,8 @@ public final class ImageSegmenter extends BaseVisionTaskApi { segmenterOptions.outputCategoryMask() ? getStreamIndex.apply(outputStreams, "CATEGORY_MASK:category_mask") : -1; + final int qualityScoresOutStreamIndex = + getStreamIndex.apply(outputStreams, "QUALITY_SCORES:quality_scores"); final int imageOutStreamIndex = getStreamIndex.apply(outputStreams, "IMAGE:image_out"); // TODO: Consolidate OutputHandler and TaskRunner. @@ -128,6 +130,7 @@ public final class ImageSegmenter extends BaseVisionTaskApi { return ImageSegmenterResult.create( Optional.empty(), Optional.empty(), + new ArrayList<>(), packets.get(imageOutStreamIndex).getTimestamp()); } boolean copyImage = !segmenterOptions.resultListener().isPresent(); @@ -182,9 +185,16 @@ public final class ImageSegmenter extends BaseVisionTaskApi { new ByteBufferImageBuilder(buffer, width, height, MPImage.IMAGE_FORMAT_ALPHA); categoryMask = Optional.of(builder.build()); } + float[] qualityScores = + PacketGetter.getFloat32Vector(packets.get(qualityScoresOutStreamIndex)); + List qualityScoresList = new ArrayList<>(qualityScores.length); + for (float score : qualityScores) { + qualityScoresList.add(score); + } return ImageSegmenterResult.create( confidenceMasks, categoryMask, + qualityScoresList, BaseVisionTaskApi.generateResultTimestampMs( segmenterOptions.runningMode(), packets.get(imageOutStreamIndex))); } @@ -592,8 +602,8 @@ public final class ImageSegmenter extends BaseVisionTaskApi { public abstract Builder setOutputCategoryMask(boolean value); /** - * Sets an optional {@link ResultListener} to receive the segmentation results when the graph - * pipeline is done processing an image. + * /** Sets an optional {@link ResultListener} to receive the segmentation results when the + * graph pipeline is done processing an image. */ public abstract Builder setResultListener( ResultListener value); diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterResult.java index cbc5211cc..e4ac85c2f 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterResult.java @@ -34,19 +34,30 @@ public abstract class ImageSegmenterResult implements TaskResult { * @param categoryMask an {@link Optional} MPImage in IMAGE_FORMAT_ALPHA format representing a * category mask, where each pixel represents the class which the pixel in the original image * was predicted to belong to. + * @param qualityScores The quality scores of the result masks, in the range of [0, 1]. Default to + * `1` if the model doesn't output quality scores. Each element corresponds to the score of + * the category in the model outputs. * @param timestampMs a timestamp for this result. */ // TODO: consolidate output formats across platforms. public static ImageSegmenterResult create( - Optional> confidenceMasks, Optional categoryMask, long timestampMs) { + Optional> confidenceMasks, + Optional categoryMask, + List qualityScores, + long timestampMs) { return new AutoValue_ImageSegmenterResult( - confidenceMasks.map(Collections::unmodifiableList), categoryMask, timestampMs); + confidenceMasks.map(Collections::unmodifiableList), + categoryMask, + Collections.unmodifiableList(qualityScores), + timestampMs); } public abstract Optional> confidenceMasks(); public abstract Optional categoryMask(); + public abstract List qualityScores(); + @Override public abstract long timestampMs(); } diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java index e9ff1f2b5..fe0ce0c3f 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/interactivesegmenter/InteractiveSegmenter.java @@ -127,6 +127,10 @@ public final class InteractiveSegmenter extends BaseVisionTaskApi { outputStreams.add("CATEGORY_MASK:category_mask"); } final int categoryMaskOutStreamIndex = outputStreams.size() - 1; + + outputStreams.add("QUALITY_SCORES:quality_scores"); + final int qualityScoresOutStreamIndex = outputStreams.size() - 1; + outputStreams.add("IMAGE:image_out"); // TODO: add test for stream indices. final int imageOutStreamIndex = outputStreams.size() - 1; @@ -142,6 +146,7 @@ public final class InteractiveSegmenter extends BaseVisionTaskApi { return ImageSegmenterResult.create( Optional.empty(), Optional.empty(), + new ArrayList<>(), packets.get(imageOutStreamIndex).getTimestamp()); } // If resultListener is not provided, the resulted MPImage is deep copied from @@ -199,9 +204,17 @@ public final class InteractiveSegmenter extends BaseVisionTaskApi { categoryMask = Optional.of(builder.build()); } + float[] qualityScores = + PacketGetter.getFloat32Vector(packets.get(qualityScoresOutStreamIndex)); + List qualityScoresList = new ArrayList<>(qualityScores.length); + for (float score : qualityScores) { + qualityScoresList.add(score); + } + return ImageSegmenterResult.create( confidenceMasks, categoryMask, + qualityScoresList, BaseVisionTaskApi.generateResultTimestampMs( RunningMode.IMAGE, packets.get(imageOutStreamIndex))); } From 937a6b14228591e30f74142ba4f51e456224bb35 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 18 May 2023 20:17:07 -0700 Subject: [PATCH 304/753] Internal change PiperOrigin-RevId: 533327411 --- mediapipe/gpu/BUILD | 6 +++++- mediapipe/gpu/gpu_service.h | 3 ++- mediapipe/gpu/gpu_shared_data_internal.cc | 3 ++- mediapipe/tasks/cc/core/model_resources_cache.h | 4 ++-- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/mediapipe/gpu/BUILD b/mediapipe/gpu/BUILD index c785e5624..e7c65b7c6 100644 --- a/mediapipe/gpu/BUILD +++ b/mediapipe/gpu/BUILD @@ -38,7 +38,10 @@ cc_library( srcs = ["gpu_service.cc"], hdrs = ["gpu_service.h"], visibility = ["//visibility:public"], - deps = ["//mediapipe/framework:graph_service"] + select({ + deps = [ + "//mediapipe/framework:graph_service", + "@com_google_absl//absl/base:core_headers", + ] + select({ "//conditions:default": [ ":gpu_shared_data_internal", ], @@ -630,6 +633,7 @@ cc_library( "//mediapipe/framework:executor", "//mediapipe/framework/deps:no_destructor", "//mediapipe/framework/port:ret_check", + "@com_google_absl//absl/base:core_headers", ] + select({ "//conditions:default": [], "//mediapipe:apple": [ diff --git a/mediapipe/gpu/gpu_service.h b/mediapipe/gpu/gpu_service.h index 65fecd0b8..dd3bd3bf5 100644 --- a/mediapipe/gpu/gpu_service.h +++ b/mediapipe/gpu/gpu_service.h @@ -15,6 +15,7 @@ #ifndef MEDIAPIPE_GPU_GPU_SERVICE_H_ #define MEDIAPIPE_GPU_GPU_SERVICE_H_ +#include "absl/base/attributes.h" #include "mediapipe/framework/graph_service.h" #if !MEDIAPIPE_DISABLE_GPU @@ -29,7 +30,7 @@ class GpuResources { }; #endif // MEDIAPIPE_DISABLE_GPU -extern const GraphService kGpuService; +ABSL_CONST_INIT extern const GraphService kGpuService; } // namespace mediapipe diff --git a/mediapipe/gpu/gpu_shared_data_internal.cc b/mediapipe/gpu/gpu_shared_data_internal.cc index f542f0bb2..1098c82ec 100644 --- a/mediapipe/gpu/gpu_shared_data_internal.cc +++ b/mediapipe/gpu/gpu_shared_data_internal.cc @@ -14,6 +14,7 @@ #include "mediapipe/gpu/gpu_shared_data_internal.h" +#include "absl/base/attributes.h" #include "mediapipe/framework/deps/no_destructor.h" #include "mediapipe/framework/port/ret_check.h" #include "mediapipe/gpu/gl_context.h" @@ -116,7 +117,7 @@ GpuResources::~GpuResources() { #endif // __APPLE__ } -extern const GraphService kGpuService; +ABSL_CONST_INIT extern const GraphService kGpuService; absl::Status GpuResources::PrepareGpuNode(CalculatorNode* node) { CHECK(node->Contract().ServiceRequests().contains(kGpuService.key)); diff --git a/mediapipe/tasks/cc/core/model_resources_cache.h b/mediapipe/tasks/cc/core/model_resources_cache.h index 75c24f344..113cfb2d4 100644 --- a/mediapipe/tasks/cc/core/model_resources_cache.h +++ b/mediapipe/tasks/cc/core/model_resources_cache.h @@ -103,8 +103,8 @@ class ModelResourcesCache { }; // Global service for mediapipe task model resources cache. -const mediapipe::GraphService kModelResourcesCacheService( - "mediapipe::tasks::ModelResourcesCacheService"); +inline constexpr mediapipe::GraphService + kModelResourcesCacheService("mediapipe::tasks::ModelResourcesCacheService"); } // namespace core } // namespace tasks From f219829b1d353d8410d7226aa594741acff9898e Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Fri, 19 May 2023 17:42:57 +0530 Subject: [PATCH 305/753] Removed support for Delegates from iOS --- .../tasks/ios/core/sources/MPPBaseOptions.h | 17 ----------------- .../tasks/ios/core/sources/MPPBaseOptions.m | 1 - .../utils/sources/MPPBaseOptions+Helpers.mm | 15 +-------------- 3 files changed, 1 insertion(+), 32 deletions(-) diff --git a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h index 603be803d..bef6bb9ee 100644 --- a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h +++ b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h @@ -16,17 +16,6 @@ NS_ASSUME_NONNULL_BEGIN -/** - * MediaPipe Tasks delegate. - */ -typedef NS_ENUM(NSUInteger, MPPDelegate) { - /** CPU. */ - MPPDelegateCPU, - - /** GPU. */ - MPPDelegateGPU -} NS_SWIFT_NAME(Delegate); - /** * Holds the base options that is used for creation of any type of task. It has fields with * important information acceleration configuration, TFLite model source etc. @@ -37,12 +26,6 @@ NS_SWIFT_NAME(BaseOptions) /** The path to the model asset to open and mmap in memory. */ @property(nonatomic, copy) NSString *modelAssetPath; -/** - * Device delegate to run the MediaPipe pipeline. If the delegate is not set, the default - * delegate CPU is used. - */ -@property(nonatomic) MPPDelegate delegate; - @end NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m index c3571c4b4..a43119ad8 100644 --- a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m +++ b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m @@ -28,7 +28,6 @@ MPPBaseOptions *baseOptions = [[MPPBaseOptions alloc] init]; baseOptions.modelAssetPath = self.modelAssetPath; - baseOptions.delegate = self.delegate; return baseOptions; } diff --git a/mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.mm b/mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.mm index f7f8e5a55..eceed4998 100644 --- a/mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.mm +++ b/mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.mm @@ -33,20 +33,7 @@ using BaseOptionsProto = ::mediapipe::tasks::core::proto::BaseOptions; if (self.modelAssetPath) { baseOptionsProto->mutable_model_asset()->set_file_name(self.modelAssetPath.UTF8String); } - - switch (self.delegate) { - case MPPDelegateCPU: { - baseOptionsProto->mutable_acceleration()->mutable_tflite(); - break; - } - case MPPDelegateGPU: { - // TODO: Provide an implementation for GPU Delegate. - [NSException raise:@"Invalid value for delegate" format:@"GPU Delegate is not implemented."]; - break; - } - default: - break; - } + } @end From 7c28c5d58ffbcb72043cbe8c9cc32b40aaebac41 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Fri, 19 May 2023 14:24:19 -0700 Subject: [PATCH 306/753] Fix rendering of MPMask and MPImage clone PiperOrigin-RevId: 533551170 --- mediapipe/tasks/web/vision/core/image.test.ts | 4 +++ mediapipe/tasks/web/vision/core/image.ts | 31 +++++++++++++------ mediapipe/tasks/web/vision/core/mask.test.ts | 5 ++- mediapipe/tasks/web/vision/core/mask.ts | 27 +++++++++++----- 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/image.test.ts b/mediapipe/tasks/web/vision/core/image.test.ts index e92debc2e..3c30c7293 100644 --- a/mediapipe/tasks/web/vision/core/image.test.ts +++ b/mediapipe/tasks/web/vision/core/image.test.ts @@ -60,6 +60,10 @@ class MPImageTestContext { this.webGLTexture = gl.createTexture()!; gl.bindTexture(gl.TEXTURE_2D, this.webGLTexture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.imageBitmap); gl.bindTexture(gl.TEXTURE_2D, null); diff --git a/mediapipe/tasks/web/vision/core/image.ts b/mediapipe/tasks/web/vision/core/image.ts index 3b067bd78..9a5d0de86 100644 --- a/mediapipe/tasks/web/vision/core/image.ts +++ b/mediapipe/tasks/web/vision/core/image.ts @@ -187,10 +187,11 @@ export class MPImage { destinationContainer = assertNotNull(gl.createTexture(), 'Failed to create texture'); gl.bindTexture(gl.TEXTURE_2D, destinationContainer); - + this.configureTextureParams(); gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.bindTexture(gl.TEXTURE_2D, null); shaderContext.bindFramebuffer(gl, destinationContainer); shaderContext.run(gl, /* flipVertically= */ false, () => { @@ -302,6 +303,20 @@ export class MPImage { return webGLTexture; } + /** Sets texture params for the currently bound texture. */ + private configureTextureParams() { + const gl = this.getGL(); + // `gl.LINEAR` might break rendering for some textures, but it allows us to + // do smooth resizing. Ideally, this would be user-configurable, but for now + // we hard-code the value here to `gl.LINEAR` (versus `gl.NEAREST` for + // `MPMask` where we do not want to interpolate mask values, especially for + // category masks). + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + } + /** * Binds the backing texture to the canvas. If the texture does not yet * exist, creates it first. @@ -318,16 +333,12 @@ export class MPImage { assertNotNull(gl.createTexture(), 'Failed to create texture'); this.containers.push(webGLTexture); this.ownsWebGLTexture = true; + + gl.bindTexture(gl.TEXTURE_2D, webGLTexture); + this.configureTextureParams(); + } else { + gl.bindTexture(gl.TEXTURE_2D, webGLTexture); } - - gl.bindTexture(gl.TEXTURE_2D, webGLTexture); - // TODO: Ideally, we would only set these once per texture and - // not once every frame. - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - return webGLTexture; } diff --git a/mediapipe/tasks/web/vision/core/mask.test.ts b/mediapipe/tasks/web/vision/core/mask.test.ts index b632f2dc5..d2f5ddb09 100644 --- a/mediapipe/tasks/web/vision/core/mask.test.ts +++ b/mediapipe/tasks/web/vision/core/mask.test.ts @@ -60,8 +60,11 @@ class MPMaskTestContext { } this.webGLTexture = gl.createTexture()!; - gl.bindTexture(gl.TEXTURE_2D, this.webGLTexture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texImage2D( gl.TEXTURE_2D, 0, gl.R32F, width, height, 0, gl.RED, gl.FLOAT, new Float32Array(pixels).map(v => v / 255)); diff --git a/mediapipe/tasks/web/vision/core/mask.ts b/mediapipe/tasks/web/vision/core/mask.ts index d7cf59e5f..3f37e804f 100644 --- a/mediapipe/tasks/web/vision/core/mask.ts +++ b/mediapipe/tasks/web/vision/core/mask.ts @@ -175,6 +175,7 @@ export class MPMask { destinationContainer = assertNotNull(gl.createTexture(), 'Failed to create texture'); gl.bindTexture(gl.TEXTURE_2D, destinationContainer); + this.configureTextureParams(); gl.texImage2D( gl.TEXTURE_2D, 0, gl.R32F, this.width, this.height, 0, gl.RED, gl.FLOAT, null); @@ -283,6 +284,19 @@ export class MPMask { return webGLTexture; } + /** Sets texture params for the currently bound texture. */ + private configureTextureParams() { + const gl = this.getGL(); + // `gl.NEAREST` ensures that we do not get interpolated values for + // masks. In some cases, the user might want interpolation (e.g. for + // confidence masks), so we might want to make this user-configurable. + // Note that `MPImage` uses `gl.LINEAR`. + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + } + /** * Binds the backing texture to the canvas. If the texture does not yet * exist, creates it first. @@ -299,15 +313,12 @@ export class MPMask { assertNotNull(gl.createTexture(), 'Failed to create texture'); this.containers.push(webGLTexture); this.ownsWebGLTexture = true; - } - gl.bindTexture(gl.TEXTURE_2D, webGLTexture); - // TODO: Ideally, we would only set these once per texture and - // not once every frame. - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.bindTexture(gl.TEXTURE_2D, webGLTexture); + this.configureTextureParams(); + } else { + gl.bindTexture(gl.TEXTURE_2D, webGLTexture); + } return webGLTexture; } From 102cffdf4cc42a5403e0683424c716a89c766bd1 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Mon, 22 May 2023 05:01:36 -0700 Subject: [PATCH 307/753] Add some helpful error messages in case GL texture creation fails. PiperOrigin-RevId: 534029187 --- mediapipe/gpu/BUILD | 1 + mediapipe/gpu/gl_texture_buffer.cc | 6 +++++- mediapipe/gpu/gpu_buffer.h | 7 +++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/mediapipe/gpu/BUILD b/mediapipe/gpu/BUILD index e7c65b7c6..ee32b91e2 100644 --- a/mediapipe/gpu/BUILD +++ b/mediapipe/gpu/BUILD @@ -295,6 +295,7 @@ cc_library( "//mediapipe/framework/formats:image_frame", "//mediapipe/framework/port:logging", "@com_google_absl//absl/functional:bind_front", + "@com_google_absl//absl/log:check", "@com_google_absl//absl/strings", "@com_google_absl//absl/synchronization", ] + select({ diff --git a/mediapipe/gpu/gl_texture_buffer.cc b/mediapipe/gpu/gl_texture_buffer.cc index f1497f741..4e5ce4ee4 100644 --- a/mediapipe/gpu/gl_texture_buffer.cc +++ b/mediapipe/gpu/gl_texture_buffer.cc @@ -47,6 +47,7 @@ std::unique_ptr GlTextureBuffer::Create(int width, int height, auto buf = absl::make_unique(GL_TEXTURE_2D, 0, width, height, format, nullptr); if (!buf->CreateInternal(data, alignment)) { + LOG(WARNING) << "Failed to create a GL texture"; return nullptr; } return buf; @@ -106,7 +107,10 @@ GlTextureBuffer::GlTextureBuffer(GLenum target, GLuint name, int width, bool GlTextureBuffer::CreateInternal(const void* data, int alignment) { auto context = GlContext::GetCurrent(); - if (!context) return false; + if (!context) { + LOG(WARNING) << "Cannot create a GL texture without a valid context"; + return false; + } producer_context_ = context; // Save creation GL context. diff --git a/mediapipe/gpu/gpu_buffer.h b/mediapipe/gpu/gpu_buffer.h index b9a88aa53..93eb1460e 100644 --- a/mediapipe/gpu/gpu_buffer.h +++ b/mediapipe/gpu/gpu_buffer.h @@ -20,6 +20,7 @@ #include #include +#include "absl/log/check.h" #include "absl/synchronization/mutex.h" #include "mediapipe/framework/formats/image_frame.h" #include "mediapipe/gpu/gpu_buffer_format.h" @@ -72,8 +73,10 @@ class GpuBuffer { // are not portable. Applications and calculators should normally obtain // GpuBuffers in a portable way from the framework, e.g. using // GpuBufferMultiPool. - explicit GpuBuffer(std::shared_ptr storage) - : holder_(std::make_shared(std::move(storage))) {} + explicit GpuBuffer(std::shared_ptr storage) { + CHECK(storage) << "Cannot construct GpuBuffer with null storage"; + holder_ = std::make_shared(std::move(storage)); + } #if !MEDIAPIPE_DISABLE_GPU && MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER // This is used to support backward-compatible construction of GpuBuffer from From 51730ec25c785c82fd2e92c48d9721627eb9acb0 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Mon, 22 May 2023 12:57:32 -0700 Subject: [PATCH 308/753] Add iOS support for MPMask PiperOrigin-RevId: 534155657 --- mediapipe/tasks/web/vision/core/BUILD | 5 +- mediapipe/tasks/web/vision/core/mask.ts | 67 ++++++++++++++++---- mediapipe/web/graph_runner/platform_utils.ts | 13 ++++ 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/mediapipe/tasks/web/vision/core/BUILD b/mediapipe/tasks/web/vision/core/BUILD index 325603353..fa28e04a5 100644 --- a/mediapipe/tasks/web/vision/core/BUILD +++ b/mediapipe/tasks/web/vision/core/BUILD @@ -62,7 +62,10 @@ jasmine_node_test( mediapipe_ts_library( name = "mask", srcs = ["mask.ts"], - deps = [":image"], + deps = [ + ":image", + "//mediapipe/web/graph_runner:platform_utils", + ], ) mediapipe_ts_library( diff --git a/mediapipe/tasks/web/vision/core/mask.ts b/mediapipe/tasks/web/vision/core/mask.ts index 3f37e804f..9622b638f 100644 --- a/mediapipe/tasks/web/vision/core/mask.ts +++ b/mediapipe/tasks/web/vision/core/mask.ts @@ -15,6 +15,7 @@ */ import {assertNotNull, MPImageShaderContext} from '../../../../tasks/web/vision/core/image_shader_context'; +import {isIOS} from '../../../../web/graph_runner/platform_utils'; /** Number of instances a user can keep alive before we raise a warning. */ const INSTANCE_COUNT_WARNING_THRESHOLD = 250; @@ -32,6 +33,8 @@ enum MPMaskType { /** The supported mask formats. For internal usage. */ export type MPMaskContainer = Uint8Array|Float32Array|WebGLTexture; + + /** * The wrapper class for MediaPipe segmentation masks. * @@ -56,6 +59,9 @@ export class MPMask { */ private static instancesBeforeWarning = INSTANCE_COUNT_WARNING_THRESHOLD; + /** The format used to write pixel values from textures. */ + private static texImage2DFormat?: GLenum; + /** @hideconstructor */ constructor( private readonly containers: MPMaskContainer[], @@ -127,6 +133,29 @@ export class MPMask { return this.convertToWebGLTexture(); } + /** + * Returns the texture format used for writing float textures on this + * platform. + */ + getTexImage2DFormat(): GLenum { + const gl = this.getGL(); + if (!MPMask.texImage2DFormat) { + // Note: This is the same check we use in + // `SegmentationPostprocessorGl::GetSegmentationResultGpu()`. + if (gl.getExtension('EXT_color_buffer_float') && + gl.getExtension('OES_texture_float_linear') && + gl.getExtension('EXT_float_blend')) { + MPMask.texImage2DFormat = gl.R32F; + } else if (gl.getExtension('EXT_color_buffer_half_float')) { + MPMask.texImage2DFormat = gl.R16F; + } else { + throw new Error( + 'GPU does not fully support 4-channel float32 or float16 formats'); + } + } + return MPMask.texImage2DFormat; + } + private getContainer(type: MPMaskType.UINT8_ARRAY): Uint8Array|undefined; private getContainer(type: MPMaskType.FLOAT32_ARRAY): Float32Array|undefined; private getContainer(type: MPMaskType.WEBGL_TEXTURE): WebGLTexture|undefined; @@ -176,8 +205,9 @@ export class MPMask { assertNotNull(gl.createTexture(), 'Failed to create texture'); gl.bindTexture(gl.TEXTURE_2D, destinationContainer); this.configureTextureParams(); + const format = this.getTexImage2DFormat(); gl.texImage2D( - gl.TEXTURE_2D, 0, gl.R32F, this.width, this.height, 0, gl.RED, + gl.TEXTURE_2D, 0, format, this.width, this.height, 0, gl.RED, gl.FLOAT, null); gl.bindTexture(gl.TEXTURE_2D, null); @@ -208,7 +238,7 @@ export class MPMask { if (!this.canvas) { throw new Error( 'Conversion to different image formats require that a canvas ' + - 'is passed when iniitializing the image.'); + 'is passed when initializing the image.'); } if (!this.gl) { this.gl = assertNotNull( @@ -216,11 +246,6 @@ export class MPMask { 'You cannot use a canvas that is already bound to a different ' + 'type of rendering context.'); } - const ext = this.gl.getExtension('EXT_color_buffer_float'); - if (!ext) { - // TODO: Ensure this works on iOS - throw new Error('Missing required EXT_color_buffer_float extension'); - } return this.gl; } @@ -238,18 +263,34 @@ export class MPMask { if (uint8Array) { float32Array = new Float32Array(uint8Array).map(v => v / 255); } else { + float32Array = new Float32Array(this.width * this.height); + const gl = this.getGL(); const shaderContext = this.getShaderContext(); - float32Array = new Float32Array(this.width * this.height); // Create texture if needed const webGlTexture = this.convertToWebGLTexture(); // Create a framebuffer from the texture and read back pixels shaderContext.bindFramebuffer(gl, webGlTexture); - gl.readPixels( - 0, 0, this.width, this.height, gl.RED, gl.FLOAT, float32Array); - shaderContext.unbindFramebuffer(); + + if (isIOS()) { + // WebKit on iOS only supports gl.HALF_FLOAT for single channel reads + // (as tested on iOS 16.4). HALF_FLOAT requires reading data into a + // Uint16Array, however, and requires a manual bitwise conversion from + // Uint16 to floating point numbers. This conversion is more expensive + // that reading back a Float32Array from the RGBA image and dropping + // the superfluous data, so we do this instead. + const outputArray = new Float32Array(this.width * this.height * 4); + gl.readPixels( + 0, 0, this.width, this.height, gl.RGBA, gl.FLOAT, outputArray); + for (let i = 0, j = 0; i < float32Array.length; ++i, j += 4) { + float32Array[i] = outputArray[j]; + } + } else { + gl.readPixels( + 0, 0, this.width, this.height, gl.RED, gl.FLOAT, float32Array); + } } this.containers.push(float32Array); } @@ -274,9 +315,9 @@ export class MPMask { webGLTexture = this.bindTexture(); const data = this.convertToFloat32Array(); - // TODO: Add support for R16F to support iOS + const format = this.getTexImage2DFormat(); gl.texImage2D( - gl.TEXTURE_2D, 0, gl.R32F, this.width, this.height, 0, gl.RED, + gl.TEXTURE_2D, 0, format, this.width, this.height, 0, gl.RED, gl.FLOAT, data); this.unbindTexture(); } diff --git a/mediapipe/web/graph_runner/platform_utils.ts b/mediapipe/web/graph_runner/platform_utils.ts index 71239abab..7e1decf34 100644 --- a/mediapipe/web/graph_runner/platform_utils.ts +++ b/mediapipe/web/graph_runner/platform_utils.ts @@ -21,3 +21,16 @@ export function isWebKit(browser = navigator) { // it uses "CriOS". return userAgent.includes('Safari') && !userAgent.includes('Chrome'); } + +/** Detect if code is running on iOS. */ +export function isIOS() { + // Source: + // https://stackoverflow.com/questions/9038625/detect-if-device-is-ios + return [ + 'iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', + 'iPod' + // tslint:disable-next-line:deprecation + ].includes(navigator.platform) + // iPad on iOS 13 detection + || (navigator.userAgent.includes('Mac') && 'ontouchend' in document); +} From 87f525c76b1b133c3caa0b033a097bb268c37b06 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Mon, 22 May 2023 19:59:19 -0700 Subject: [PATCH 309/753] Internal change PiperOrigin-RevId: 534264040 --- mediapipe/tasks/ios/BUILD | 4 +- .../object_detector/MPPObjectDetectorTests.m | 127 +++++++++--------- .../tasks/ios/vision/object_detector/BUILD | 12 +- .../sources/MPPObjectDetector.h | 17 ++- .../sources/MPPObjectDetector.mm | 34 ++--- .../sources/MPPObjectDetectorOptions.h | 6 +- ...tionResult.h => MPPObjectDetectorResult.h} | 8 +- ...tionResult.m => MPPObjectDetectorResult.m} | 4 +- .../ios/vision/object_detector/utils/BUILD | 8 +- ...rs.h => MPPObjectDetectorResult+Helpers.h} | 10 +- ....mm => MPPObjectDetectorResult+Helpers.mm} | 14 +- 11 files changed, 121 insertions(+), 123 deletions(-) rename mediapipe/tasks/ios/vision/object_detector/sources/{MPPObjectDetectionResult.h => MPPObjectDetectorResult.h} (86%) rename mediapipe/tasks/ios/vision/object_detector/sources/{MPPObjectDetectionResult.m => MPPObjectDetectorResult.m} (93%) rename mediapipe/tasks/ios/vision/object_detector/utils/sources/{MPPObjectDetectionResult+Helpers.h => MPPObjectDetectorResult+Helpers.h} (75%) rename mediapipe/tasks/ios/vision/object_detector/utils/sources/{MPPObjectDetectionResult+Helpers.mm => MPPObjectDetectorResult+Helpers.mm} (75%) diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index fb3d57ddd..d9be847f0 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -81,7 +81,7 @@ strip_api_include_path_prefix( "//mediapipe/tasks/ios/vision/image_classifier:sources/MPPImageClassifierResult.h", "//mediapipe/tasks/ios/vision/object_detector:sources/MPPObjectDetector.h", "//mediapipe/tasks/ios/vision/object_detector:sources/MPPObjectDetectorOptions.h", - "//mediapipe/tasks/ios/vision/object_detector:sources/MPPObjectDetectionResult.h", + "//mediapipe/tasks/ios/vision/object_detector:sources/MPPObjectDetectorResult.h", ], ) @@ -162,7 +162,7 @@ apple_static_xcframework( ":MPPImageClassifierResult.h", ":MPPObjectDetector.h", ":MPPObjectDetectorOptions.h", - ":MPPObjectDetectionResult.h", + ":MPPObjectDetectorResult.h", ], deps = [ "//mediapipe/tasks/ios/vision/image_classifier:MPPImageClassifier", diff --git a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m index 700df65a5..164159ed6 100644 --- a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m +++ b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m @@ -70,7 +70,7 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; #pragma mark Results -+ (MPPObjectDetectionResult *)expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: ++ (MPPObjectDetectorResult *)expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: (NSInteger)timestampInMilliseconds { NSArray *detections = @[ [[MPPDetection alloc] initWithCategories:@[ @@ -95,8 +95,8 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; keypoints:nil], ]; - return [[MPPObjectDetectionResult alloc] initWithDetections:detections - timestampInMilliseconds:timestampInMilliseconds]; + return [[MPPObjectDetectorResult alloc] initWithDetections:detections + timestampInMilliseconds:timestampInMilliseconds]; } - (void)assertDetections:(NSArray *)detections @@ -112,25 +112,25 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; } } -- (void)assertObjectDetectionResult:(MPPObjectDetectionResult *)objectDetectionResult - isEqualToExpectedResult:(MPPObjectDetectionResult *)expectedObjectDetectionResult - expectedDetectionsCount:(NSInteger)expectedDetectionsCount { - XCTAssertNotNil(objectDetectionResult); +- (void)assertObjectDetectorResult:(MPPObjectDetectorResult *)objectDetectorResult + isEqualToExpectedResult:(MPPObjectDetectorResult *)expectedObjectDetectorResult + expectedDetectionsCount:(NSInteger)expectedDetectionsCount { + XCTAssertNotNil(objectDetectorResult); NSArray *detectionsSubsetToCompare; - XCTAssertEqual(objectDetectionResult.detections.count, expectedDetectionsCount); - if (objectDetectionResult.detections.count > expectedObjectDetectionResult.detections.count) { - detectionsSubsetToCompare = [objectDetectionResult.detections - subarrayWithRange:NSMakeRange(0, expectedObjectDetectionResult.detections.count)]; + XCTAssertEqual(objectDetectorResult.detections.count, expectedDetectionsCount); + if (objectDetectorResult.detections.count > expectedObjectDetectorResult.detections.count) { + detectionsSubsetToCompare = [objectDetectorResult.detections + subarrayWithRange:NSMakeRange(0, expectedObjectDetectorResult.detections.count)]; } else { - detectionsSubsetToCompare = objectDetectionResult.detections; + detectionsSubsetToCompare = objectDetectorResult.detections; } [self assertDetections:detectionsSubsetToCompare - isEqualToExpectedDetections:expectedObjectDetectionResult.detections]; + isEqualToExpectedDetections:expectedObjectDetectorResult.detections]; - XCTAssertEqual(objectDetectionResult.timestampInMilliseconds, - expectedObjectDetectionResult.timestampInMilliseconds); + XCTAssertEqual(objectDetectorResult.timestampInMilliseconds, + expectedObjectDetectorResult.timestampInMilliseconds); } #pragma mark File @@ -195,28 +195,27 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; - (void)assertResultsOfDetectInImage:(MPPImage *)mppImage usingObjectDetector:(MPPObjectDetector *)objectDetector maxResults:(NSInteger)maxResults - equalsObjectDetectionResult:(MPPObjectDetectionResult *)expectedObjectDetectionResult { - MPPObjectDetectionResult *objectDetectionResult = [objectDetector detectInImage:mppImage - error:nil]; + equalsObjectDetectorResult:(MPPObjectDetectorResult *)expectedObjectDetectorResult { + MPPObjectDetectorResult *ObjectDetectorResult = [objectDetector detectInImage:mppImage error:nil]; - [self assertObjectDetectionResult:objectDetectionResult - isEqualToExpectedResult:expectedObjectDetectionResult - expectedDetectionsCount:maxResults > 0 ? maxResults - : objectDetectionResult.detections.count]; + [self assertObjectDetectorResult:ObjectDetectorResult + isEqualToExpectedResult:expectedObjectDetectorResult + expectedDetectionsCount:maxResults > 0 ? maxResults + : ObjectDetectorResult.detections.count]; } - (void)assertResultsOfDetectInImageWithFileInfo:(NSDictionary *)fileInfo usingObjectDetector:(MPPObjectDetector *)objectDetector maxResults:(NSInteger)maxResults - equalsObjectDetectionResult: - (MPPObjectDetectionResult *)expectedObjectDetectionResult { + equalsObjectDetectorResult: + (MPPObjectDetectorResult *)expectedObjectDetectorResult { MPPImage *mppImage = [self imageWithFileInfo:fileInfo]; [self assertResultsOfDetectInImage:mppImage usingObjectDetector:objectDetector maxResults:maxResults - equalsObjectDetectionResult:expectedObjectDetectionResult]; + equalsObjectDetectorResult:expectedObjectDetectorResult]; } #pragma mark General Tests @@ -266,10 +265,10 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; [self assertResultsOfDetectInImageWithFileInfo:kCatsAndDogsImage usingObjectDetector:objectDetector maxResults:-1 - equalsObjectDetectionResult: - [MPPObjectDetectorTests - expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: - 0]]; + equalsObjectDetectorResult: + [MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: + 0]]; } - (void)testDetectWithOptionsSucceeds { @@ -280,10 +279,10 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; [self assertResultsOfDetectInImageWithFileInfo:kCatsAndDogsImage usingObjectDetector:objectDetector maxResults:-1 - equalsObjectDetectionResult: - [MPPObjectDetectorTests - expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: - 0]]; + equalsObjectDetectorResult: + [MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: + 0]]; } - (void)testDetectWithMaxResultsSucceeds { @@ -297,10 +296,10 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; [self assertResultsOfDetectInImageWithFileInfo:kCatsAndDogsImage usingObjectDetector:objectDetector maxResults:maxResults - equalsObjectDetectionResult: - [MPPObjectDetectorTests - expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: - 0]]; + equalsObjectDetectorResult: + [MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: + 0]]; } - (void)testDetectWithScoreThresholdSucceeds { @@ -316,13 +315,13 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; boundingBox:CGRectMake(608, 161, 381, 439) keypoints:nil], ]; - MPPObjectDetectionResult *expectedObjectDetectionResult = - [[MPPObjectDetectionResult alloc] initWithDetections:detections timestampInMilliseconds:0]; + MPPObjectDetectorResult *expectedObjectDetectorResult = + [[MPPObjectDetectorResult alloc] initWithDetections:detections timestampInMilliseconds:0]; [self assertResultsOfDetectInImageWithFileInfo:kCatsAndDogsImage usingObjectDetector:objectDetector maxResults:-1 - equalsObjectDetectionResult:expectedObjectDetectionResult]; + equalsObjectDetectorResult:expectedObjectDetectorResult]; } - (void)testDetectWithCategoryAllowlistSucceeds { @@ -359,13 +358,13 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; keypoints:nil], ]; - MPPObjectDetectionResult *expectedDetectionResult = - [[MPPObjectDetectionResult alloc] initWithDetections:detections timestampInMilliseconds:0]; + MPPObjectDetectorResult *expectedDetectionResult = + [[MPPObjectDetectorResult alloc] initWithDetections:detections timestampInMilliseconds:0]; [self assertResultsOfDetectInImageWithFileInfo:kCatsAndDogsImage usingObjectDetector:objectDetector maxResults:-1 - equalsObjectDetectionResult:expectedDetectionResult]; + equalsObjectDetectorResult:expectedDetectionResult]; } - (void)testDetectWithCategoryDenylistSucceeds { @@ -414,13 +413,13 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; keypoints:nil], ]; - MPPObjectDetectionResult *expectedDetectionResult = - [[MPPObjectDetectionResult alloc] initWithDetections:detections timestampInMilliseconds:0]; + MPPObjectDetectorResult *expectedDetectionResult = + [[MPPObjectDetectorResult alloc] initWithDetections:detections timestampInMilliseconds:0]; [self assertResultsOfDetectInImageWithFileInfo:kCatsAndDogsImage usingObjectDetector:objectDetector maxResults:-1 - equalsObjectDetectionResult:expectedDetectionResult]; + equalsObjectDetectorResult:expectedDetectionResult]; } - (void)testDetectWithOrientationSucceeds { @@ -437,8 +436,8 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; keypoints:nil], ]; - MPPObjectDetectionResult *expectedDetectionResult = - [[MPPObjectDetectionResult alloc] initWithDetections:detections timestampInMilliseconds:0]; + MPPObjectDetectorResult *expectedDetectionResult = + [[MPPObjectDetectorResult alloc] initWithDetections:detections timestampInMilliseconds:0]; MPPImage *image = [self imageWithFileInfo:kCatsAndDogsRotatedImage orientation:UIImageOrientationRight]; @@ -446,7 +445,7 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; [self assertResultsOfDetectInImage:image usingObjectDetector:objectDetector maxResults:1 - equalsObjectDetectionResult:expectedDetectionResult]; + equalsObjectDetectorResult:expectedDetectionResult]; } #pragma mark Running Mode Tests @@ -613,15 +612,15 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; MPPImage *image = [self imageWithFileInfo:kCatsAndDogsImage]; for (int i = 0; i < 3; i++) { - MPPObjectDetectionResult *objectDetectionResult = [objectDetector detectInVideoFrame:image - timestampInMilliseconds:i - error:nil]; + MPPObjectDetectorResult *ObjectDetectorResult = [objectDetector detectInVideoFrame:image + timestampInMilliseconds:i + error:nil]; - [self assertObjectDetectionResult:objectDetectionResult - isEqualToExpectedResult: - [MPPObjectDetectorTests - expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds:i] - expectedDetectionsCount:maxResults]; + [self assertObjectDetectorResult:ObjectDetectorResult + isEqualToExpectedResult: + [MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds:i] + expectedDetectionsCount:maxResults]; } } @@ -714,16 +713,16 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; #pragma mark MPPObjectDetectorLiveStreamDelegate Methods - (void)objectDetector:(MPPObjectDetector *)objectDetector - didFinishDetectionWithResult:(MPPObjectDetectionResult *)objectDetectionResult + didFinishDetectionWithResult:(MPPObjectDetectorResult *)ObjectDetectorResult timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(NSError *)error { NSInteger maxResults = 4; - [self assertObjectDetectionResult:objectDetectionResult - isEqualToExpectedResult: - [MPPObjectDetectorTests - expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: - timestampInMilliseconds] - expectedDetectionsCount:maxResults]; + [self assertObjectDetectorResult:ObjectDetectorResult + isEqualToExpectedResult: + [MPPObjectDetectorTests + expectedDetectionResultForCatsAndDogsImageWithTimestampInMilliseconds: + timestampInMilliseconds] + expectedDetectionsCount:maxResults]; if (objectDetector == outOfOrderTimestampTestDict[kLiveStreamTestsDictObjectDetectorKey]) { [outOfOrderTimestampTestDict[kLiveStreamTestsDictExpectationKey] fulfill]; diff --git a/mediapipe/tasks/ios/vision/object_detector/BUILD b/mediapipe/tasks/ios/vision/object_detector/BUILD index 81c97c894..002a59920 100644 --- a/mediapipe/tasks/ios/vision/object_detector/BUILD +++ b/mediapipe/tasks/ios/vision/object_detector/BUILD @@ -17,9 +17,9 @@ package(default_visibility = ["//mediapipe/tasks:internal"]) licenses(["notice"]) objc_library( - name = "MPPObjectDetectionResult", - srcs = ["sources/MPPObjectDetectionResult.m"], - hdrs = ["sources/MPPObjectDetectionResult.h"], + name = "MPPObjectDetectorResult", + srcs = ["sources/MPPObjectDetectorResult.m"], + hdrs = ["sources/MPPObjectDetectorResult.h"], deps = [ "//mediapipe/tasks/ios/components/containers:MPPDetection", "//mediapipe/tasks/ios/core:MPPTaskResult", @@ -31,7 +31,7 @@ objc_library( srcs = ["sources/MPPObjectDetectorOptions.m"], hdrs = ["sources/MPPObjectDetectorOptions.h"], deps = [ - ":MPPObjectDetectionResult", + ":MPPObjectDetectorResult", "//mediapipe/tasks/ios/core:MPPTaskOptions", "//mediapipe/tasks/ios/vision/core:MPPRunningMode", ], @@ -47,8 +47,8 @@ objc_library( "-x objective-c++", ], deps = [ - ":MPPObjectDetectionResult", ":MPPObjectDetectorOptions", + ":MPPObjectDetectorResult", "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", "//mediapipe/tasks/ios/common/utils:NSStringHelpers", @@ -56,7 +56,7 @@ objc_library( "//mediapipe/tasks/ios/vision/core:MPPImage", "//mediapipe/tasks/ios/vision/core:MPPVisionPacketCreator", "//mediapipe/tasks/ios/vision/core:MPPVisionTaskRunner", - "//mediapipe/tasks/ios/vision/object_detector/utils:MPPObjectDetectionResultHelpers", "//mediapipe/tasks/ios/vision/object_detector/utils:MPPObjectDetectorOptionsHelpers", + "//mediapipe/tasks/ios/vision/object_detector/utils:MPPObjectDetectorResultHelpers", ], ) diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h index ae18bf58d..d3f946bbe 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h @@ -15,8 +15,8 @@ #import #import "mediapipe/tasks/ios/vision/core/sources/MPPImage.h" -#import "mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectionResult.h" #import "mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h" +#import "mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorResult.h" NS_ASSUME_NONNULL_BEGIN @@ -109,14 +109,13 @@ NS_SWIFT_NAME(ObjectDetector) * @param error An optional error parameter populated when there is an error in performing object * detection on the input image. * - * @return An `MPPObjectDetectionResult` object that contains a list of detections, each detection + * @return An `MPPObjectDetectorResult` object that contains a list of detections, each detection * has a bounding box that is expressed in the unrotated input frame of reference coordinates * system, i.e. in `[0,image_width) x [0,image_height)`, which are the dimensions of the underlying * image data. */ -- (nullable MPPObjectDetectionResult *)detectInImage:(MPPImage *)image - error:(NSError **)error - NS_SWIFT_NAME(detect(image:)); +- (nullable MPPObjectDetectorResult *)detectInImage:(MPPImage *)image + error:(NSError **)error NS_SWIFT_NAME(detect(image:)); /** * Performs object detection on the provided video frame of type `MPPImage` using the whole @@ -139,14 +138,14 @@ NS_SWIFT_NAME(ObjectDetector) * @param error An optional error parameter populated when there is an error in performing object * detection on the input image. * - * @return An `MPPObjectDetectionResult` object that contains a list of detections, each detection + * @return An `MPPObjectDetectorResult` object that contains a list of detections, each detection * has a bounding box that is expressed in the unrotated input frame of reference coordinates * system, i.e. in `[0,image_width) x [0,image_height)`, which are the dimensions of the underlying * image data. */ -- (nullable MPPObjectDetectionResult *)detectInVideoFrame:(MPPImage *)image - timestampInMilliseconds:(NSInteger)timestampInMilliseconds - error:(NSError **)error +- (nullable MPPObjectDetectorResult *)detectInVideoFrame:(MPPImage *)image + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(NSError **)error NS_SWIFT_NAME(detect(videoFrame:timestampInMilliseconds:)); /** diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm index a5b4077be..27b196d7f 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.mm @@ -19,8 +19,8 @@ #import "mediapipe/tasks/ios/core/sources/MPPTaskInfo.h" #import "mediapipe/tasks/ios/vision/core/sources/MPPVisionPacketCreator.h" #import "mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h" -#import "mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectionResult+Helpers.h" #import "mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorOptions+Helpers.h" +#import "mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorResult+Helpers.h" namespace { using ::mediapipe::NormalizedRect; @@ -118,9 +118,9 @@ static NSString *const kTaskName = @"objectDetector"; return; } - MPPObjectDetectionResult *result = [MPPObjectDetectionResult - objectDetectionResultWithDetectionsPacket:statusOrPackets.value()[kDetectionsStreamName - .cppString]]; + MPPObjectDetectorResult *result = [MPPObjectDetectorResult + objectDetectorResultWithDetectionsPacket:statusOrPackets + .value()[kDetectionsStreamName.cppString]]; NSInteger timeStampInMilliseconds = outputPacketMap[kImageOutStreamName.cppString].Timestamp().Value() / @@ -184,9 +184,9 @@ static NSString *const kTaskName = @"objectDetector"; return inputPacketMap; } -- (nullable MPPObjectDetectionResult *)detectInImage:(MPPImage *)image - regionOfInterest:(CGRect)roi - error:(NSError **)error { +- (nullable MPPObjectDetectorResult *)detectInImage:(MPPImage *)image + regionOfInterest:(CGRect)roi + error:(NSError **)error { std::optional rect = [_visionTaskRunner normalizedRectFromRegionOfInterest:roi imageSize:CGSizeMake(image.width, image.height) @@ -213,18 +213,18 @@ static NSString *const kTaskName = @"objectDetector"; return nil; } - return [MPPObjectDetectionResult - objectDetectionResultWithDetectionsPacket:outputPacketMap - .value()[kDetectionsStreamName.cppString]]; + return [MPPObjectDetectorResult + objectDetectorResultWithDetectionsPacket:outputPacketMap + .value()[kDetectionsStreamName.cppString]]; } -- (nullable MPPObjectDetectionResult *)detectInImage:(MPPImage *)image error:(NSError **)error { +- (nullable MPPObjectDetectorResult *)detectInImage:(MPPImage *)image error:(NSError **)error { return [self detectInImage:image regionOfInterest:CGRectZero error:error]; } -- (nullable MPPObjectDetectionResult *)detectInVideoFrame:(MPPImage *)image - timestampInMilliseconds:(NSInteger)timestampInMilliseconds - error:(NSError **)error { +- (nullable MPPObjectDetectorResult *)detectInVideoFrame:(MPPImage *)image + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(NSError **)error { std::optional inputPacketMap = [self inputPacketMapWithMPPImage:image timestampInMilliseconds:timestampInMilliseconds error:error]; @@ -239,9 +239,9 @@ static NSString *const kTaskName = @"objectDetector"; return nil; } - return [MPPObjectDetectionResult - objectDetectionResultWithDetectionsPacket:outputPacketMap - .value()[kDetectionsStreamName.cppString]]; + return [MPPObjectDetectorResult + objectDetectorResultWithDetectionsPacket:outputPacketMap + .value()[kDetectionsStreamName.cppString]]; } - (BOOL)detectAsyncInImage:(MPPImage *)image diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h index 182714c03..33d7bdbbb 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorOptions.h @@ -16,7 +16,7 @@ #import "mediapipe/tasks/ios/core/sources/MPPTaskOptions.h" #import "mediapipe/tasks/ios/vision/core/sources/MPPRunningMode.h" -#import "mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectionResult.h" +#import "mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorResult.h" NS_ASSUME_NONNULL_BEGIN @@ -44,7 +44,7 @@ NS_SWIFT_NAME(ObjectDetectorLiveStreamDelegate) * * @param objectDetector The object detector which performed the object detection. * This is useful to test equality when there are multiple instances of `MPPObjectDetector`. - * @param result The `MPPObjectDetectionResult` object that contains a list of detections, each + * @param result The `MPPObjectDetectorResult` object that contains a list of detections, each * detection has a bounding box that is expressed in the unrotated input frame of reference * coordinates system, i.e. in `[0,image_width) x [0,image_height)`, which are the dimensions of the * underlying image data. @@ -54,7 +54,7 @@ NS_SWIFT_NAME(ObjectDetectorLiveStreamDelegate) * detection on the input live stream image data. */ - (void)objectDetector:(MPPObjectDetector *)objectDetector - didFinishDetectionWithResult:(nullable MPPObjectDetectionResult *)result + didFinishDetectionWithResult:(nullable MPPObjectDetectorResult *)result timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(nullable NSError *)error NS_SWIFT_NAME(objectDetector(_:didFinishDetection:timestampInMilliseconds:error:)); diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectionResult.h b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorResult.h similarity index 86% rename from mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectionResult.h rename to mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorResult.h index da9899d40..2641b6b4e 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectionResult.h +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorResult.h @@ -19,8 +19,8 @@ NS_ASSUME_NONNULL_BEGIN /** Represents the detection results generated by `MPPObjectDetector`. */ -NS_SWIFT_NAME(ObjectDetectionResult) -@interface MPPObjectDetectionResult : MPPTaskResult +NS_SWIFT_NAME(ObjectDetectorResult) +@interface MPPObjectDetectorResult : MPPTaskResult /** * The array of `MPPDetection` objects each of which has a bounding box that is expressed in the @@ -30,7 +30,7 @@ NS_SWIFT_NAME(ObjectDetectionResult) @property(nonatomic, readonly) NSArray *detections; /** - * Initializes a new `MPPObjectDetectionResult` with the given array of detections and timestamp (in + * Initializes a new `MPPObjectDetectorResult` with the given array of detections and timestamp (in * milliseconds). * * @param detections An array of `MPPDetection` objects each of which has a bounding box that is @@ -38,7 +38,7 @@ NS_SWIFT_NAME(ObjectDetectionResult) * x [0,image_height)`, which are the dimensions of the underlying image data. * @param timestampInMilliseconds The timestamp (in milliseconds) for this result. * - * @return An instance of `MPPObjectDetectionResult` initialized with the given array of detections + * @return An instance of `MPPObjectDetectorResult` initialized with the given array of detections * and timestamp (in milliseconds). */ - (instancetype)initWithDetections:(NSArray *)detections diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectionResult.m b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorResult.m similarity index 93% rename from mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectionResult.m rename to mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorResult.m index 47902bba4..568fbcff7 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectionResult.m +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorResult.m @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectionResult.h" +#import "mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorResult.h" -@implementation MPPObjectDetectionResult +@implementation MPPObjectDetectorResult - (instancetype)initWithDetections:(NSArray *)detections timestampInMilliseconds:(NSInteger)timestampInMilliseconds { diff --git a/mediapipe/tasks/ios/vision/object_detector/utils/BUILD b/mediapipe/tasks/ios/vision/object_detector/utils/BUILD index d4597b239..63ddbd0b8 100644 --- a/mediapipe/tasks/ios/vision/object_detector/utils/BUILD +++ b/mediapipe/tasks/ios/vision/object_detector/utils/BUILD @@ -31,12 +31,12 @@ objc_library( ) objc_library( - name = "MPPObjectDetectionResultHelpers", - srcs = ["sources/MPPObjectDetectionResult+Helpers.mm"], - hdrs = ["sources/MPPObjectDetectionResult+Helpers.h"], + name = "MPPObjectDetectorResultHelpers", + srcs = ["sources/MPPObjectDetectorResult+Helpers.mm"], + hdrs = ["sources/MPPObjectDetectorResult+Helpers.h"], deps = [ "//mediapipe/framework:packet", "//mediapipe/tasks/ios/components/containers/utils:MPPDetectionHelpers", - "//mediapipe/tasks/ios/vision/object_detector:MPPObjectDetectionResult", + "//mediapipe/tasks/ios/vision/object_detector:MPPObjectDetectorResult", ], ) diff --git a/mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectionResult+Helpers.h b/mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorResult+Helpers.h similarity index 75% rename from mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectionResult+Helpers.h rename to mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorResult+Helpers.h index 645f5c565..377e6e323 100644 --- a/mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectionResult+Helpers.h +++ b/mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorResult+Helpers.h @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectionResult.h" +#import "mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetectorResult.h" #include "mediapipe/framework/packet.h" @@ -20,17 +20,17 @@ NS_ASSUME_NONNULL_BEGIN static const int kMicroSecondsPerMilliSecond = 1000; -@interface MPPObjectDetectionResult (Helpers) +@interface MPPObjectDetectorResult (Helpers) /** - * Creates an `MPPObjectDetectionResult` from a MediaPipe packet containing a + * Creates an `MPPObjectDetectorResult` from a MediaPipe packet containing a * `std::vector`. * * @param packet a MediaPipe packet wrapping a `std::vector`. * - * @return An `MPPObjectDetectionResult` object that contains a list of detections. + * @return An `MPPObjectDetectorResult` object that contains a list of detections. */ -+ (nullable MPPObjectDetectionResult *)objectDetectionResultWithDetectionsPacket: ++ (nullable MPPObjectDetectorResult *)objectDetectorResultWithDetectionsPacket: (const mediapipe::Packet &)packet; @end diff --git a/mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectionResult+Helpers.mm b/mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorResult+Helpers.mm similarity index 75% rename from mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectionResult+Helpers.mm rename to mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorResult+Helpers.mm index 225a6993d..b2f9cfc08 100644 --- a/mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectionResult+Helpers.mm +++ b/mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorResult+Helpers.mm @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import "mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectionResult+Helpers.h" +#import "mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorResult+Helpers.h" #import "mediapipe/tasks/ios/components/containers/utils/sources/MPPDetection+Helpers.h" @@ -21,9 +21,9 @@ using DetectionProto = ::mediapipe::Detection; using ::mediapipe::Packet; } // namespace -@implementation MPPObjectDetectionResult (Helpers) +@implementation MPPObjectDetectorResult (Helpers) -+ (nullable MPPObjectDetectionResult *)objectDetectionResultWithDetectionsPacket: ++ (nullable MPPObjectDetectorResult *)objectDetectorResultWithDetectionsPacket: (const Packet &)packet { if (!packet.ValidateAsType>().ok()) { return nil; @@ -37,10 +37,10 @@ using ::mediapipe::Packet; [detections addObject:[MPPDetection detectionWithProto:detectionProto]]; } - return [[MPPObjectDetectionResult alloc] - initWithDetections:detections - timestampInMilliseconds:(NSInteger)(packet.Timestamp().Value() / - kMicroSecondsPerMilliSecond)]; + return + [[MPPObjectDetectorResult alloc] initWithDetections:detections + timestampInMilliseconds:(NSInteger)(packet.Timestamp().Value() / + kMicroSecondsPerMilliSecond)]; } @end From fda001b666c8f46aa5072a8d42ecdcee77fec1a7 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 23 May 2023 19:31:14 +0530 Subject: [PATCH 310/753] Updated error tests to use XCTAssertEqualObjects --- .../ios/test/text/text_classifier/MPPTextClassifierTests.m | 4 +--- .../ios/test/text/text_embedder/MPPTextEmbedderTests.m | 4 +--- .../test/vision/image_classifier/MPPImageClassifierTests.m | 6 ++---- .../test/vision/object_detector/MPPObjectDetectorTests.m | 4 +--- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/mediapipe/tasks/ios/test/text/text_classifier/MPPTextClassifierTests.m b/mediapipe/tasks/ios/test/text/text_classifier/MPPTextClassifierTests.m index a80fb8824..2ffccd2b7 100644 --- a/mediapipe/tasks/ios/test/text/text_classifier/MPPTextClassifierTests.m +++ b/mediapipe/tasks/ios/test/text/text_classifier/MPPTextClassifierTests.m @@ -28,9 +28,7 @@ static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; XCTAssertNotNil(error); \ XCTAssertEqualObjects(error.domain, expectedError.domain); \ XCTAssertEqual(error.code, expectedError.code); \ - XCTAssertNotEqual( \ - [error.localizedDescription rangeOfString:expectedError.localizedDescription].location, \ - NSNotFound) + XCTAssertEqualObjects(error.localizedDescription, expectedError.localizedDescription) #define AssertEqualCategoryArrays(categories, expectedCategories) \ XCTAssertEqual(categories.count, expectedCategories.count); \ diff --git a/mediapipe/tasks/ios/test/text/text_embedder/MPPTextEmbedderTests.m b/mediapipe/tasks/ios/test/text/text_embedder/MPPTextEmbedderTests.m index b32bb076c..51d37667c 100644 --- a/mediapipe/tasks/ios/test/text/text_embedder/MPPTextEmbedderTests.m +++ b/mediapipe/tasks/ios/test/text/text_embedder/MPPTextEmbedderTests.m @@ -29,9 +29,7 @@ static const float kSimilarityDiffTolerance = 1e-4; XCTAssertNotNil(error); \ XCTAssertEqualObjects(error.domain, expectedError.domain); \ XCTAssertEqual(error.code, expectedError.code); \ - XCTAssertNotEqual( \ - [error.localizedDescription rangeOfString:expectedError.localizedDescription].location, \ - NSNotFound) + XCTAssertEqualObjects(error.localizedDescription, expectedError.localizedDescription) \ #define AssertTextEmbedderResultHasOneEmbedding(textEmbedderResult) \ XCTAssertNotNil(textEmbedderResult); \ diff --git a/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m b/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m index 8db71a11b..62cfb1f84 100644 --- a/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m +++ b/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m @@ -34,10 +34,8 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; XCTAssertNotNil(error); \ XCTAssertEqualObjects(error.domain, expectedError.domain); \ XCTAssertEqual(error.code, expectedError.code); \ - XCTAssertNotEqual( \ - [error.localizedDescription rangeOfString:expectedError.localizedDescription].location, \ - NSNotFound) - + XCTAssertEqualObjects(error.localizedDescription, expectedError.localizedDescription) \ + #define AssertEqualCategoryArrays(categories, expectedCategories) \ XCTAssertEqual(categories.count, expectedCategories.count); \ for (int i = 0; i < categories.count; i++) { \ diff --git a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m index 164159ed6..c438a789a 100644 --- a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m +++ b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m @@ -32,9 +32,7 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; XCTAssertNotNil(error); \ XCTAssertEqualObjects(error.domain, expectedError.domain); \ XCTAssertEqual(error.code, expectedError.code); \ - XCTAssertNotEqual( \ - [error.localizedDescription rangeOfString:expectedError.localizedDescription].location, \ - NSNotFound) + XCTAssertEqualObjects(error.localizedDescription, expectedError.localizedDescription) #define AssertEqualCategories(category, expectedCategory, detectionIndex, categoryIndex) \ XCTAssertEqual(category.index, expectedCategory.index, \ From 3eb97ae1ff13660ef4a1110378075f3b7268b26b Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Tue, 23 May 2023 20:54:42 +0530 Subject: [PATCH 311/753] Updated Image classifier result to return empty results if packet can't be validated. --- .../sources/MPPImageClassifierResult+Helpers.mm | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/ios/vision/image_classifier/utils/sources/MPPImageClassifierResult+Helpers.mm b/mediapipe/tasks/ios/vision/image_classifier/utils/sources/MPPImageClassifierResult+Helpers.mm index 61ae785d1..e9f74a0cd 100644 --- a/mediapipe/tasks/ios/vision/image_classifier/utils/sources/MPPImageClassifierResult+Helpers.mm +++ b/mediapipe/tasks/ios/vision/image_classifier/utils/sources/MPPImageClassifierResult+Helpers.mm @@ -29,13 +29,20 @@ using ::mediapipe::Packet; + (nullable MPPImageClassifierResult *)imageClassifierResultWithClassificationsPacket: (const Packet &)packet { - MPPClassificationResult *classificationResult; + // Even if packet does not validate a the expected type, you can safely access the timestamp. + NSInteger timestampInMilliSeconds = + (NSInteger)(packet.Timestamp().Value() / kMicroSecondsPerMilliSecond); if (!packet.ValidateAsType().ok()) { - return nil; + // MPPClassificationResult's timestamp is populated from timestamp `ClassificationResultProto`'s + // timestamp_ms(). It is 0 since the packet can't be validated as a `ClassificationResultProto`. + return [[MPPImageClassifierResult alloc] + initWithClassificationResult:[[MPPClassificationResult alloc] initWithClassifications:@[] + timestampInMilliseconds:0] + timestampInMilliseconds:timestampInMilliSeconds]; } - classificationResult = [MPPClassificationResult + MPPClassificationResult *classificationResult = [MPPClassificationResult classificationResultWithProto:packet.Get()]; return [[MPPImageClassifierResult alloc] From 1fe78180c86ef400c2f9b1af70ccb63a0175cee2 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Tue, 23 May 2023 11:33:56 -0700 Subject: [PATCH 312/753] Add quality scores to Segmenter tasks PiperOrigin-RevId: 534497957 --- .../image_segmenter/image_segmenter_result.h | 2 +- .../imagesegmenter/ImageSegmenterResult.java | 4 ++-- .../vision/image_segmenter/image_segmenter.ts | 21 +++++++++++++++++-- .../image_segmenter/image_segmenter_result.ts | 8 ++++++- .../image_segmenter/image_segmenter_test.ts | 16 +++++++++++++- .../interactive_segmenter.ts | 19 ++++++++++++++++- .../interactive_segmenter_result.ts | 8 ++++++- .../interactive_segmenter_test.ts | 18 ++++++++++++++-- 8 files changed, 85 insertions(+), 11 deletions(-) diff --git a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_result.h b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_result.h index a203718f4..7f159cc39 100644 --- a/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_result.h +++ b/mediapipe/tasks/cc/vision/image_segmenter/image_segmenter_result.h @@ -33,7 +33,7 @@ struct ImageSegmenterResult { // A category mask of uint8 image in GRAY8 format where each pixel represents // the class which the pixel in the original image was predicted to belong to. std::optional category_mask; - // The quality scores of the result masks, in the range of [0, 1]. Default to + // The quality scores of the result masks, in the range of [0, 1]. Defaults to // `1` if the model doesn't output quality scores. Each element corresponds to // the score of the category in the model outputs. std::vector quality_scores; diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterResult.java index e4ac85c2f..7f567c1a4 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/imagesegmenter/ImageSegmenterResult.java @@ -34,8 +34,8 @@ public abstract class ImageSegmenterResult implements TaskResult { * @param categoryMask an {@link Optional} MPImage in IMAGE_FORMAT_ALPHA format representing a * category mask, where each pixel represents the class which the pixel in the original image * was predicted to belong to. - * @param qualityScores The quality scores of the result masks, in the range of [0, 1]. Default to - * `1` if the model doesn't output quality scores. Each element corresponds to the score of + * @param qualityScores The quality scores of the result masks, in the range of [0, 1]. Defaults + * to `1` if the model doesn't output quality scores. Each element corresponds to the score of * the category in the model outputs. * @param timestampMs a timestamp for this result. */ diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts index ee9caaa1f..3dd2d03ef 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts @@ -39,6 +39,7 @@ const IMAGE_STREAM = 'image_in'; const NORM_RECT_STREAM = 'norm_rect'; const CONFIDENCE_MASKS_STREAM = 'confidence_masks'; const CATEGORY_MASK_STREAM = 'category_mask'; +const QUALITY_SCORES_STREAM = 'quality_scores'; const IMAGE_SEGMENTER_GRAPH = 'mediapipe.tasks.vision.image_segmenter.ImageSegmenterGraph'; const TENSORS_TO_SEGMENTATION_CALCULATOR_NAME = @@ -61,6 +62,7 @@ export type ImageSegmenterCallback = (result: ImageSegmenterResult) => void; export class ImageSegmenter extends VisionTaskRunner { private categoryMask?: MPMask; private confidenceMasks?: MPMask[]; + private qualityScores?: number[]; private labels: string[] = []; private userCallback?: ImageSegmenterCallback; private outputCategoryMask = DEFAULT_OUTPUT_CATEGORY_MASK; @@ -367,12 +369,13 @@ export class ImageSegmenter extends VisionTaskRunner { private reset(): void { this.categoryMask = undefined; this.confidenceMasks = undefined; + this.qualityScores = undefined; } private processResults(): ImageSegmenterResult|void { try { - const result = - new ImageSegmenterResult(this.confidenceMasks, this.categoryMask); + const result = new ImageSegmenterResult( + this.confidenceMasks, this.categoryMask, this.qualityScores); if (this.userCallback) { this.userCallback(result); } else { @@ -442,6 +445,20 @@ export class ImageSegmenter extends VisionTaskRunner { }); } + graphConfig.addOutputStream(QUALITY_SCORES_STREAM); + segmenterNode.addOutputStream('QUALITY_SCORES:' + QUALITY_SCORES_STREAM); + + this.graphRunner.attachFloatVectorListener( + QUALITY_SCORES_STREAM, (scores, timestamp) => { + this.qualityScores = scores; + this.setLatestOutputTimestamp(timestamp); + }); + this.graphRunner.attachEmptyPacketListener( + QUALITY_SCORES_STREAM, timestamp => { + this.categoryMask = undefined; + this.setLatestOutputTimestamp(timestamp); + }); + const binaryGraph = graphConfig.serializeBinary(); this.setGraph(new Uint8Array(binaryGraph), /* isBinary= */ true); } diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.ts index 9107a5c80..363cc213d 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_result.ts @@ -30,7 +30,13 @@ export class ImageSegmenterResult { * `WebGLTexture`-backed `MPImage` where each pixel represents the class * which the pixel in the original image was predicted to belong to. */ - readonly categoryMask?: MPMask) {} + readonly categoryMask?: MPMask, + /** + * The quality scores of the result masks, in the range of [0, 1]. + * Defaults to `1` if the model doesn't output quality scores. Each + * element corresponds to the score of the category in the model outputs. + */ + readonly qualityScores?: number[]) {} /** Frees the resources held by the category and confidence masks. */ close(): void { diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts index 10983b488..c245001b2 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter_test.ts @@ -35,6 +35,8 @@ class ImageSegmenterFake extends ImageSegmenter implements MediapipeTasksFake { ((images: WasmImage, timestamp: number) => void)|undefined; confidenceMasksListener: ((images: WasmImage[], timestamp: number) => void)|undefined; + qualityScoresListener: + ((data: number[], timestamp: number) => void)|undefined; constructor() { super(createSpyWasmModule(), /* glCanvas= */ null); @@ -52,6 +54,12 @@ class ImageSegmenterFake extends ImageSegmenter implements MediapipeTasksFake { expect(stream).toEqual('confidence_masks'); this.confidenceMasksListener = listener; }); + this.attachListenerSpies[2] = + spyOn(this.graphRunner, 'attachFloatVectorListener') + .and.callFake((stream, listener) => { + expect(stream).toEqual('quality_scores'); + this.qualityScoresListener = listener; + }); spyOn(this.graphRunner, 'setGraph').and.callFake(binaryGraph => { this.graph = CalculatorGraphConfig.deserializeBinary(binaryGraph); }); @@ -266,6 +274,7 @@ describe('ImageSegmenter', () => { it('invokes listener after masks are available', async () => { const categoryMask = new Uint8Array([1]); const confidenceMask = new Float32Array([0.0]); + const qualityScores = [1.0]; let listenerCalled = false; await imageSegmenter.setOptions( @@ -283,11 +292,16 @@ describe('ImageSegmenter', () => { ], 1337); expect(listenerCalled).toBeFalse(); + imageSegmenter.qualityScoresListener!(qualityScores, 1337); + expect(listenerCalled).toBeFalse(); }); return new Promise(resolve => { - imageSegmenter.segment({} as HTMLImageElement, () => { + imageSegmenter.segment({} as HTMLImageElement, result => { listenerCalled = true; + expect(result.categoryMask).toBeInstanceOf(MPMask); + expect(result.confidenceMasks![0]).toBeInstanceOf(MPMask); + expect(result.qualityScores).toEqual(qualityScores); resolve(); }); }); diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts index 16bf10eeb..662eaf09a 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter.ts @@ -42,6 +42,7 @@ const NORM_RECT_IN_STREAM = 'norm_rect_in'; const ROI_IN_STREAM = 'roi_in'; const CONFIDENCE_MASKS_STREAM = 'confidence_masks'; const CATEGORY_MASK_STREAM = 'category_mask'; +const QUALITY_SCORES_STREAM = 'quality_scores'; const IMAGEA_SEGMENTER_GRAPH = 'mediapipe.tasks.vision.interactive_segmenter.InteractiveSegmenterGraph'; const DEFAULT_OUTPUT_CATEGORY_MASK = false; @@ -86,6 +87,7 @@ export type InteractiveSegmenterCallback = export class InteractiveSegmenter extends VisionTaskRunner { private categoryMask?: MPMask; private confidenceMasks?: MPMask[]; + private qualityScores?: number[]; private outputCategoryMask = DEFAULT_OUTPUT_CATEGORY_MASK; private outputConfidenceMasks = DEFAULT_OUTPUT_CONFIDENCE_MASKS; private userCallback?: InteractiveSegmenterCallback; @@ -284,12 +286,13 @@ export class InteractiveSegmenter extends VisionTaskRunner { private reset(): void { this.confidenceMasks = undefined; this.categoryMask = undefined; + this.qualityScores = undefined; } private processResults(): InteractiveSegmenterResult|void { try { const result = new InteractiveSegmenterResult( - this.confidenceMasks, this.categoryMask); + this.confidenceMasks, this.categoryMask, this.qualityScores); if (this.userCallback) { this.userCallback(result); } else { @@ -361,6 +364,20 @@ export class InteractiveSegmenter extends VisionTaskRunner { }); } + graphConfig.addOutputStream(QUALITY_SCORES_STREAM); + segmenterNode.addOutputStream('QUALITY_SCORES:' + QUALITY_SCORES_STREAM); + + this.graphRunner.attachFloatVectorListener( + QUALITY_SCORES_STREAM, (scores, timestamp) => { + this.qualityScores = scores; + this.setLatestOutputTimestamp(timestamp); + }); + this.graphRunner.attachEmptyPacketListener( + QUALITY_SCORES_STREAM, timestamp => { + this.categoryMask = undefined; + this.setLatestOutputTimestamp(timestamp); + }); + const binaryGraph = graphConfig.serializeBinary(); this.setGraph(new Uint8Array(binaryGraph), /* isBinary= */ true); } diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.ts index 5da7e4df3..3b45d09e7 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_result.ts @@ -30,7 +30,13 @@ export class InteractiveSegmenterResult { * `WebGLTexture`-backed `MPImage` where each pixel represents the class * which the pixel in the original image was predicted to belong to. */ - readonly categoryMask?: MPMask) {} + readonly categoryMask?: MPMask, + /** + * The quality scores of the result masks, in the range of [0, 1]. + * Defaults to `1` if the model doesn't output quality scores. Each + * element corresponds to the score of the category in the model outputs. + */ + readonly qualityScores?: number[]) {} /** Frees the resources held by the category and confidence masks. */ close(): void { diff --git a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts index 6550202e0..fe2d27157 100644 --- a/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts +++ b/mediapipe/tasks/web/vision/interactive_segmenter/interactive_segmenter_test.ts @@ -46,6 +46,8 @@ class InteractiveSegmenterFake extends InteractiveSegmenter implements ((images: WasmImage, timestamp: number) => void)|undefined; confidenceMasksListener: ((images: WasmImage[], timestamp: number) => void)|undefined; + qualityScoresListener: + ((data: number[], timestamp: number) => void)|undefined; lastRoi?: RenderDataProto; constructor() { @@ -64,6 +66,12 @@ class InteractiveSegmenterFake extends InteractiveSegmenter implements expect(stream).toEqual('confidence_masks'); this.confidenceMasksListener = listener; }); + this.attachListenerSpies[2] = + spyOn(this.graphRunner, 'attachFloatVectorListener') + .and.callFake((stream, listener) => { + expect(stream).toEqual('quality_scores'); + this.qualityScoresListener = listener; + }); spyOn(this.graphRunner, 'setGraph').and.callFake(binaryGraph => { this.graph = CalculatorGraphConfig.deserializeBinary(binaryGraph); }); @@ -277,9 +285,10 @@ describe('InteractiveSegmenter', () => { }); }); - it('invokes listener after masks are avaiblae', async () => { + it('invokes listener after masks are available', async () => { const categoryMask = new Uint8Array([1]); const confidenceMask = new Float32Array([0.0]); + const qualityScores = [1.0]; let listenerCalled = false; await interactiveSegmenter.setOptions( @@ -297,11 +306,16 @@ describe('InteractiveSegmenter', () => { ], 1337); expect(listenerCalled).toBeFalse(); + interactiveSegmenter.qualityScoresListener!(qualityScores, 1337); + expect(listenerCalled).toBeFalse(); }); return new Promise(resolve => { - interactiveSegmenter.segment({} as HTMLImageElement, KEYPOINT, () => { + interactiveSegmenter.segment({} as HTMLImageElement, KEYPOINT, result => { listenerCalled = true; + expect(result.categoryMask).toBeInstanceOf(MPMask); + expect(result.confidenceMasks![0]).toBeInstanceOf(MPMask); + expect(result.qualityScores).toEqual(qualityScores); resolve(); }); }); From e8ee934bf99a5cb209c1132d08879f34c8c13894 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Tue, 23 May 2023 15:07:06 -0700 Subject: [PATCH 313/753] Use empty keypoint array for Detection if no keypoints are detected PiperOrigin-RevId: 534572162 --- .../web/components/containers/detection_result.d.ts | 13 +++++++------ .../components/processors/detection_result.test.ts | 3 ++- .../web/components/processors/detection_result.ts | 3 +-- .../web/vision/face_detector/face_detector_test.ts | 3 ++- .../vision/object_detector/object_detector_test.ts | 3 ++- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/mediapipe/tasks/web/components/containers/detection_result.d.ts b/mediapipe/tasks/web/components/containers/detection_result.d.ts index 287632f2d..590bd7340 100644 --- a/mediapipe/tasks/web/components/containers/detection_result.d.ts +++ b/mediapipe/tasks/web/components/containers/detection_result.d.ts @@ -27,13 +27,14 @@ export declare interface Detection { boundingBox?: BoundingBox; /** - * Optional list of keypoints associated with the detection. Keypoints - * represent interesting points related to the detection. For example, the - * keypoints represent the eye, ear and mouth from face detection model. Or - * in the template matching detection, e.g. KNIFT, they can represent the - * feature points for template matching. + * List of keypoints associated with the detection. Keypoints represent + * interesting points related to the detection. For example, the keypoints + * represent the eye, ear and mouth from face detection model. Or in the + * template matching detection, e.g. KNIFT, they can represent the feature + * points for template matching. Contains an empty list if no keypoints are + * detected. */ - keypoints?: NormalizedKeypoint[]; + keypoints: NormalizedKeypoint[]; } /** Detection results of a model. */ diff --git a/mediapipe/tasks/web/components/processors/detection_result.test.ts b/mediapipe/tasks/web/components/processors/detection_result.test.ts index 28b37ab0e..0fa8156ba 100644 --- a/mediapipe/tasks/web/components/processors/detection_result.test.ts +++ b/mediapipe/tasks/web/components/processors/detection_result.test.ts @@ -85,7 +85,8 @@ describe('convertFromDetectionProto()', () => { categoryName: '', displayName: '', }], - boundingBox: {originX: 0, originY: 0, width: 0, height: 0} + boundingBox: {originX: 0, originY: 0, width: 0, height: 0}, + keypoints: [] }); }); }); diff --git a/mediapipe/tasks/web/components/processors/detection_result.ts b/mediapipe/tasks/web/components/processors/detection_result.ts index 304b51a8e..4999ed31b 100644 --- a/mediapipe/tasks/web/components/processors/detection_result.ts +++ b/mediapipe/tasks/web/components/processors/detection_result.ts @@ -26,7 +26,7 @@ export function convertFromDetectionProto(source: DetectionProto): Detection { const labels = source.getLabelList(); const displayNames = source.getDisplayNameList(); - const detection: Detection = {categories: []}; + const detection: Detection = {categories: [], keypoints: []}; for (let i = 0; i < scores.length; i++) { detection.categories.push({ score: scores[i], @@ -47,7 +47,6 @@ export function convertFromDetectionProto(source: DetectionProto): Detection { } if (source.getLocationData()?.getRelativeKeypointsList().length) { - detection.keypoints = []; for (const keypoint of source.getLocationData()!.getRelativeKeypointsList()) { detection.keypoints.push({ diff --git a/mediapipe/tasks/web/vision/face_detector/face_detector_test.ts b/mediapipe/tasks/web/vision/face_detector/face_detector_test.ts index 28f602965..dfe84bb17 100644 --- a/mediapipe/tasks/web/vision/face_detector/face_detector_test.ts +++ b/mediapipe/tasks/web/vision/face_detector/face_detector_test.ts @@ -191,7 +191,8 @@ describe('FaceDetector', () => { categoryName: '', displayName: '', }], - boundingBox: {originX: 0, originY: 0, width: 0, height: 0} + boundingBox: {originX: 0, originY: 0, width: 0, height: 0}, + keypoints: [] }); }); }); diff --git a/mediapipe/tasks/web/vision/object_detector/object_detector_test.ts b/mediapipe/tasks/web/vision/object_detector/object_detector_test.ts index 1613f27d7..9c63eaba1 100644 --- a/mediapipe/tasks/web/vision/object_detector/object_detector_test.ts +++ b/mediapipe/tasks/web/vision/object_detector/object_detector_test.ts @@ -210,7 +210,8 @@ describe('ObjectDetector', () => { categoryName: '', displayName: '', }], - boundingBox: {originX: 0, originY: 0, width: 0, height: 0} + boundingBox: {originX: 0, originY: 0, width: 0, height: 0}, + keypoints: [] }); }); }); From 3dcfca3a731b0bfe7c86f0354fa4ecfa39b83fc2 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 23 May 2023 17:56:25 -0700 Subject: [PATCH 314/753] 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 --- mediapipe/framework/deps/status_builder.cc | 4 ++-- mediapipe/framework/deps/status_builder.h | 4 ++-- mediapipe/framework/type_map.h | 15 +++++++++------ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/mediapipe/framework/deps/status_builder.cc b/mediapipe/framework/deps/status_builder.cc index 0202b8689..041b8608b 100644 --- a/mediapipe/framework/deps/status_builder.cc +++ b/mediapipe/framework/deps/status_builder.cc @@ -68,11 +68,11 @@ StatusBuilder&& StatusBuilder::SetNoLogging() && { return std::move(SetNoLogging()); } -StatusBuilder::operator Status() const& { +StatusBuilder::operator absl::Status() const& { return StatusBuilder(*this).JoinMessageToStatus(); } -StatusBuilder::operator Status() && { return JoinMessageToStatus(); } +StatusBuilder::operator absl::Status() && { return JoinMessageToStatus(); } absl::Status StatusBuilder::JoinMessageToStatus() { if (!impl_) { diff --git a/mediapipe/framework/deps/status_builder.h b/mediapipe/framework/deps/status_builder.h index ae11699d2..935ab7776 100644 --- a/mediapipe/framework/deps/status_builder.h +++ b/mediapipe/framework/deps/status_builder.h @@ -83,8 +83,8 @@ class ABSL_MUST_USE_RESULT StatusBuilder { return std::move(*this << msg); } - operator Status() const&; - operator Status() &&; + operator absl::Status() const&; + operator absl::Status() &&; absl::Status JoinMessageToStatus(); diff --git a/mediapipe/framework/type_map.h b/mediapipe/framework/type_map.h index e26efa039..8fb324e98 100644 --- a/mediapipe/framework/type_map.h +++ b/mediapipe/framework/type_map.h @@ -272,17 +272,20 @@ DEFINE_MEDIAPIPE_TYPE_MAP(PacketTypeStringToMediaPipeTypeData, std::string); #define MEDIAPIPE_REGISTER_TYPE(type, type_name, serialize_fn, deserialize_fn) \ SET_MEDIAPIPE_TYPE_MAP_VALUE( \ mediapipe::PacketTypeIdToMediaPipeTypeData, \ - mediapipe::tool::GetTypeHash< \ - mediapipe::type_map_internal::ReflectType::Type>(), \ + mediapipe::TypeId::Of< \ + mediapipe::type_map_internal::ReflectType::Type>() \ + .hash_code(), \ (mediapipe::MediaPipeTypeData{ \ - mediapipe::tool::GetTypeHash< \ - mediapipe::type_map_internal::ReflectType::Type>(), \ + mediapipe::TypeId::Of< \ + mediapipe::type_map_internal::ReflectType::Type>() \ + .hash_code(), \ type_name, serialize_fn, deserialize_fn})); \ SET_MEDIAPIPE_TYPE_MAP_VALUE( \ mediapipe::PacketTypeStringToMediaPipeTypeData, type_name, \ (mediapipe::MediaPipeTypeData{ \ - mediapipe::tool::GetTypeHash< \ - mediapipe::type_map_internal::ReflectType::Type>(), \ + mediapipe::TypeId::Of< \ + mediapipe::type_map_internal::ReflectType::Type>() \ + .hash_code(), \ type_name, serialize_fn, deserialize_fn})); // End define MEDIAPIPE_REGISTER_TYPE. From 201b2d739d994c51bb1b72336a09b8a93ed982d2 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 23 May 2023 18:00:54 -0700 Subject: [PATCH 315/753] Fix c++98-compat-extra-semi warnings PiperOrigin-RevId: 534624086 --- mediapipe/framework/deps/strong_int.h | 34 +++++++++++++-------------- mediapipe/framework/timestamp.h | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/mediapipe/framework/deps/strong_int.h b/mediapipe/framework/deps/strong_int.h index 6f102238f..3ddb6d0be 100644 --- a/mediapipe/framework/deps/strong_int.h +++ b/mediapipe/framework/deps/strong_int.h @@ -403,11 +403,11 @@ std::ostream &operator<<(std::ostream &os, lhs op## = rhs; \ return lhs; \ } -STRONG_INT_VS_STRONG_INT_BINARY_OP(+); -STRONG_INT_VS_STRONG_INT_BINARY_OP(-); -STRONG_INT_VS_STRONG_INT_BINARY_OP(&); -STRONG_INT_VS_STRONG_INT_BINARY_OP(|); -STRONG_INT_VS_STRONG_INT_BINARY_OP(^); +STRONG_INT_VS_STRONG_INT_BINARY_OP(+) +STRONG_INT_VS_STRONG_INT_BINARY_OP(-) +STRONG_INT_VS_STRONG_INT_BINARY_OP(&) +STRONG_INT_VS_STRONG_INT_BINARY_OP(|) +STRONG_INT_VS_STRONG_INT_BINARY_OP(^) #undef STRONG_INT_VS_STRONG_INT_BINARY_OP // Define operators that take one StrongInt and one native integer argument. @@ -431,12 +431,12 @@ STRONG_INT_VS_STRONG_INT_BINARY_OP(^); rhs op## = lhs; \ return rhs; \ } -STRONG_INT_VS_NUMERIC_BINARY_OP(*); -NUMERIC_VS_STRONG_INT_BINARY_OP(*); -STRONG_INT_VS_NUMERIC_BINARY_OP(/); -STRONG_INT_VS_NUMERIC_BINARY_OP(%); -STRONG_INT_VS_NUMERIC_BINARY_OP(<<); // NOLINT(whitespace/operators) -STRONG_INT_VS_NUMERIC_BINARY_OP(>>); // NOLINT(whitespace/operators) +STRONG_INT_VS_NUMERIC_BINARY_OP(*) +NUMERIC_VS_STRONG_INT_BINARY_OP(*) +STRONG_INT_VS_NUMERIC_BINARY_OP(/) +STRONG_INT_VS_NUMERIC_BINARY_OP(%) +STRONG_INT_VS_NUMERIC_BINARY_OP(<<) // NOLINT(whitespace/operators) +STRONG_INT_VS_NUMERIC_BINARY_OP(>>) // NOLINT(whitespace/operators) #undef STRONG_INT_VS_NUMERIC_BINARY_OP #undef NUMERIC_VS_STRONG_INT_BINARY_OP @@ -447,12 +447,12 @@ STRONG_INT_VS_NUMERIC_BINARY_OP(>>); // NOLINT(whitespace/operators) StrongInt rhs) { \ return lhs.value() op rhs.value(); \ } -STRONG_INT_COMPARISON_OP(==); // NOLINT(whitespace/operators) -STRONG_INT_COMPARISON_OP(!=); // NOLINT(whitespace/operators) -STRONG_INT_COMPARISON_OP(<); // NOLINT(whitespace/operators) -STRONG_INT_COMPARISON_OP(<=); // NOLINT(whitespace/operators) -STRONG_INT_COMPARISON_OP(>); // NOLINT(whitespace/operators) -STRONG_INT_COMPARISON_OP(>=); // NOLINT(whitespace/operators) +STRONG_INT_COMPARISON_OP(==) // NOLINT(whitespace/operators) +STRONG_INT_COMPARISON_OP(!=) // NOLINT(whitespace/operators) +STRONG_INT_COMPARISON_OP(<) // NOLINT(whitespace/operators) +STRONG_INT_COMPARISON_OP(<=) // NOLINT(whitespace/operators) +STRONG_INT_COMPARISON_OP(>) // NOLINT(whitespace/operators) +STRONG_INT_COMPARISON_OP(>=) // NOLINT(whitespace/operators) #undef STRONG_INT_COMPARISON_OP } // namespace intops diff --git a/mediapipe/framework/timestamp.h b/mediapipe/framework/timestamp.h index b8c3a69a2..966ec1839 100644 --- a/mediapipe/framework/timestamp.h +++ b/mediapipe/framework/timestamp.h @@ -57,7 +57,7 @@ namespace mediapipe { // have underflow/overflow etc. This type is used internally by Timestamp // and TimestampDiff. MEDIAPIPE_DEFINE_SAFE_INT_TYPE(TimestampBaseType, int64, - mediapipe::intops::LogFatalOnError); + mediapipe::intops::LogFatalOnError) class TimestampDiff; From bc035d914667e94d8ab5a03f8b4fdb53e79c5ce4 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 23 May 2023 21:47:20 -0700 Subject: [PATCH 316/753] This will fix the multiple typos in the tasks files. PiperOrigin-RevId: 534679277 --- mediapipe/model_maker/python/core/utils/loss_functions.py | 2 +- .../python/vision/face_stylizer/face_stylizer.py | 4 ++-- .../vision/image_classifier/MPPImageClassifierTests.m | 4 ++-- .../test/vision/object_detector/MPPObjectDetectorTests.m | 8 ++++---- .../mediapipe/tasks/vision/core/BaseVisionTaskApi.java | 2 +- mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts | 6 +++--- .../tasks/web/vision/image_segmenter/image_segmenter.ts | 6 +++--- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/mediapipe/model_maker/python/core/utils/loss_functions.py b/mediapipe/model_maker/python/core/utils/loss_functions.py index a60bd2ed4..504ba91ef 100644 --- a/mediapipe/model_maker/python/core/utils/loss_functions.py +++ b/mediapipe/model_maker/python/core/utils/loss_functions.py @@ -187,7 +187,7 @@ class PerceptualLoss(tf.keras.Model, metaclass=abc.ABCMeta): """Instantiates perceptual loss. Args: - feature_weight: The weight coeffcients of multiple model extracted + feature_weight: The weight coefficients of multiple model extracted features used for calculating the perceptual loss. loss_weight: The weight coefficients between `style_loss` and `content_loss`. diff --git a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py index 85b567ca3..5758ac7b5 100644 --- a/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py +++ b/mediapipe/model_maker/python/vision/face_stylizer/face_stylizer.py @@ -105,7 +105,7 @@ class FaceStylizer(object): self._train_model(train_data=train_data, preprocessor=self._preprocessor) def _create_model(self): - """Creates the componenets of face stylizer.""" + """Creates the components of face stylizer.""" self._encoder = model_util.load_keras_model( constants.FACE_STYLIZER_ENCODER_MODEL_FILES.get_path() ) @@ -138,7 +138,7 @@ class FaceStylizer(object): """ train_dataset = train_data.gen_tf_dataset(preprocess=preprocessor) - # TODO: Support processing mulitple input style images. The + # TODO: Support processing multiple input style images. The # input style images are expected to have similar style. # style_sample represents a tuple of (style_image, style_label). style_sample = next(iter(train_dataset)) diff --git a/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m b/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m index 332a217ca..59383dad6 100644 --- a/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m +++ b/mediapipe/tasks/ios/test/vision/image_classifier/MPPImageClassifierTests.m @@ -668,10 +668,10 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; // Because of flow limiting, we cannot ensure that the callback will be // invoked `iterationCount` times. - // An normal expectation will fail if expectation.fullfill() is not called + // An normal expectation will fail if expectation.fulfill() is not called // `expectation.expectedFulfillmentCount` times. // If `expectation.isInverted = true`, the test will only succeed if - // expectation is not fullfilled for the specified `expectedFulfillmentCount`. + // expectation is not fulfilled for the specified `expectedFulfillmentCount`. // Since in our case we cannot predict how many times the expectation is // supposed to be fullfilled setting, // `expectation.expectedFulfillmentCount` = `iterationCount` + 1 and diff --git a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m index 1b717ba48..2ef5a0957 100644 --- a/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m +++ b/mediapipe/tasks/ios/test/vision/object_detector/MPPObjectDetectorTests.m @@ -673,15 +673,15 @@ static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; // Because of flow limiting, we cannot ensure that the callback will be // invoked `iterationCount` times. - // An normal expectation will fail if expectation.fullfill() is not called + // An normal expectation will fail if expectation.fulfill() is not called // `expectation.expectedFulfillmentCount` times. // If `expectation.isInverted = true`, the test will only succeed if - // expectation is not fullfilled for the specified `expectedFulfillmentCount`. + // expectation is not fulfilled for the specified `expectedFulfillmentCount`. // Since in our case we cannot predict how many times the expectation is - // supposed to be fullfilled setting, + // supposed to be fulfilled setting, // `expectation.expectedFulfillmentCount` = `iterationCount` + 1 and // `expectation.isInverted = true` ensures that test succeeds if - // expectation is fullfilled <= `iterationCount` times. + // expectation is fulfilled <= `iterationCount` times. XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:@"detectWithOutOfOrderTimestampsAndLiveStream"]; expectation.expectedFulfillmentCount = iterationCount + 1; diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java index 5964cef2c..9ea057b0d 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/core/BaseVisionTaskApi.java @@ -166,7 +166,7 @@ public class BaseVisionTaskApi implements AutoCloseable { // For 90° and 270° rotations, we need to swap width and height. // This is due to the internal behavior of ImageToTensorCalculator, which: // - first denormalizes the provided rect by multiplying the rect width or - // height by the image width or height, repectively. + // height by the image width or height, respectively. // - then rotates this by denormalized rect by the provided rotation, and // uses this for cropping, // - then finally rotates this back. diff --git a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts index 8169e6775..2d99dc54d 100644 --- a/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts +++ b/mediapipe/tasks/web/vision/face_stylizer/face_stylizer.ts @@ -171,7 +171,7 @@ export class FaceStylizer extends VisionTaskRunner { /** * Performs face stylization on the provided single image and returns the * result. This method creates a copy of the resulting image and should not be - * used in high-throughput applictions. Only use this method when the + * used in high-throughput applications. Only use this method when the * FaceStylizer is created with the image running mode. * * @param image An image to process. @@ -182,7 +182,7 @@ export class FaceStylizer extends VisionTaskRunner { /** * Performs face stylization on the provided single image and returns the * result. This method creates a copy of the resulting image and should not be - * used in high-throughput applictions. Only use this method when the + * used in high-throughput applications. Only use this method when the * FaceStylizer is created with the image running mode. * * The 'imageProcessingOptions' parameter can be used to specify one or all @@ -275,7 +275,7 @@ export class FaceStylizer extends VisionTaskRunner { /** * Performs face stylization on the provided video frame. This method creates * a copy of the resulting image and should not be used in high-throughput - * applictions. Only use this method when the FaceStylizer is created with the + * applications. Only use this method when the FaceStylizer is created with the * video running mode. * * The input frame can be of any size. It's required to provide the video diff --git a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts index 3dd2d03ef..6d295aaa8 100644 --- a/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts +++ b/mediapipe/tasks/web/vision/image_segmenter/image_segmenter.ts @@ -231,7 +231,7 @@ export class ImageSegmenter extends VisionTaskRunner { /** * Performs image segmentation on the provided single image and returns the * segmentation result. This method creates a copy of the resulting masks and - * should not be used in high-throughput applictions. Only use this method + * should not be used in high-throughput applications. Only use this method * when the ImageSegmenter is created with running mode `image`. * * @param image An image to process. @@ -242,7 +242,7 @@ export class ImageSegmenter extends VisionTaskRunner { /** * Performs image segmentation on the provided single image and returns the * segmentation result. This method creates a copy of the resulting masks and - * should not be used in high-v applictions. Only use this method when + * should not be used in high-v applications. Only use this method when * the ImageSegmenter is created with running mode `image`. * * @param image An image to process. @@ -320,7 +320,7 @@ export class ImageSegmenter extends VisionTaskRunner { /** * Performs image segmentation on the provided video frame and returns the * segmentation result. This method creates a copy of the resulting masks and - * should not be used in high-v applictions. Only use this method when + * should not be used in high-v applications. Only use this method when * the ImageSegmenter is created with running mode `video`. * * @param videoFrame A video frame to process. From 69017381af8d647b14242320e3a2c208c2b42d8f Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 24 May 2023 19:57:38 +0530 Subject: [PATCH 317/753] Updated MPPObjectDetectorResult Helpers to return empty result instead of nil --- .../utils/sources/MPPObjectDetectorResult+Helpers.mm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorResult+Helpers.mm b/mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorResult+Helpers.mm index b2f9cfc08..3a8a72f71 100644 --- a/mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorResult+Helpers.mm +++ b/mediapipe/tasks/ios/vision/object_detector/utils/sources/MPPObjectDetectorResult+Helpers.mm @@ -25,8 +25,12 @@ using ::mediapipe::Packet; + (nullable MPPObjectDetectorResult *)objectDetectorResultWithDetectionsPacket: (const Packet &)packet { + + NSInteger timestampInMilliseconds = (NSInteger)(packet.Timestamp().Value() / + kMicroSecondsPerMilliSecond); if (!packet.ValidateAsType>().ok()) { - return nil; + return [[MPPObjectDetectorResult alloc] initWithDetections:@[] + timestampInMilliseconds:timestampInMilliseconds]; } const std::vector &detectionProtos = packet.Get>(); @@ -39,8 +43,7 @@ using ::mediapipe::Packet; return [[MPPObjectDetectorResult alloc] initWithDetections:detections - timestampInMilliseconds:(NSInteger)(packet.Timestamp().Value() / - kMicroSecondsPerMilliSecond)]; + timestampInMilliseconds:timestampInMilliseconds]; } @end From 1e1693d9aaf348fdf1d2fa9d2836bd76056b1c54 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 24 May 2023 20:24:34 +0530 Subject: [PATCH 318/753] Added support to set delegates in MPPBaseOptions --- .../tasks/ios/core/sources/MPPBaseOptions.h | 21 ++++++++++++++++++- .../tasks/ios/core/sources/MPPBaseOptions.m | 1 + .../utils/sources/MPPBaseOptions+Helpers.mm | 13 ++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h index bef6bb9ee..9f61d872a 100644 --- a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h +++ b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h @@ -16,6 +16,17 @@ NS_ASSUME_NONNULL_BEGIN +/** + * MediaPipe Tasks delegate. + */ + typedef NS_ENUM(NSUInteger, MPPDelegate) { + /** CPU. */ + MPPDelegateCPU, + + /** GPU. */ + MPPDelegateGPU + } NS_SWIFT_NAME(Delegate); + /** * Holds the base options that is used for creation of any type of task. It has fields with * important information acceleration configuration, TFLite model source etc. @@ -23,9 +34,17 @@ NS_ASSUME_NONNULL_BEGIN NS_SWIFT_NAME(BaseOptions) @interface MPPBaseOptions : NSObject -/** The path to the model asset to open and mmap in memory. */ +/** + * The absolute path to a model asset file (a tflite model or a model asset bundle file) stored in the app bundle. + */ @property(nonatomic, copy) NSString *modelAssetPath; +/** + * Device delegate to run the MediaPipe pipeline. If the delegate is not set, the default + * delegate CPU is used. + */ +@property(nonatomic) MPPDelegate delegate; + @end NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m index a43119ad8..c3571c4b4 100644 --- a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m +++ b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m @@ -28,6 +28,7 @@ MPPBaseOptions *baseOptions = [[MPPBaseOptions alloc] init]; baseOptions.modelAssetPath = self.modelAssetPath; + baseOptions.delegate = self.delegate; return baseOptions; } diff --git a/mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.mm b/mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.mm index 73bcac49d..a97487cd9 100644 --- a/mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.mm +++ b/mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.mm @@ -33,6 +33,19 @@ using BaseOptionsProto = ::mediapipe::tasks::core::proto::BaseOptions; if (self.modelAssetPath) { baseOptionsProto->mutable_model_asset()->set_file_name(self.modelAssetPath.UTF8String); } + + switch (self.delegate) { + case MPPDelegateCPU: { + baseOptionsProto->mutable_acceleration()->mutable_tflite(); + break; + } + case MPPDelegateGPU: { + baseOptionsProto->mutable_acceleration()->mutable_gpu(); + break; + } + default: + break; + } } @end From 8f1a56f3c2ee36737a6511e7fc951eb65fd1d243 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 24 May 2023 20:24:41 +0530 Subject: [PATCH 319/753] Fixed typos --- .../object_detector/sources/MPPObjectDetector.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h index d3f946bbe..f8cfcc916 100644 --- a/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h +++ b/mediapipe/tasks/ios/vision/object_detector/sources/MPPObjectDetector.h @@ -80,7 +80,7 @@ NS_SWIFT_NAME(ObjectDetector) * Creates a new instance of `MPPObjectDetector` from the given `MPPObjectDetectorOptions`. * * @param options The options of type `MPPObjectDetectorOptions` to use for configuring the - * `MPPImageClassifMPPObjectDetectorier`. + * `MPPObjectDetector`. * @param error An optional error parameter populated when there is an error in initializing the * object detector. * @@ -96,7 +96,7 @@ NS_SWIFT_NAME(ObjectDetector) * `MPPImage`. Only use this method when the `MPPObjectDetector` is created with * `MPPRunningModeImage`. * - * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * This method supports detecting objects in RGBA images. If your `MPPImage` has a source type of * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer * must have one of the following pixel format types: * 1. kCVPixelFormatType_32BGRA @@ -123,7 +123,7 @@ NS_SWIFT_NAME(ObjectDetector) * the provided `MPPImage`. Only use this method when the `MPPObjectDetector` is created with * `MPPRunningModeVideo`. * - * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * This method supports detecting objects in of RGBA images. If your `MPPImage` has a source type of * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer * must have one of the following pixel format types: * 1. kCVPixelFormatType_32BGRA @@ -161,7 +161,7 @@ NS_SWIFT_NAME(ObjectDetector) * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent * to the object detector. The input timestamps must be monotonically increasing. * - * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * This method supports detecting objects in RGBA images. If your `MPPImage` has a source type of * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer * must have one of the following pixel format types: * 1. kCVPixelFormatType_32BGRA @@ -170,8 +170,8 @@ NS_SWIFT_NAME(ObjectDetector) * If the input `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color * space is RGB with an Alpha channel. * - * If this method is used for classifying live camera frames using `AVFoundation`, ensure that you - * request `AVCaptureVideoDataOutput` to output frames in `kCMPixelFormat_32RGBA` using its + * If this method is used for detecting objects in live camera frames using `AVFoundation`, ensure + * that you request `AVCaptureVideoDataOutput` to output frames in `kCMPixelFormat_32RGBA` using its * `videoSettings` property. * * @param image A live stream image data of type `MPPImage` on which object detection is to be From 1aa44abcaba07ab2e5ba768d6f3e9882a3e694f9 Mon Sep 17 00:00:00 2001 From: Prianka Liz Kariat Date: Wed, 24 May 2023 20:25:45 +0530 Subject: [PATCH 320/753] Revert "Added support to set delegates in MPPBaseOptions" This reverts commit 1e1693d9aaf348fdf1d2fa9d2836bd76056b1c54. --- .../tasks/ios/core/sources/MPPBaseOptions.h | 21 +------------------ .../tasks/ios/core/sources/MPPBaseOptions.m | 1 - .../utils/sources/MPPBaseOptions+Helpers.mm | 13 ------------ 3 files changed, 1 insertion(+), 34 deletions(-) diff --git a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h index 9f61d872a..bef6bb9ee 100644 --- a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h +++ b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.h @@ -16,17 +16,6 @@ NS_ASSUME_NONNULL_BEGIN -/** - * MediaPipe Tasks delegate. - */ - typedef NS_ENUM(NSUInteger, MPPDelegate) { - /** CPU. */ - MPPDelegateCPU, - - /** GPU. */ - MPPDelegateGPU - } NS_SWIFT_NAME(Delegate); - /** * Holds the base options that is used for creation of any type of task. It has fields with * important information acceleration configuration, TFLite model source etc. @@ -34,17 +23,9 @@ NS_ASSUME_NONNULL_BEGIN NS_SWIFT_NAME(BaseOptions) @interface MPPBaseOptions : NSObject -/** - * The absolute path to a model asset file (a tflite model or a model asset bundle file) stored in the app bundle. - */ +/** The path to the model asset to open and mmap in memory. */ @property(nonatomic, copy) NSString *modelAssetPath; -/** - * Device delegate to run the MediaPipe pipeline. If the delegate is not set, the default - * delegate CPU is used. - */ -@property(nonatomic) MPPDelegate delegate; - @end NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m index c3571c4b4..a43119ad8 100644 --- a/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m +++ b/mediapipe/tasks/ios/core/sources/MPPBaseOptions.m @@ -28,7 +28,6 @@ MPPBaseOptions *baseOptions = [[MPPBaseOptions alloc] init]; baseOptions.modelAssetPath = self.modelAssetPath; - baseOptions.delegate = self.delegate; return baseOptions; } diff --git a/mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.mm b/mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.mm index a97487cd9..73bcac49d 100644 --- a/mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.mm +++ b/mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.mm @@ -33,19 +33,6 @@ using BaseOptionsProto = ::mediapipe::tasks::core::proto::BaseOptions; if (self.modelAssetPath) { baseOptionsProto->mutable_model_asset()->set_file_name(self.modelAssetPath.UTF8String); } - - switch (self.delegate) { - case MPPDelegateCPU: { - baseOptionsProto->mutable_acceleration()->mutable_tflite(); - break; - } - case MPPDelegateGPU: { - baseOptionsProto->mutable_acceleration()->mutable_gpu(); - break; - } - default: - break; - } } @end From 2017fcc9ab593da1717a79353ea706a365f907ea Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 24 May 2023 08:52:13 -0700 Subject: [PATCH 321/753] Add FaceDetector iOS API PiperOrigin-RevId: 534858193 --- mediapipe/tasks/ios/BUILD | 14 +- .../tasks/ios/vision/face_detector/BUILD | 62 +++++ .../face_detector/sources/MPPFaceDetector.h | 190 +++++++++++++ .../face_detector/sources/MPPFaceDetector.mm | 259 ++++++++++++++++++ .../sources/MPPFaceDetectorOptions.h | 101 +++++++ .../sources/MPPFaceDetectorOptions.m | 38 +++ .../sources/MPPFaceDetectorResult.h | 49 ++++ .../sources/MPPFaceDetectorResult.m | 28 ++ .../ios/vision/face_detector/utils/BUILD | 42 +++ .../sources/MPPFaceDetectorOptions+Helpers.h | 36 +++ .../sources/MPPFaceDetectorOptions+Helpers.mm | 39 +++ .../sources/MPPFaceDetectorResult+Helpers.h | 39 +++ .../sources/MPPFaceDetectorResult+Helpers.mm | 45 +++ 13 files changed, 939 insertions(+), 3 deletions(-) create mode 100644 mediapipe/tasks/ios/vision/face_detector/BUILD create mode 100644 mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetector.h create mode 100644 mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetector.mm create mode 100644 mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorOptions.h create mode 100644 mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorOptions.m create mode 100644 mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.h create mode 100644 mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.m create mode 100644 mediapipe/tasks/ios/vision/face_detector/utils/BUILD create mode 100644 mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorOptions+Helpers.h create mode 100644 mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorOptions+Helpers.mm create mode 100644 mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorResult+Helpers.h create mode 100644 mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorResult+Helpers.mm diff --git a/mediapipe/tasks/ios/BUILD b/mediapipe/tasks/ios/BUILD index d9be847f0..fae60e243 100644 --- a/mediapipe/tasks/ios/BUILD +++ b/mediapipe/tasks/ios/BUILD @@ -49,11 +49,12 @@ OBJC_TASK_COMMON_DEPS = [ ] CALCULATORS_AND_GRAPHS = [ - "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", - "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", + "//mediapipe/calculators/core:flow_limiter_calculator", "//mediapipe/tasks/cc/text/text_classifier:text_classifier_graph", "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", - "//mediapipe/calculators/core:flow_limiter_calculator", + "//mediapipe/tasks/cc/vision/face_detector:face_detector_graph", + "//mediapipe/tasks/cc/vision/image_classifier:image_classifier_graph", + "//mediapipe/tasks/cc/vision/object_detector:object_detector_graph", ] strip_api_include_path_prefix( @@ -76,6 +77,9 @@ strip_api_include_path_prefix( "//mediapipe/tasks/ios/text/text_embedder:sources/MPPTextEmbedderResult.h", "//mediapipe/tasks/ios/vision/core:sources/MPPRunningMode.h", "//mediapipe/tasks/ios/vision/core:sources/MPPImage.h", + "//mediapipe/tasks/ios/vision/face_detector:sources/MPPFaceDetector.h", + "//mediapipe/tasks/ios/vision/face_detector:sources/MPPFaceDetectorOptions.h", + "//mediapipe/tasks/ios/vision/face_detector:sources/MPPFaceDetectorResult.h", "//mediapipe/tasks/ios/vision/image_classifier:sources/MPPImageClassifier.h", "//mediapipe/tasks/ios/vision/image_classifier:sources/MPPImageClassifierOptions.h", "//mediapipe/tasks/ios/vision/image_classifier:sources/MPPImageClassifierResult.h", @@ -157,6 +161,9 @@ apple_static_xcframework( ":MPPTaskResult.h", ":MPPImage.h", ":MPPRunningMode.h", + ":MPPFaceDetector.h", + ":MPPFaceDetectorOptions.h", + ":MPPFaceDetectorResult.h", ":MPPImageClassifier.h", ":MPPImageClassifierOptions.h", ":MPPImageClassifierResult.h", @@ -165,6 +172,7 @@ apple_static_xcframework( ":MPPObjectDetectorResult.h", ], deps = [ + "//mediapipe/tasks/ios/vision/face_detector:MPPFaceDetector", "//mediapipe/tasks/ios/vision/image_classifier:MPPImageClassifier", "//mediapipe/tasks/ios/vision/object_detector:MPPObjectDetector", ], diff --git a/mediapipe/tasks/ios/vision/face_detector/BUILD b/mediapipe/tasks/ios/vision/face_detector/BUILD new file mode 100644 index 000000000..e4fc15616 --- /dev/null +++ b/mediapipe/tasks/ios/vision/face_detector/BUILD @@ -0,0 +1,62 @@ +# 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. + +package(default_visibility = ["//mediapipe/tasks:internal"]) + +licenses(["notice"]) + +objc_library( + name = "MPPFaceDetectorResult", + srcs = ["sources/MPPFaceDetectorResult.m"], + hdrs = ["sources/MPPFaceDetectorResult.h"], + deps = [ + "//mediapipe/tasks/ios/components/containers:MPPDetection", + "//mediapipe/tasks/ios/core:MPPTaskResult", + ], +) + +objc_library( + name = "MPPFaceDetectorOptions", + srcs = ["sources/MPPFaceDetectorOptions.m"], + hdrs = ["sources/MPPFaceDetectorOptions.h"], + deps = [ + ":MPPFaceDetectorResult", + "//mediapipe/tasks/ios/core:MPPTaskOptions", + "//mediapipe/tasks/ios/vision/core:MPPRunningMode", + ], +) + +objc_library( + name = "MPPFaceDetector", + srcs = ["sources/MPPFaceDetector.mm"], + hdrs = ["sources/MPPFaceDetector.h"], + copts = [ + "-ObjC++", + "-std=c++17", + "-x objective-c++", + ], + deps = [ + ":MPPFaceDetectorOptions", + ":MPPFaceDetectorResult", + "//mediapipe/tasks/cc/vision/face_detector:face_detector_graph", + "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", + "//mediapipe/tasks/ios/common/utils:NSStringHelpers", + "//mediapipe/tasks/ios/core:MPPTaskInfo", + "//mediapipe/tasks/ios/vision/core:MPPImage", + "//mediapipe/tasks/ios/vision/core:MPPVisionPacketCreator", + "//mediapipe/tasks/ios/vision/core:MPPVisionTaskRunner", + "//mediapipe/tasks/ios/vision/face_detector/utils:MPPFaceDetectorOptionsHelpers", + "//mediapipe/tasks/ios/vision/face_detector/utils:MPPFaceDetectorResultHelpers", + ], +) diff --git a/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetector.h b/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetector.h new file mode 100644 index 000000000..78f2fafbf --- /dev/null +++ b/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetector.h @@ -0,0 +1,190 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +#import "mediapipe/tasks/ios/vision/core/sources/MPPImage.h" +#import "mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorOptions.h" +#import "mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * @brief Class that performs face detection on images. + * + * The API expects a TFLite model with mandatory TFLite Model Metadata. + * + * The API supports models with one image input tensor and one or more output tensors. To be more + * specific, here are the requirements: + * + * Input tensor + * (kTfLiteUInt8/kTfLiteFloat32) + * - image input of size `[batch x height x width x channels]`. + * - batch inference is not supported (`batch` is required to be 1). + * - only RGB inputs are supported (`channels` is required to be 3). + * - if type is kTfLiteFloat32, NormalizationOptions are required to be attached to the metadata + * for input normalization. + * + * Output tensors must be the 4 outputs of a `DetectionPostProcess` op, i.e:(kTfLiteFloat32) + * (kTfLiteUInt8/kTfLiteFloat32) + * - locations tensor of size `[num_results x 4]`, the inner array representing bounding boxes + * in the form [top, left, right, bottom]. + * - BoundingBoxProperties are required to be attached to the metadata and must specify + * type=BOUNDARIES and coordinate_type=RATIO. + * (kTfLiteFloat32) + * - classes tensor of size `[num_results]`, each value representing the integer index of a + * class. + * - scores tensor of size `[num_results]`, each value representing the score of the detected + * face. + * - optional score calibration can be attached using ScoreCalibrationOptions and an + * AssociatedFile with type TENSOR_AXIS_SCORE_CALIBRATION. See metadata_schema.fbs [1] for more + * details. + * (kTfLiteFloat32) + * - integer num_results as a tensor of size `[1]` + */ +NS_SWIFT_NAME(FaceDetector) +@interface MPPFaceDetector : NSObject + +/** + * Creates a new instance of `MPPFaceDetector` from an absolute path to a TensorFlow Lite model + * file stored locally on the device and the default `MPPFaceDetector`. + * + * @param modelPath An absolute path to a TensorFlow Lite model file stored locally on the device. + * @param error An optional error parameter populated when there is an error in initializing the + * face detector. + * + * @return A new instance of `MPPFaceDetector` with the given model path. `nil` if there is an + * error in initializing the face detector. + */ +- (nullable instancetype)initWithModelPath:(NSString *)modelPath error:(NSError **)error; + +/** + * Creates a new instance of `MPPFaceDetector` from the given `MPPFaceDetectorOptions`. + * + * @param options The options of type `MPPFaceDetectorOptions` to use for configuring the + * `MPPFaceDetector`. + * @param error An optional error parameter populated when there is an error in initializing the + * face detector. + * + * @return A new instance of `MPPFaceDetector` with the given options. `nil` if there is an error + * in initializing the face detector. + */ +- (nullable instancetype)initWithOptions:(MPPFaceDetectorOptions *)options + error:(NSError **)error NS_DESIGNATED_INITIALIZER; + +/** + * Performs face detection on the provided MPPImage using the whole image as region of + * interest. Rotation will be applied according to the `orientation` property of the provided + * `MPPImage`. Only use this method when the `MPPFaceDetector` is created with + * `MPPRunningModeImage`. + * + * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is + * RGB with an Alpha channel. + * + * @param image The `MPPImage` on which face detection is to be performed. + * @param error An optional error parameter populated when there is an error in performing face + * detection on the input image. + * + * @return An `MPPFaceDetectorResult` face that contains a list of detections, each detection + * has a bounding box that is expressed in the unrotated input frame of reference coordinates + * system, i.e. in `[0,image_width) x [0,image_height)`, which are the dimensions of the underlying + * image data. + */ +- (nullable MPPFaceDetectorResult *)detectInImage:(MPPImage *)image + error:(NSError **)error NS_SWIFT_NAME(detect(image:)); + +/** + * Performs face detection on the provided video frame of type `MPPImage` using the whole + * image as region of interest. Rotation will be applied according to the `orientation` property of + * the provided `MPPImage`. Only use this method when the `MPPFaceDetector` is created with + * `MPPRunningModeVideo`. + * + * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If your `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color space is + * RGB with an Alpha channel. + * + * @param image The `MPPImage` on which face detection is to be performed. + * @param timestampInMilliseconds The video frame's timestamp (in milliseconds). The input + * timestamps must be monotonically increasing. + * @param error An optional error parameter populated when there is an error in performing face + * detection on the input image. + * + * @return An `MPPFaceDetectorResult` face that contains a list of detections, each detection + * has a bounding box that is expressed in the unrotated input frame of reference coordinates + * system, i.e. in `[0,image_width) x [0,image_height)`, which are the dimensions of the underlying + * image data. + */ +- (nullable MPPFaceDetectorResult *)detectInVideoFrame:(MPPImage *)image + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(NSError **)error + NS_SWIFT_NAME(detect(videoFrame:timestampInMilliseconds:)); + +/** + * Sends live stream image data of type `MPPImage` to perform face detection using the whole + * image as region of interest. Rotation will be applied according to the `orientation` property of + * the provided `MPPImage`. Only use this method when the `MPPFaceDetector` is created with + * `MPPRunningModeLiveStream`. + * + * The object which needs to be continuously notified of the available results of face + * detection must confirm to `MPPFaceDetectorLiveStreamDelegate` protocol and implement the + * `faceDetector:didFinishDetectionWithResult:timestampInMilliseconds:error:` delegate method. + * + * It's required to provide a timestamp (in milliseconds) to indicate when the input image is sent + * to the face detector. The input timestamps must be monotonically increasing. + * + * This method supports classification of RGBA images. If your `MPPImage` has a source type of + * `MPPImageSourceTypePixelBuffer` or `MPPImageSourceTypeSampleBuffer`, the underlying pixel buffer + * must have one of the following pixel format types: + * 1. kCVPixelFormatType_32BGRA + * 2. kCVPixelFormatType_32RGBA + * + * If the input `MPPImage` has a source type of `MPPImageSourceTypeImage` ensure that the color + * space is RGB with an Alpha channel. + * + * If this method is used for classifying live camera frames using `AVFoundation`, ensure that you + * request `AVCaptureVideoDataOutput` to output frames in `kCMPixelFormat_32RGBA` using its + * `videoSettings` property. + * + * @param image A live stream image data of type `MPPImage` on which face detection is to be + * performed. + * @param timestampInMilliseconds The timestamp (in milliseconds) which indicates when the input + * image is sent to the face detector. The input timestamps must be monotonically increasing. + * @param error An optional error parameter populated when there is an error in performing face + * detection on the input live stream image data. + * + * @return `YES` if the image was sent to the task successfully, otherwise `NO`. + */ +- (BOOL)detectAsyncInImage:(MPPImage *)image + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(NSError **)error + NS_SWIFT_NAME(detectAsync(image:timestampInMilliseconds:)); + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetector.mm b/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetector.mm new file mode 100644 index 000000000..ceb5c957d --- /dev/null +++ b/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetector.mm @@ -0,0 +1,259 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetector.h" + +#import "mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h" +#import "mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h" +#import "mediapipe/tasks/ios/core/sources/MPPTaskInfo.h" +#import "mediapipe/tasks/ios/vision/core/sources/MPPVisionPacketCreator.h" +#import "mediapipe/tasks/ios/vision/core/sources/MPPVisionTaskRunner.h" +#import "mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorOptions+Helpers.h" +#import "mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorResult+Helpers.h" + +using ::mediapipe::NormalizedRect; +using ::mediapipe::Packet; +using ::mediapipe::Timestamp; +using ::mediapipe::tasks::core::PacketMap; +using ::mediapipe::tasks::core::PacketsCallback; + +static constexpr int kMicrosecondsPerMillisecond = 1000; + +// Constants for the underlying MP Tasks Graph. See +// https://github.com/google/mediapipe/tree/master/mediapipe/tasks/cc/vision/face_detector/face_detector_graph.cc +static NSString *const kDetectionsStreamName = @"detections_out"; +static NSString *const kDetectionsTag = @"DETECTIONS"; +static NSString *const kImageInStreamName = @"image_in"; +static NSString *const kImageOutStreamName = @"image_out"; +static NSString *const kImageTag = @"IMAGE"; +static NSString *const kNormRectStreamName = @"norm_rect_in"; +static NSString *const kNormRectTag = @"NORM_RECT"; +static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.face_detector.FaceDetectorGraph"; +static NSString *const kTaskName = @"faceDetector"; + +#define InputPacketMap(imagePacket, normalizedRectPacket) \ + { \ + {kImageInStreamName.cppString, imagePacket}, { \ + kNormRectStreamName.cppString, normalizedRectPacket \ + } \ + } + +@interface MPPFaceDetector () { + /** iOS Vision Task Runner */ + MPPVisionTaskRunner *_visionTaskRunner; + dispatch_queue_t _callbackQueue; +} +@property(nonatomic, weak) id faceDetectorLiveStreamDelegate; + +- (void)processLiveStreamResult:(absl::StatusOr)liveStreamResult; +@end + +@implementation MPPFaceDetector + +- (instancetype)initWithOptions:(MPPFaceDetectorOptions *)options error:(NSError **)error { + self = [super init]; + if (self) { + MPPTaskInfo *taskInfo = [[MPPTaskInfo alloc] + initWithTaskGraphName:kTaskGraphName + inputStreams:@[ + [NSString stringWithFormat:@"%@:%@", kImageTag, kImageInStreamName], + [NSString stringWithFormat:@"%@:%@", kNormRectTag, kNormRectStreamName] + ] + outputStreams:@[ + [NSString stringWithFormat:@"%@:%@", kDetectionsTag, kDetectionsStreamName], + [NSString stringWithFormat:@"%@:%@", kImageTag, kImageOutStreamName] + ] + taskOptions:options + enableFlowLimiting:options.runningMode == MPPRunningModeLiveStream + error:error]; + + if (!taskInfo) { + return nil; + } + + PacketsCallback packetsCallback = nullptr; + + if (options.faceDetectorLiveStreamDelegate) { + _faceDetectorLiveStreamDelegate = options.faceDetectorLiveStreamDelegate; + + // Create a private serial dispatch queue in which the delegate method will be called + // asynchronously. This is to ensure that if the client performs a long running operation in + // the delegate method, the queue on which the C++ callbacks is invoked is not blocked and is + // freed up to continue with its operations. + _callbackQueue = dispatch_queue_create( + [MPPVisionTaskRunner uniqueDispatchQueueNameWithSuffix:kTaskName], NULL); + + // Capturing `self` as weak in order to avoid `self` being kept in memory + // and cause a retain cycle, after self is set to `nil`. + MPPFaceDetector *__weak weakSelf = self; + packetsCallback = [=](absl::StatusOr liveStreamResult) { + [weakSelf processLiveStreamResult:liveStreamResult]; + }; + } + + _visionTaskRunner = + [[MPPVisionTaskRunner alloc] initWithCalculatorGraphConfig:[taskInfo generateGraphConfig] + runningMode:options.runningMode + packetsCallback:std::move(packetsCallback) + error:error]; + + if (!_visionTaskRunner) { + return nil; + } + } + + return self; +} + +- (instancetype)initWithModelPath:(NSString *)modelPath error:(NSError **)error { + MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init]; + + options.baseOptions.modelAssetPath = modelPath; + + return [self initWithOptions:options error:error]; +} + +- (std::optional)inputPacketMapWithMPPImage:(MPPImage *)image + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(NSError **)error { + std::optional rect = + [_visionTaskRunner normalizedRectFromRegionOfInterest:CGRectZero + imageSize:CGSizeMake(image.width, image.height) + imageOrientation:image.orientation + ROIAllowed:NO + error:error]; + if (!rect.has_value()) { + return std::nullopt; + } + + Packet imagePacket = [MPPVisionPacketCreator createPacketWithMPPImage:image + timestampInMilliseconds:timestampInMilliseconds + error:error]; + if (imagePacket.IsEmpty()) { + return std::nullopt; + } + + Packet normalizedRectPacket = + [MPPVisionPacketCreator createPacketWithNormalizedRect:rect.value() + timestampInMilliseconds:timestampInMilliseconds]; + + PacketMap inputPacketMap = InputPacketMap(imagePacket, normalizedRectPacket); + return inputPacketMap; +} + +- (nullable MPPFaceDetectorResult *)detectInImage:(MPPImage *)image error:(NSError **)error { + std::optional rect = + [_visionTaskRunner normalizedRectFromRegionOfInterest:CGRectZero + imageSize:CGSizeMake(image.width, image.height) + imageOrientation:image.orientation + ROIAllowed:NO + error:error]; + if (!rect.has_value()) { + return nil; + } + + Packet imagePacket = [MPPVisionPacketCreator createPacketWithMPPImage:image error:error]; + if (imagePacket.IsEmpty()) { + return nil; + } + + Packet normalizedRectPacket = + [MPPVisionPacketCreator createPacketWithNormalizedRect:rect.value()]; + + PacketMap inputPacketMap = InputPacketMap(imagePacket, normalizedRectPacket); + + std::optional outputPacketMap = [_visionTaskRunner processImagePacketMap:inputPacketMap + error:error]; + if (!outputPacketMap.has_value()) { + return nil; + } + + return [MPPFaceDetectorResult + faceDetectorResultWithDetectionsPacket:outputPacketMap + .value()[kDetectionsStreamName.cppString]]; +} + +- (nullable MPPFaceDetectorResult *)detectInVideoFrame:(MPPImage *)image + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(NSError **)error { + std::optional inputPacketMap = [self inputPacketMapWithMPPImage:image + timestampInMilliseconds:timestampInMilliseconds + error:error]; + if (!inputPacketMap.has_value()) { + return nil; + } + + std::optional outputPacketMap = + [_visionTaskRunner processVideoFramePacketMap:inputPacketMap.value() error:error]; + + if (!outputPacketMap.has_value()) { + return nil; + } + + return [MPPFaceDetectorResult + faceDetectorResultWithDetectionsPacket:outputPacketMap + .value()[kDetectionsStreamName.cppString]]; +} + +- (BOOL)detectAsyncInImage:(MPPImage *)image + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(NSError **)error { + std::optional inputPacketMap = [self inputPacketMapWithMPPImage:image + timestampInMilliseconds:timestampInMilliseconds + error:error]; + if (!inputPacketMap.has_value()) { + return NO; + } + + return [_visionTaskRunner processLiveStreamPacketMap:inputPacketMap.value() error:error]; +} + +- (void)processLiveStreamResult:(absl::StatusOr)liveStreamResult { + if (![self.faceDetectorLiveStreamDelegate + respondsToSelector:@selector(faceDetector: + didFinishDetectionWithResult:timestampInMilliseconds:error:)]) { + return; + } + NSError *callbackError = nil; + if (![MPPCommonUtils checkCppError:liveStreamResult.status() toError:&callbackError]) { + dispatch_async(_callbackQueue, ^{ + [self.faceDetectorLiveStreamDelegate faceDetector:self + didFinishDetectionWithResult:nil + timestampInMilliseconds:Timestamp::Unset().Value() + error:callbackError]; + }); + return; + } + + PacketMap &outputPacketMap = liveStreamResult.value(); + if (outputPacketMap[kImageOutStreamName.cppString].IsEmpty()) { + return; + } + + MPPFaceDetectorResult *result = [MPPFaceDetectorResult + faceDetectorResultWithDetectionsPacket:liveStreamResult + .value()[kDetectionsStreamName.cppString]]; + + NSInteger timeStampInMilliseconds = + outputPacketMap[kImageOutStreamName.cppString].Timestamp().Value() / + kMicrosecondsPerMillisecond; + dispatch_async(_callbackQueue, ^{ + [self.faceDetectorLiveStreamDelegate faceDetector:self + didFinishDetectionWithResult:result + timestampInMilliseconds:timeStampInMilliseconds + error:callbackError]; + }); +} + +@end diff --git a/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorOptions.h b/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorOptions.h new file mode 100644 index 000000000..b5d652683 --- /dev/null +++ b/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorOptions.h @@ -0,0 +1,101 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +#import "mediapipe/tasks/ios/core/sources/MPPTaskOptions.h" +#import "mediapipe/tasks/ios/vision/core/sources/MPPRunningMode.h" +#import "mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.h" + +NS_ASSUME_NONNULL_BEGIN + +@class MPPFaceDetector; + +/** + * This protocol defines an interface for the delegates of `MPPFaceDetector` face to receive + * results of performing asynchronous face detection on images (i.e, when `runningMode` = + * `MPPRunningModeLiveStream`). + * + * The delegate of `MPPFaceDetector` must adopt `MPPFaceDetectorLiveStreamDelegate` protocol. + * The methods in this protocol are optional. + */ +NS_SWIFT_NAME(FaceDetectorLiveStreamDelegate) +@protocol MPPFaceDetectorLiveStreamDelegate + +@optional + +/** + * This method notifies a delegate that the results of asynchronous face detection of + * an image submitted to the `MPPFaceDetector` is available. + * + * This method is called on a private serial dispatch queue created by the `MPPFaceDetector` + * for performing the asynchronous delegates calls. + * + * @param faceDetector The face detector which performed the face detection. + * This is useful to test equality when there are multiple instances of `MPPFaceDetector`. + * @param result The `MPPFaceDetectorResult` object that contains a list of detections, each + * detection has a bounding box that is expressed in the unrotated input frame of reference + * coordinates system, i.e. in `[0,image_width) x [0,image_height)`, which are the dimensions of the + * underlying image data. + * @param timestampInMilliseconds The timestamp (in milliseconds) which indicates when the input + * image was sent to the face detector. + * @param error An optional error parameter populated when there is an error in performing face + * detection on the input live stream image data. + */ +- (void)faceDetector:(MPPFaceDetector *)faceDetector + didFinishDetectionWithResult:(nullable MPPFaceDetectorResult *)result + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(nullable NSError *)error + NS_SWIFT_NAME(faceDetector(_:didFinishDetection:timestampInMilliseconds:error:)); +@end + +/** Options for setting up a `MPPFaceDetector`. */ +NS_SWIFT_NAME(FaceDetectorOptions) +@interface MPPFaceDetectorOptions : MPPTaskOptions + +/** + * Running mode of the face detector task. Defaults to `MPPRunningModeImage`. + * `MPPFaceDetector` can be created with one of the following running modes: + * 1. `MPPRunningModeImage`: The mode for performing face detection on single image inputs. + * 2. `MPPRunningModeVideo`: The mode for performing face detection on the decoded frames of a + * video. + * 3. `MPPRunningModeLiveStream`: The mode for performing face detection on a live stream of + * input data, such as from the camera. + */ +@property(nonatomic) MPPRunningMode runningMode; + +/** + * An object that confirms to `MPPFaceDetectorLiveStreamDelegate` protocol. This object must + * implement `faceDetector:didFinishDetectionWithResult:timestampInMilliseconds:error:` to receive + * the results of performing asynchronous face detection on images (i.e, when `runningMode` = + * `MPPRunningModeLiveStream`). + */ +@property(nonatomic, weak, nullable) id + faceDetectorLiveStreamDelegate; + +/** + * The minimum confidence score for the face detection to be considered successful. Defaults to + * 0.5. + */ +@property(nonatomic) float minDetectionConfidence; + +/** + * The minimum non-maximum-suppression threshold for face detection to be considered overlapped. + * Defaults to 0.3. + */ +@property(nonatomic) float minSuppressionThreshold; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorOptions.m b/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorOptions.m new file mode 100644 index 000000000..7d990aa69 --- /dev/null +++ b/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorOptions.m @@ -0,0 +1,38 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorOptions.h" + +@implementation MPPFaceDetectorOptions + +- (instancetype)init { + self = [super init]; + if (self) { + _minDetectionConfidence = 0.5; + _minSuppressionThreshold = 0.3; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + MPPFaceDetectorOptions *faceDetectorOptions = [super copyWithZone:zone]; + + faceDetectorOptions.minDetectionConfidence = self.minDetectionConfidence; + faceDetectorOptions.minSuppressionThreshold = self.minSuppressionThreshold; + faceDetectorOptions.faceDetectorLiveStreamDelegate = self.faceDetectorLiveStreamDelegate; + + return faceDetectorOptions; +} + +@end diff --git a/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.h b/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.h new file mode 100644 index 000000000..67a9082af --- /dev/null +++ b/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.h @@ -0,0 +1,49 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import +#import "mediapipe/tasks/ios/components/containers/sources/MPPDetection.h" +#import "mediapipe/tasks/ios/core/sources/MPPTaskResult.h" + +NS_ASSUME_NONNULL_BEGIN + +/** Represents the detection results generated by `MPPFaceDetector`. */ +NS_SWIFT_NAME(FaceDetectorResult) +@interface MPPFaceDetectorResult : MPPTaskResult + +/** + * The array of `MPPDetection` objects each of which has a bounding box that is expressed in the + * unrotated input frame of reference coordinates system, i.e. in `[0,image_width) x + * [0,image_height)`, which are the dimensions of the underlying image data. + */ +@property(nonatomic, readonly) NSArray *detections; + +/** + * Initializes a new `MPPFaceDetectorResult` with the given array of detections and timestamp (in + * milliseconds). + * + * @param detections An array of `MPPDetection` objects each of which has a bounding box that is + * expressed in the unrotated input frame of reference coordinates system, i.e. in `[0,image_width) + * x [0,image_height)`, which are the dimensions of the underlying image data. + * @param timestampInMilliseconds The timestamp (in milliseconds) for this result. + * + * @return An instance of `MPPFaceDetectorResult` initialized with the given array of detections + * and timestamp (in milliseconds). + */ +- (instancetype)initWithDetections:(NSArray *)detections + timestampInMilliseconds:(NSInteger)timestampInMilliseconds; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.m b/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.m new file mode 100644 index 000000000..e6ec7fabe --- /dev/null +++ b/mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.m @@ -0,0 +1,28 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.h" + +@implementation MPPFaceDetectorResult + +- (instancetype)initWithDetections:(NSArray *)detections + timestampInMilliseconds:(NSInteger)timestampInMilliseconds { + self = [super initWithTimestampInMilliseconds:timestampInMilliseconds]; + if (self) { + _detections = [detections copy]; + } + return self; +} + +@end diff --git a/mediapipe/tasks/ios/vision/face_detector/utils/BUILD b/mediapipe/tasks/ios/vision/face_detector/utils/BUILD new file mode 100644 index 000000000..2659fcca6 --- /dev/null +++ b/mediapipe/tasks/ios/vision/face_detector/utils/BUILD @@ -0,0 +1,42 @@ +# 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. + +package(default_visibility = ["//mediapipe/tasks:internal"]) + +licenses(["notice"]) + +objc_library( + name = "MPPFaceDetectorOptionsHelpers", + srcs = ["sources/MPPFaceDetectorOptions+Helpers.mm"], + hdrs = ["sources/MPPFaceDetectorOptions+Helpers.h"], + deps = [ + "//mediapipe/framework:calculator_options_cc_proto", + "//mediapipe/tasks/cc/vision/face_detector/proto:face_detector_graph_options_cc_proto", + "//mediapipe/tasks/ios/common/utils:NSStringHelpers", + "//mediapipe/tasks/ios/core:MPPTaskOptionsProtocol", + "//mediapipe/tasks/ios/core/utils:MPPBaseOptionsHelpers", + "//mediapipe/tasks/ios/vision/face_detector:MPPFaceDetectorOptions", + ], +) + +objc_library( + name = "MPPFaceDetectorResultHelpers", + srcs = ["sources/MPPFaceDetectorResult+Helpers.mm"], + hdrs = ["sources/MPPFaceDetectorResult+Helpers.h"], + deps = [ + "//mediapipe/framework:packet", + "//mediapipe/tasks/ios/components/containers/utils:MPPDetectionHelpers", + "//mediapipe/tasks/ios/vision/face_detector:MPPFaceDetectorResult", + ], +) diff --git a/mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorOptions+Helpers.h b/mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorOptions+Helpers.h new file mode 100644 index 000000000..16be4a3f1 --- /dev/null +++ b/mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorOptions+Helpers.h @@ -0,0 +1,36 @@ +// 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 __cplusplus +#error "This file requires Objective-C++." +#endif // __cplusplus + +#include "mediapipe/framework/calculator_options.pb.h" +#import "mediapipe/tasks/ios/core/sources/MPPTaskOptionsProtocol.h" +#import "mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorOptions.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MPPFaceDetectorOptions (Helpers) + +/** + * Populates the provided `CalculatorOptions` proto container with the current settings. + * + * @param optionsProto The `CalculatorOptions` proto object to copy the settings to. + */ +- (void)copyToProto:(::mediapipe::CalculatorOptions *)optionsProto; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorOptions+Helpers.mm b/mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorOptions+Helpers.mm new file mode 100644 index 000000000..50335c8e5 --- /dev/null +++ b/mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorOptions+Helpers.mm @@ -0,0 +1,39 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorOptions+Helpers.h" + +#import "mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h" +#import "mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.h" + +#include "mediapipe/tasks/cc/vision/face_detector/proto/face_detector_graph_options.pb.h" + +using CalculatorOptionsProto = ::mediapipe::CalculatorOptions; +using FaceDetectorGraphOptionsProto = + ::mediapipe::tasks::vision::face_detector::proto::FaceDetectorGraphOptions; + +@implementation MPPFaceDetectorOptions (Helpers) + +- (void)copyToProto:(CalculatorOptionsProto *)optionsProto { + FaceDetectorGraphOptionsProto *graphOptions = + optionsProto->MutableExtension(FaceDetectorGraphOptionsProto::ext); + + graphOptions->Clear(); + + [self.baseOptions copyToProto:graphOptions->mutable_base_options()]; + graphOptions->set_min_detection_confidence(self.minDetectionConfidence); + graphOptions->set_min_suppression_threshold(self.minSuppressionThreshold); +} + +@end diff --git a/mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorResult+Helpers.h b/mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorResult+Helpers.h new file mode 100644 index 000000000..8e077d393 --- /dev/null +++ b/mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorResult+Helpers.h @@ -0,0 +1,39 @@ +// 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 __cplusplus +#error "This file requires Objective-C++." +#endif // __cplusplus + +#include "mediapipe/framework/packet.h" +#import "mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MPPFaceDetectorResult (Helpers) + +/** + * Creates an `MPPFaceDetectorResult` from a MediaPipe packet containing a + * `std::vector`. + * + * @param packet a MediaPipe packet wrapping a `std::vector`. + * + * @return An `MPPFaceDetectorResult` object that contains a list of detections. + */ ++ (nullable MPPFaceDetectorResult *)faceDetectorResultWithDetectionsPacket: + (const ::mediapipe::Packet &)packet; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorResult+Helpers.mm b/mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorResult+Helpers.mm new file mode 100644 index 000000000..67fb20937 --- /dev/null +++ b/mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorResult+Helpers.mm @@ -0,0 +1,45 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "mediapipe/tasks/ios/vision/face_detector/utils/sources/MPPFaceDetectorResult+Helpers.h" + +#import "mediapipe/tasks/ios/components/containers/utils/sources/MPPDetection+Helpers.h" + +using DetectionProto = ::mediapipe::Detection; +using ::mediapipe::Packet; + +static constexpr int kMicrosecondsPerMillisecond = 1000; + +@implementation MPPFaceDetectorResult (Helpers) + ++ (nullable MPPFaceDetectorResult *)faceDetectorResultWithDetectionsPacket:(const Packet &)packet { + NSMutableArray *detections; + + if (packet.ValidateAsType>().ok()) { + const std::vector &detectionProtos = packet.Get>(); + detections = [NSMutableArray arrayWithCapacity:(NSUInteger)detectionProtos.size()]; + for (const auto &detectionProto : detectionProtos) { + [detections addObject:[MPPDetection detectionWithProto:detectionProto]]; + } + } else { + detections = [NSMutableArray arrayWithCapacity:0]; + } + + return + [[MPPFaceDetectorResult alloc] initWithDetections:detections + timestampInMilliseconds:(NSInteger)(packet.Timestamp().Value() / + kMicrosecondsPerMillisecond)]; +} + +@end From d9f316e12a1e59b6d9daa45c64431d29d8700310 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 24 May 2023 08:53:19 -0700 Subject: [PATCH 322/753] Rename ObjectDetctionResult to ObjectDetectorResult PiperOrigin-RevId: 534858600 --- .../com/google/mediapipe/tasks/vision/BUILD | 1 + .../objectdetector/ObjectDetectionResult.java | 22 ++++---- .../vision/objectdetector/ObjectDetector.java | 34 +++++++------ .../objectdetector/ObjectDetectorResult.java | 44 ++++++++++++++++ .../objectdetector/ObjectDetectorTest.java | 50 +++++++++++-------- 5 files changed, 104 insertions(+), 47 deletions(-) create mode 100644 mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorResult.java diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD index 399156da3..cbb1797e2 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/BUILD @@ -71,6 +71,7 @@ android_library( srcs = [ "objectdetector/ObjectDetectionResult.java", "objectdetector/ObjectDetector.java", + "objectdetector/ObjectDetectorResult.java", ], javacopts = [ "-Xep:AndroidJdkLibsChecker:OFF", diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectionResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectionResult.java index 120cddd46..49ab0ae2b 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectionResult.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectionResult.java @@ -14,15 +14,16 @@ package com.google.mediapipe.tasks.vision.objectdetector; -import com.google.auto.value.AutoValue; import com.google.mediapipe.tasks.core.TaskResult; import com.google.mediapipe.formats.proto.DetectionProto.Detection; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; -/** Represents the detection results generated by {@link ObjectDetector}. */ -@AutoValue +/** + * Represents the detection results generated by {@link ObjectDetector}. + * + * @deprecated Use {@link ObjectDetectorResult} instead. + */ +@Deprecated public abstract class ObjectDetectionResult implements TaskResult { @Override @@ -36,15 +37,10 @@ public abstract class ObjectDetectionResult implements TaskResult { * * @param detectionList a list of {@link DetectionOuterClass.Detection} protobuf messages. * @param timestampMs a timestamp for this result. + * @deprecated Use {@link ObjectDetectorResult#create} instead. */ + @Deprecated public static ObjectDetectionResult create(List detectionList, long timestampMs) { - List detections = new ArrayList<>(); - for (Detection detectionProto : detectionList) { - detections.add( - com.google.mediapipe.tasks.components.containers.Detection.createFromProto( - detectionProto)); - } - return new AutoValue_ObjectDetectionResult( - timestampMs, Collections.unmodifiableList(detections)); + return ObjectDetectorResult.create(detectionList, timestampMs); } } diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetector.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetector.java index d9a36cce7..0c70a119d 100644 --- a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetector.java +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetector.java @@ -99,11 +99,16 @@ public final class ObjectDetector extends BaseVisionTaskApi { private static final String TAG = ObjectDetector.class.getSimpleName(); private static final String IMAGE_IN_STREAM_NAME = "image_in"; private static final String NORM_RECT_IN_STREAM_NAME = "norm_rect_in"; + + @SuppressWarnings("ConstantCaseForConstants") private static final List INPUT_STREAMS = Collections.unmodifiableList( Arrays.asList("IMAGE:" + IMAGE_IN_STREAM_NAME, "NORM_RECT:" + NORM_RECT_IN_STREAM_NAME)); + + @SuppressWarnings("ConstantCaseForConstants") private static final List OUTPUT_STREAMS = Collections.unmodifiableList(Arrays.asList("DETECTIONS:detections_out", "IMAGE:image_out")); + private static final int DETECTIONS_OUT_STREAM_INDEX = 0; private static final int IMAGE_OUT_STREAM_INDEX = 1; private static final String TASK_GRAPH_NAME = "mediapipe.tasks.vision.ObjectDetectorGraph"; @@ -166,19 +171,19 @@ public final class ObjectDetector extends BaseVisionTaskApi { public static ObjectDetector createFromOptions( Context context, ObjectDetectorOptions detectorOptions) { // TODO: Consolidate OutputHandler and TaskRunner. - OutputHandler handler = new OutputHandler<>(); + OutputHandler handler = new OutputHandler<>(); handler.setOutputPacketConverter( - new OutputHandler.OutputPacketConverter() { + new OutputHandler.OutputPacketConverter() { @Override - public ObjectDetectionResult convertToTaskResult(List packets) { + public ObjectDetectorResult convertToTaskResult(List packets) { // If there is no object detected in the image, just returns empty lists. if (packets.get(DETECTIONS_OUT_STREAM_INDEX).isEmpty()) { - return ObjectDetectionResult.create( + return ObjectDetectorResult.create( new ArrayList<>(), BaseVisionTaskApi.generateResultTimestampMs( detectorOptions.runningMode(), packets.get(DETECTIONS_OUT_STREAM_INDEX))); } - return ObjectDetectionResult.create( + return ObjectDetectorResult.create( PacketGetter.getProtoVector( packets.get(DETECTIONS_OUT_STREAM_INDEX), Detection.parser()), BaseVisionTaskApi.generateResultTimestampMs( @@ -235,7 +240,7 @@ public final class ObjectDetector extends BaseVisionTaskApi { * @param image a MediaPipe {@link MPImage} object for processing. * @throws MediaPipeException if there is an internal error. */ - public ObjectDetectionResult detect(MPImage image) { + public ObjectDetectorResult detect(MPImage image) { return detect(image, ImageProcessingOptions.builder().build()); } @@ -258,10 +263,9 @@ public final class ObjectDetector extends BaseVisionTaskApi { * region-of-interest. * @throws MediaPipeException if there is an internal error. */ - public ObjectDetectionResult detect( - MPImage image, ImageProcessingOptions imageProcessingOptions) { + public ObjectDetectorResult detect(MPImage image, ImageProcessingOptions imageProcessingOptions) { validateImageProcessingOptions(imageProcessingOptions); - return (ObjectDetectionResult) processImageData(image, imageProcessingOptions); + return (ObjectDetectorResult) processImageData(image, imageProcessingOptions); } /** @@ -282,7 +286,7 @@ public final class ObjectDetector extends BaseVisionTaskApi { * @param timestampMs the input timestamp (in milliseconds). * @throws MediaPipeException if there is an internal error. */ - public ObjectDetectionResult detectForVideo(MPImage image, long timestampMs) { + public ObjectDetectorResult detectForVideo(MPImage image, long timestampMs) { return detectForVideo(image, ImageProcessingOptions.builder().build(), timestampMs); } @@ -309,10 +313,10 @@ public final class ObjectDetector extends BaseVisionTaskApi { * region-of-interest. * @throws MediaPipeException if there is an internal error. */ - public ObjectDetectionResult detectForVideo( + public ObjectDetectorResult detectForVideo( MPImage image, ImageProcessingOptions imageProcessingOptions, long timestampMs) { validateImageProcessingOptions(imageProcessingOptions); - return (ObjectDetectionResult) processVideoData(image, imageProcessingOptions, timestampMs); + return (ObjectDetectorResult) processVideoData(image, imageProcessingOptions, timestampMs); } /** @@ -435,7 +439,7 @@ public final class ObjectDetector extends BaseVisionTaskApi { * object detector is in the live stream mode. */ public abstract Builder setResultListener( - ResultListener value); + ResultListener value); /** Sets an optional {@link ErrorListener}}. */ public abstract Builder setErrorListener(ErrorListener value); @@ -476,11 +480,13 @@ public final class ObjectDetector extends BaseVisionTaskApi { abstract Optional scoreThreshold(); + @SuppressWarnings("AutoValueImmutableFields") abstract List categoryAllowlist(); + @SuppressWarnings("AutoValueImmutableFields") abstract List categoryDenylist(); - abstract Optional> resultListener(); + abstract Optional> resultListener(); abstract Optional errorListener(); diff --git a/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorResult.java b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorResult.java new file mode 100644 index 000000000..a17dc90c0 --- /dev/null +++ b/mediapipe/tasks/java/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorResult.java @@ -0,0 +1,44 @@ +// 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.mediapipe.tasks.vision.objectdetector; + +import com.google.auto.value.AutoValue; +import com.google.mediapipe.formats.proto.DetectionProto.Detection; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** Represents the detection results generated by {@link ObjectDetector}. */ +@AutoValue +@SuppressWarnings("deprecation") +public abstract class ObjectDetectorResult extends ObjectDetectionResult { + /** + * Creates an {@link ObjectDetectorResult} instance from a list of {@link Detection} protobuf + * messages. + * + * @param detectionList a list of {@link DetectionOuterClass.Detection} protobuf messages. + * @param timestampMs a timestamp for this result. + */ + public static ObjectDetectorResult create(List detectionList, long timestampMs) { + List detections = new ArrayList<>(); + for (Detection detectionProto : detectionList) { + detections.add( + com.google.mediapipe.tasks.components.containers.Detection.createFromProto( + detectionProto)); + } + return new AutoValue_ObjectDetectorResult( + timestampMs, Collections.unmodifiableList(detections)); + } +} diff --git a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorTest.java b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorTest.java index 20ddfcef6..fb83723c5 100644 --- a/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorTest.java +++ b/mediapipe/tasks/javatests/com/google/mediapipe/tasks/vision/objectdetector/ObjectDetectorTest.java @@ -69,7 +69,7 @@ public class ObjectDetectorTest { .build(); ObjectDetector objectDetector = ObjectDetector.createFromOptions(ApplicationProvider.getApplicationContext(), options); - ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + ObjectDetectorResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); assertContainsOnlyCat(results, CAT_BOUNDING_BOX, CAT_SCORE); } @@ -77,7 +77,7 @@ public class ObjectDetectorTest { public void detect_successWithNoOptions() throws Exception { ObjectDetector objectDetector = ObjectDetector.createFromFile(ApplicationProvider.getApplicationContext(), MODEL_FILE); - ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + ObjectDetectorResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); // Check if the object with the highest score is cat. assertIsCat(results.detections().get(0).categories().get(0), CAT_SCORE); } @@ -91,7 +91,7 @@ public class ObjectDetectorTest { .build(); ObjectDetector objectDetector = ObjectDetector.createFromOptions(ApplicationProvider.getApplicationContext(), options); - ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + ObjectDetectorResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); // results should have 8 detected objects because maxResults was set to 8. assertThat(results.detections()).hasSize(8); } @@ -105,7 +105,7 @@ public class ObjectDetectorTest { .build(); ObjectDetector objectDetector = ObjectDetector.createFromOptions(ApplicationProvider.getApplicationContext(), options); - ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + ObjectDetectorResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); // The score threshold should block all other other objects, except cat. assertContainsOnlyCat(results, CAT_BOUNDING_BOX, CAT_SCORE); } @@ -119,7 +119,7 @@ public class ObjectDetectorTest { .build(); ObjectDetector objectDetector = ObjectDetector.createFromOptions(ApplicationProvider.getApplicationContext(), options); - ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + ObjectDetectorResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); // The score threshold should block objects. assertThat(results.detections()).isEmpty(); } @@ -133,7 +133,7 @@ public class ObjectDetectorTest { .build(); ObjectDetector objectDetector = ObjectDetector.createFromOptions(ApplicationProvider.getApplicationContext(), options); - ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + ObjectDetectorResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); // Because of the allowlist, results should only contain cat, and there are 6 detected // bounding boxes of cats in CAT_AND_DOG_IMAGE. assertThat(results.detections()).hasSize(5); @@ -148,7 +148,7 @@ public class ObjectDetectorTest { .build(); ObjectDetector objectDetector = ObjectDetector.createFromOptions(ApplicationProvider.getApplicationContext(), options); - ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + ObjectDetectorResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); // Because of the denylist, the highest result is not cat anymore. assertThat(results.detections().get(0).categories().get(0).categoryName()) .isNotEqualTo("cat"); @@ -160,7 +160,7 @@ public class ObjectDetectorTest { ObjectDetector.createFromFile( ApplicationProvider.getApplicationContext(), TestUtils.loadFile(ApplicationProvider.getApplicationContext(), MODEL_FILE)); - ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + ObjectDetectorResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); // Check if the object with the highest score is cat. assertIsCat(results.detections().get(0).categories().get(0), CAT_SCORE); } @@ -172,7 +172,7 @@ public class ObjectDetectorTest { ApplicationProvider.getApplicationContext(), TestUtils.loadToDirectByteBuffer( ApplicationProvider.getApplicationContext(), MODEL_FILE)); - ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + ObjectDetectorResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); // Check if the object with the highest score is cat. assertIsCat(results.detections().get(0).categories().get(0), CAT_SCORE); } @@ -191,7 +191,7 @@ public class ObjectDetectorTest { .build(); ObjectDetector objectDetector = ObjectDetector.createFromOptions(ApplicationProvider.getApplicationContext(), options); - ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + ObjectDetectorResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); assertContainsOnlyCat(results, CAT_BOUNDING_BOX, CAT_SCORE); } @@ -256,7 +256,7 @@ public class ObjectDetectorTest { ObjectDetector.createFromOptions(ApplicationProvider.getApplicationContext(), options); ImageProcessingOptions imageProcessingOptions = ImageProcessingOptions.builder().setRotationDegrees(-90).build(); - ObjectDetectionResult results = + ObjectDetectorResult results = objectDetector.detect( getImageFromAsset(CAT_AND_DOG_ROTATED_IMAGE), imageProcessingOptions); @@ -302,7 +302,7 @@ public class ObjectDetectorTest { ObjectDetectorOptions.builder() .setBaseOptions(BaseOptions.builder().setModelAssetPath(MODEL_FILE).build()) .setRunningMode(mode) - .setResultListener((objectDetectionResult, inputImage) -> {}) + .setResultListener((ObjectDetectorResult, inputImage) -> {}) .build()); assertThat(exception) .hasMessageThat() @@ -381,7 +381,7 @@ public class ObjectDetectorTest { ObjectDetectorOptions.builder() .setBaseOptions(BaseOptions.builder().setModelAssetPath(MODEL_FILE).build()) .setRunningMode(RunningMode.LIVE_STREAM) - .setResultListener((objectDetectionResult, inputImage) -> {}) + .setResultListener((ObjectDetectorResult, inputImage) -> {}) .build(); ObjectDetector objectDetector = @@ -411,7 +411,7 @@ public class ObjectDetectorTest { .build(); ObjectDetector objectDetector = ObjectDetector.createFromOptions(ApplicationProvider.getApplicationContext(), options); - ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + ObjectDetectorResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); assertContainsOnlyCat(results, CAT_BOUNDING_BOX, CAT_SCORE); } @@ -426,7 +426,7 @@ public class ObjectDetectorTest { ObjectDetector objectDetector = ObjectDetector.createFromOptions(ApplicationProvider.getApplicationContext(), options); for (int i = 0; i < 3; i++) { - ObjectDetectionResult results = + ObjectDetectorResult results = objectDetector.detectForVideo( getImageFromAsset(CAT_AND_DOG_IMAGE), /* timestampsMs= */ i); assertContainsOnlyCat(results, CAT_BOUNDING_BOX, CAT_SCORE); @@ -441,8 +441,8 @@ public class ObjectDetectorTest { .setBaseOptions(BaseOptions.builder().setModelAssetPath(MODEL_FILE).build()) .setRunningMode(RunningMode.LIVE_STREAM) .setResultListener( - (objectDetectionResult, inputImage) -> { - assertContainsOnlyCat(objectDetectionResult, CAT_BOUNDING_BOX, CAT_SCORE); + (ObjectDetectorResult, inputImage) -> { + assertContainsOnlyCat(ObjectDetectorResult, CAT_BOUNDING_BOX, CAT_SCORE); assertImageSizeIsExpected(inputImage); }) .setMaxResults(1) @@ -468,8 +468,8 @@ public class ObjectDetectorTest { .setBaseOptions(BaseOptions.builder().setModelAssetPath(MODEL_FILE).build()) .setRunningMode(RunningMode.LIVE_STREAM) .setResultListener( - (objectDetectionResult, inputImage) -> { - assertContainsOnlyCat(objectDetectionResult, CAT_BOUNDING_BOX, CAT_SCORE); + (ObjectDetectorResult, inputImage) -> { + assertContainsOnlyCat(ObjectDetectorResult, CAT_BOUNDING_BOX, CAT_SCORE); assertImageSizeIsExpected(inputImage); }) .setMaxResults(1) @@ -483,6 +483,16 @@ public class ObjectDetectorTest { } } + @Test + @SuppressWarnings("deprecation") + public void detect_canUseDeprecatedApi() throws Exception { + ObjectDetector objectDetector = + ObjectDetector.createFromFile(ApplicationProvider.getApplicationContext(), MODEL_FILE); + ObjectDetectionResult results = objectDetector.detect(getImageFromAsset(CAT_AND_DOG_IMAGE)); + // Check if the object with the highest score is cat. + assertIsCat(results.detections().get(0).categories().get(0), CAT_SCORE); + } + private static MPImage getImageFromAsset(String filePath) throws Exception { AssetManager assetManager = ApplicationProvider.getApplicationContext().getAssets(); InputStream istr = assetManager.open(filePath); @@ -491,7 +501,7 @@ public class ObjectDetectorTest { // Checks if results has one and only detection result, which is a cat. private static void assertContainsOnlyCat( - ObjectDetectionResult result, RectF expectedBoundingBox, float expectedScore) { + ObjectDetectorResult result, RectF expectedBoundingBox, float expectedScore) { assertThat(result.detections()).hasSize(1); Detection catResult = result.detections().get(0); assertApproximatelyEqualBoundingBoxes(catResult.boundingBox(), expectedBoundingBox); From acfaf3f1b6e1fcbd73ef6b0b4568e2c7b4dca15a Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 24 May 2023 09:37:45 -0700 Subject: [PATCH 323/753] Add unit test for FaceDetector iOS PiperOrigin-RevId: 534874603 --- .../tasks/ios/test/vision/face_detector/BUILD | 64 +++ .../face_detector/MPPFaceDetectorTests.mm | 522 ++++++++++++++++++ 2 files changed, 586 insertions(+) create mode 100644 mediapipe/tasks/ios/test/vision/face_detector/BUILD create mode 100644 mediapipe/tasks/ios/test/vision/face_detector/MPPFaceDetectorTests.mm diff --git a/mediapipe/tasks/ios/test/vision/face_detector/BUILD b/mediapipe/tasks/ios/test/vision/face_detector/BUILD new file mode 100644 index 000000000..49e2fe1bf --- /dev/null +++ b/mediapipe/tasks/ios/test/vision/face_detector/BUILD @@ -0,0 +1,64 @@ +load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test") +load( + "//mediapipe/framework/tool:ios.bzl", + "MPP_TASK_MINIMUM_OS_VERSION", +) +load( + "@org_tensorflow//tensorflow/lite:special_rules.bzl", + "tflite_ios_lab_runner", +) + +package(default_visibility = ["//mediapipe/tasks:internal"]) + +licenses(["notice"]) + +# Default tags for filtering iOS targets. Targets are restricted to Apple platforms. +TFL_DEFAULT_TAGS = [ + "apple", +] + +# Following sanitizer tests are not supported by iOS test targets. +TFL_DISABLED_SANITIZER_TAGS = [ + "noasan", + "nomsan", + "notsan", +] + +objc_library( + name = "MPPFaceDetectorObjcTestLibrary", + testonly = 1, + srcs = ["MPPFaceDetectorTests.mm"], + copts = [ + "-ObjC++", + "-std=c++17", + "-x objective-c++", + ], + data = [ + "//mediapipe/tasks/testdata/vision:test_images", + "//mediapipe/tasks/testdata/vision:test_models", + "//mediapipe/tasks/testdata/vision:test_protos", + ], + deps = [ + "//mediapipe/tasks/ios/common:MPPCommon", + "//mediapipe/tasks/ios/components/containers/utils:MPPDetectionHelpers", + "//mediapipe/tasks/ios/test/vision/utils:MPPImageTestUtils", + "//mediapipe/tasks/ios/vision/face_detector:MPPFaceDetector", + "//mediapipe/tasks/ios/vision/face_detector:MPPFaceDetectorResult", + "//third_party/apple_frameworks:UIKit", + ] + select({ + "//third_party:opencv_ios_sim_arm64_source_build": ["@ios_opencv_source//:opencv_xcframework"], + "//third_party:opencv_ios_arm64_source_build": ["@ios_opencv_source//:opencv_xcframework"], + "//third_party:opencv_ios_x86_64_source_build": ["@ios_opencv_source//:opencv_xcframework"], + "//conditions:default": ["@ios_opencv//:OpencvFramework"], + }), +) + +ios_unit_test( + name = "MPPFaceDetectorObjcTest", + minimum_os_version = MPP_TASK_MINIMUM_OS_VERSION, + runner = tflite_ios_lab_runner("IOS_LATEST"), + tags = TFL_DEFAULT_TAGS + TFL_DISABLED_SANITIZER_TAGS, + deps = [ + ":MPPFaceDetectorObjcTestLibrary", + ], +) diff --git a/mediapipe/tasks/ios/test/vision/face_detector/MPPFaceDetectorTests.mm b/mediapipe/tasks/ios/test/vision/face_detector/MPPFaceDetectorTests.mm new file mode 100644 index 000000000..ea0664409 --- /dev/null +++ b/mediapipe/tasks/ios/test/vision/face_detector/MPPFaceDetectorTests.mm @@ -0,0 +1,522 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import +#import +#import + +#import "mediapipe/tasks/ios/common/sources/MPPCommon.h" +#import "mediapipe/tasks/ios/components/containers/utils/sources/MPPDetection+Helpers.h" +#import "mediapipe/tasks/ios/test/vision/utils/sources/MPPImage+TestUtils.h" +#import "mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetector.h" +#import "mediapipe/tasks/ios/vision/face_detector/sources/MPPFaceDetectorResult.h" + +static NSDictionary *const kPortraitImage = + @{@"name" : @"portrait", @"type" : @"jpg", @"orientation" : @(UIImageOrientationUp)}; +static NSDictionary *const kPortraitRotatedImage = + @{@"name" : @"portrait_rotated", @"type" : @"jpg", @"orientation" : @(UIImageOrientationRight)}; +static NSDictionary *const kCatImage = @{@"name" : @"cat", @"type" : @"jpg"}; +static NSString *const kShortRangeBlazeFaceModel = @"face_detection_short_range"; +static NSArray *const kPortraitExpectedKeypoints = @[ + @[ @0.44416f, @0.17643f ], @[ @0.55514f, @0.17731f ], @[ @0.50467f, @0.22657f ], + @[ @0.50227f, @0.27199f ], @[ @0.36063f, @0.20143f ], @[ @0.60841f, @0.20409f ] +]; +static NSArray *const kPortraitRotatedExpectedKeypoints = @[ + @[ @0.82075f, @0.44679f ], @[ @0.81965f, @0.56261f ], @[ @0.76194f, @0.51719f ], + @[ @0.71993f, @0.51719f ], @[ @0.80700f, @0.36298f ], @[ @0.80882f, @0.61204f ] +]; +static NSString *const kExpectedErrorDomain = @"com.google.mediapipe.tasks"; +static NSString *const kLiveStreamTestsDictFaceDetectorKey = @"face_detector"; +static NSString *const kLiveStreamTestsDictExpectationKey = @"expectation"; + +static const float kKeypointErrorThreshold = 1e-2; + +#define AssertEqualErrors(error, expectedError) \ + XCTAssertNotNil(error); \ + XCTAssertEqualObjects(error.domain, expectedError.domain); \ + XCTAssertEqual(error.code, expectedError.code); \ + XCTAssertEqualObjects(error.localizedDescription, expectedError.localizedDescription) + +@interface MPPFaceDetectorTests : XCTestCase { + NSDictionary *liveStreamSucceedsTestDict; + NSDictionary *outOfOrderTimestampTestDict; +} +@end + +@implementation MPPFaceDetectorTests + +#pragma mark General Tests + +- (void)testCreateFaceDetectorWithMissingModelPathFails { + NSString *modelPath = [MPPFaceDetectorTests filePathWithName:@"" extension:@""]; + + NSError *error = nil; + MPPFaceDetector *faceDetector = [[MPPFaceDetector alloc] initWithModelPath:modelPath + error:&error]; + XCTAssertNil(faceDetector); + + NSError *expectedError = [NSError + errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : + @"INVALID_ARGUMENT: ExternalFile must specify at least one of 'file_content', " + @"'file_name', 'file_pointer_meta' or 'file_descriptor_meta'." + }]; + AssertEqualErrors(error, expectedError); +} + +#pragma mark Image Mode Tests + +- (void)testDetectWithImageModeAndPotraitSucceeds { + NSString *modelPath = [MPPFaceDetectorTests filePathWithName:kShortRangeBlazeFaceModel + extension:@"tflite"]; + MPPFaceDetector *faceDetector = [[MPPFaceDetector alloc] initWithModelPath:modelPath error:nil]; + + [self assertResultsOfDetectInImageWithFileInfo:kPortraitImage + usingFaceDetector:faceDetector + containsExpectedKeypoints:kPortraitExpectedKeypoints]; +} + +- (void)testDetectWithImageModeAndRotatedPotraitSucceeds { + NSString *modelPath = [MPPFaceDetectorTests filePathWithName:kShortRangeBlazeFaceModel + extension:@"tflite"]; + MPPFaceDetector *faceDetector = [[MPPFaceDetector alloc] initWithModelPath:modelPath error:nil]; + XCTAssertNotNil(faceDetector); + + MPPImage *image = [self imageWithFileInfo:kPortraitRotatedImage]; + [self assertResultsOfDetectInImage:image + usingFaceDetector:faceDetector + containsExpectedKeypoints:kPortraitRotatedExpectedKeypoints]; +} + +- (void)testDetectWithImageModeAndNoFaceSucceeds { + NSString *modelPath = [MPPFaceDetectorTests filePathWithName:kShortRangeBlazeFaceModel + extension:@"tflite"]; + MPPFaceDetector *faceDetector = [[MPPFaceDetector alloc] initWithModelPath:modelPath error:nil]; + XCTAssertNotNil(faceDetector); + + NSError *error; + MPPImage *mppImage = [self imageWithFileInfo:kCatImage]; + MPPFaceDetectorResult *faceDetectorResult = [faceDetector detectInImage:mppImage error:&error]; + XCTAssertNil(error); + XCTAssertNotNil(faceDetectorResult); + XCTAssertEqual(faceDetectorResult.detections.count, 0); +} + +#pragma mark Video Mode Tests + +- (void)testDetectWithVideoModeAndPotraitSucceeds { + MPPFaceDetectorOptions *options = + [self faceDetectorOptionsWithModelName:kShortRangeBlazeFaceModel]; + options.runningMode = MPPRunningModeVideo; + MPPFaceDetector *faceDetector = [self faceDetectorWithOptionsSucceeds:options]; + + MPPImage *image = [self imageWithFileInfo:kPortraitImage]; + for (int i = 0; i < 3; i++) { + MPPFaceDetectorResult *faceDetectorResult = [faceDetector detectInVideoFrame:image + timestampInMilliseconds:i + error:nil]; + [self assertFaceDetectorResult:faceDetectorResult + containsExpectedKeypoints:kPortraitExpectedKeypoints]; + } +} + +- (void)testDetectWithVideoModeAndRotatedPotraitSucceeds { + MPPFaceDetectorOptions *options = + [self faceDetectorOptionsWithModelName:kShortRangeBlazeFaceModel]; + options.runningMode = MPPRunningModeVideo; + MPPFaceDetector *faceDetector = [self faceDetectorWithOptionsSucceeds:options]; + + MPPImage *image = [self imageWithFileInfo:kPortraitRotatedImage]; + for (int i = 0; i < 3; i++) { + MPPFaceDetectorResult *faceDetectorResult = [faceDetector detectInVideoFrame:image + timestampInMilliseconds:i + error:nil]; + [self assertFaceDetectorResult:faceDetectorResult + containsExpectedKeypoints:kPortraitRotatedExpectedKeypoints]; + } +} + +#pragma mark Live Stream Mode Tests + +- (void)testDetectWithLiveStreamModeAndPotraitSucceeds { + NSInteger iterationCount = 100; + + // Because of flow limiting, the callback might be invoked fewer than `iterationCount` times. An + // normal expectation will fail if expectation.fullfill() is not called + // `expectation.expectedFulfillmentCount` times. If `expectation.isInverted = true`, the test will + // only succeed if expectation is not fullfilled for the specified `expectedFulfillmentCount`. + // Since it is not possible to predict how many times the expectation is supposed to be + // fullfilled, `expectation.expectedFulfillmentCount` = `iterationCount` + 1 and + // `expectation.isInverted = true` ensures that test succeeds if expectation is fullfilled <= + // `iterationCount` times. + XCTestExpectation *expectation = [[XCTestExpectation alloc] + initWithDescription:@"detectWithOutOfOrderTimestampsAndLiveStream"]; + expectation.expectedFulfillmentCount = iterationCount + 1; + expectation.inverted = YES; + + MPPFaceDetectorOptions *options = + [self faceDetectorOptionsWithModelName:kShortRangeBlazeFaceModel]; + options.runningMode = MPPRunningModeLiveStream; + options.faceDetectorLiveStreamDelegate = self; + + MPPFaceDetector *faceDetector = [self faceDetectorWithOptionsSucceeds:options]; + MPPImage *image = [self imageWithFileInfo:kPortraitImage]; + + liveStreamSucceedsTestDict = @{ + kLiveStreamTestsDictFaceDetectorKey : faceDetector, + kLiveStreamTestsDictExpectationKey : expectation + }; + + for (int i = 0; i < iterationCount; i++) { + XCTAssertTrue([faceDetector detectAsyncInImage:image timestampInMilliseconds:i error:nil]); + } + + NSTimeInterval timeout = 0.5f; + [self waitForExpectations:@[ expectation ] timeout:timeout]; +} + +- (void)testDetectWithOutOfOrderTimestampsAndLiveStreamModeFails { + MPPFaceDetectorOptions *options = + [self faceDetectorOptionsWithModelName:kShortRangeBlazeFaceModel]; + options.runningMode = MPPRunningModeLiveStream; + options.faceDetectorLiveStreamDelegate = self; + + XCTestExpectation *expectation = [[XCTestExpectation alloc] + initWithDescription:@"detectWithOutOfOrderTimestampsAndLiveStream"]; + expectation.expectedFulfillmentCount = 1; + + MPPFaceDetector *faceDetector = [self faceDetectorWithOptionsSucceeds:options]; + liveStreamSucceedsTestDict = @{ + kLiveStreamTestsDictFaceDetectorKey : faceDetector, + kLiveStreamTestsDictExpectationKey : expectation + }; + + MPPImage *image = [self imageWithFileInfo:kPortraitImage]; + XCTAssertTrue([faceDetector detectAsyncInImage:image timestampInMilliseconds:1 error:nil]); + + NSError *error; + XCTAssertFalse([faceDetector detectAsyncInImage:image timestampInMilliseconds:0 error:&error]); + + NSError *expectedError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : + @"INVALID_ARGUMENT: Input timestamp must be monotonically increasing." + }]; + AssertEqualErrors(error, expectedError); + + NSTimeInterval timeout = 0.5f; + [self waitForExpectations:@[ expectation ] timeout:timeout]; +} + +#pragma mark Running Mode Tests + +- (void)testCreateFaceDetectorFailsWithDelegateInNonLiveStreamMode { + MPPRunningMode runningModesToTest[] = {MPPRunningModeImage, MPPRunningModeVideo}; + for (int i = 0; i < sizeof(runningModesToTest) / sizeof(runningModesToTest[0]); i++) { + MPPFaceDetectorOptions *options = + [self faceDetectorOptionsWithModelName:kShortRangeBlazeFaceModel]; + + options.runningMode = runningModesToTest[i]; + options.faceDetectorLiveStreamDelegate = self; + + [self assertCreateFaceDetectorWithOptions:options + failsWithExpectedError: + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : + @"The vision task is in image or video mode. The " + @"delegate must not be set in the task's options." + }]]; + } +} + +- (void)testCreateFaceDetectorFailsWithMissingDelegateInLiveStreamMode { + MPPFaceDetectorOptions *options = + [self faceDetectorOptionsWithModelName:kShortRangeBlazeFaceModel]; + + options.runningMode = MPPRunningModeLiveStream; + + [self assertCreateFaceDetectorWithOptions:options + failsWithExpectedError: + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : + @"The vision task is in live stream mode. An " + @"object must be set as the delegate of the task " + @"in its options to ensure asynchronous delivery " + @"of results." + }]]; +} + +- (void)testDetectFailsWithCallingWrongApiInImageMode { + MPPFaceDetectorOptions *options = + [self faceDetectorOptionsWithModelName:kShortRangeBlazeFaceModel]; + + MPPFaceDetector *faceDetector = [self faceDetectorWithOptionsSucceeds:options]; + + MPPImage *image = [self imageWithFileInfo:kPortraitImage]; + + NSError *liveStreamApiCallError; + XCTAssertFalse([faceDetector detectAsyncInImage:image + timestampInMilliseconds:0 + error:&liveStreamApiCallError]); + + NSError *expectedLiveStreamApiCallError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : @"The vision task is not initialized with live " + @"stream mode. Current Running Mode: Image" + }]; + AssertEqualErrors(liveStreamApiCallError, expectedLiveStreamApiCallError); + + NSError *videoApiCallError; + XCTAssertFalse([faceDetector detectInVideoFrame:image + timestampInMilliseconds:0 + error:&videoApiCallError]); + + NSError *expectedVideoApiCallError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : @"The vision task is not initialized with " + @"video mode. Current Running Mode: Image" + }]; + AssertEqualErrors(videoApiCallError, expectedVideoApiCallError); +} + +- (void)testDetectFailsWithCallingWrongApiInVideoMode { + MPPFaceDetectorOptions *options = + [self faceDetectorOptionsWithModelName:kShortRangeBlazeFaceModel]; + options.runningMode = MPPRunningModeVideo; + + MPPFaceDetector *faceDetector = [self faceDetectorWithOptionsSucceeds:options]; + + MPPImage *image = [self imageWithFileInfo:kPortraitImage]; + + NSError *liveStreamApiCallError; + XCTAssertFalse([faceDetector detectAsyncInImage:image + timestampInMilliseconds:0 + error:&liveStreamApiCallError]); + + NSError *expectedLiveStreamApiCallError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : @"The vision task is not initialized with live " + @"stream mode. Current Running Mode: Video" + }]; + AssertEqualErrors(liveStreamApiCallError, expectedLiveStreamApiCallError); + + NSError *imageApiCallError; + XCTAssertFalse([faceDetector detectInImage:image error:&imageApiCallError]); + + NSError *expectedImageApiCallError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : @"The vision task is not initialized with " + @"image mode. Current Running Mode: Video" + }]; + AssertEqualErrors(imageApiCallError, expectedImageApiCallError); +} + +- (void)testDetectFailsWithCallingWrongApiInLiveStreamMode { + MPPFaceDetectorOptions *options = + [self faceDetectorOptionsWithModelName:kShortRangeBlazeFaceModel]; + + options.runningMode = MPPRunningModeLiveStream; + options.faceDetectorLiveStreamDelegate = self; + + MPPFaceDetector *faceDetector = [self faceDetectorWithOptionsSucceeds:options]; + + MPPImage *image = [self imageWithFileInfo:kPortraitImage]; + + NSError *imageApiCallError; + XCTAssertFalse([faceDetector detectInImage:image error:&imageApiCallError]); + + NSError *expectedImageApiCallError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : @"The vision task is not initialized with " + @"image mode. Current Running Mode: Live Stream" + }]; + AssertEqualErrors(imageApiCallError, expectedImageApiCallError); + + NSError *videoApiCallError; + XCTAssertFalse([faceDetector detectInVideoFrame:image + timestampInMilliseconds:0 + error:&videoApiCallError]); + + NSError *expectedVideoApiCallError = + [NSError errorWithDomain:kExpectedErrorDomain + code:MPPTasksErrorCodeInvalidArgumentError + userInfo:@{ + NSLocalizedDescriptionKey : @"The vision task is not initialized with " + @"video mode. Current Running Mode: Live Stream" + }]; + AssertEqualErrors(videoApiCallError, expectedVideoApiCallError); +} + +- (void)testDetectWithLiveStreamModeSucceeds { + MPPFaceDetectorOptions *options = + [self faceDetectorOptionsWithModelName:kShortRangeBlazeFaceModel]; + options.runningMode = MPPRunningModeLiveStream; + options.faceDetectorLiveStreamDelegate = self; + + NSInteger iterationCount = 100; + + // Because of flow limiting, the callback might be invoked fewer than `iterationCount` times. An + // normal expectation will fail if expectation.fullfill() is not called times. An normal + // expectation will fail if expectation.fullfill() is not called + // `expectation.expectedFulfillmentCount` times. If `expectation.isInverted = true`, the test will + // only succeed if expectation is not fullfilled for the specified `expectedFulfillmentCount`. + // Since it it not possible to determine how many times the expectation is supposed to be + // fullfilled, `expectation.expectedFulfillmentCount` = `iterationCount` + 1 and + // `expectation.isInverted = true` ensures that test succeeds if expectation is fullfilled <= + // `iterationCount` times. + XCTestExpectation *expectation = [[XCTestExpectation alloc] + initWithDescription:@"detectWithOutOfOrderTimestampsAndLiveStream"]; + expectation.expectedFulfillmentCount = iterationCount + 1; + expectation.inverted = YES; + + MPPFaceDetector *faceDetector = [self faceDetectorWithOptionsSucceeds:options]; + + liveStreamSucceedsTestDict = @{ + kLiveStreamTestsDictFaceDetectorKey : faceDetector, + kLiveStreamTestsDictExpectationKey : expectation + }; + + MPPImage *image = [self imageWithFileInfo:kPortraitImage]; + for (int i = 0; i < iterationCount; i++) { + XCTAssertTrue([faceDetector detectAsyncInImage:image timestampInMilliseconds:i error:nil]); + } + + NSTimeInterval timeout = 0.5f; + [self waitForExpectations:@[ expectation ] timeout:timeout]; +} + +#pragma mark MPPFaceDetectorLiveStreamDelegate Methods +- (void)faceDetector:(MPPFaceDetector *)faceDetector + didFinishDetectionWithResult:(MPPFaceDetectorResult *)faceDetectorResult + timestampInMilliseconds:(NSInteger)timestampInMilliseconds + error:(NSError *)error { + [self assertFaceDetectorResult:faceDetectorResult + containsExpectedKeypoints:kPortraitExpectedKeypoints]; + + if (faceDetector == outOfOrderTimestampTestDict[kLiveStreamTestsDictFaceDetectorKey]) { + [outOfOrderTimestampTestDict[kLiveStreamTestsDictExpectationKey] fulfill]; + } else if (faceDetector == liveStreamSucceedsTestDict[kLiveStreamTestsDictFaceDetectorKey]) { + [liveStreamSucceedsTestDict[kLiveStreamTestsDictExpectationKey] fulfill]; + } +} + ++ (NSString *)filePathWithName:(NSString *)fileName extension:(NSString *)extension { + NSString *filePath = + [[NSBundle bundleForClass:[MPPFaceDetectorTests class]] pathForResource:fileName + ofType:extension]; + return filePath; +} + +- (void)assertKeypoints:(NSArray *)keypoints + areEqualToExpectedKeypoints:(NSArray *)expectedKeypoint { + XCTAssertEqual(keypoints.count, expectedKeypoint.count); + for (int i = 0; i < keypoints.count; ++i) { + XCTAssertEqualWithAccuracy(keypoints[i].location.x, [expectedKeypoint[i][0] floatValue], + kKeypointErrorThreshold, @"index i = %d", i); + XCTAssertEqualWithAccuracy(keypoints[i].location.y, [expectedKeypoint[i][1] floatValue], + kKeypointErrorThreshold, @"index i = %d", i); + } +} + +- (void)assertDetections:(NSArray *)detections + containExpectedKeypoints:(NSArray *)expectedKeypoints { + XCTAssertEqual(detections.count, 1); + MPPDetection *detection = detections[0]; + XCTAssertNotNil(detection); + [self assertKeypoints:detections[0].keypoints areEqualToExpectedKeypoints:expectedKeypoints]; +} + +- (void)assertFaceDetectorResult:(MPPFaceDetectorResult *)faceDetectorResult + containsExpectedKeypoints:(NSArray *)expectedKeypoints { + [self assertDetections:faceDetectorResult.detections containExpectedKeypoints:expectedKeypoints]; +} + +#pragma mark Face Detector Initializers + +- (MPPFaceDetectorOptions *)faceDetectorOptionsWithModelName:(NSString *)modelName { + NSString *modelPath = [MPPFaceDetectorTests filePathWithName:modelName extension:@"tflite"]; + MPPFaceDetectorOptions *faceDetectorOptions = [[MPPFaceDetectorOptions alloc] init]; + faceDetectorOptions.baseOptions.modelAssetPath = modelPath; + + return faceDetectorOptions; +} + +- (void)assertCreateFaceDetectorWithOptions:(MPPFaceDetectorOptions *)faceDetectorOptions + failsWithExpectedError:(NSError *)expectedError { + NSError *error = nil; + MPPFaceDetector *faceDetector = [[MPPFaceDetector alloc] initWithOptions:faceDetectorOptions + error:&error]; + XCTAssertNil(faceDetector); + AssertEqualErrors(error, expectedError); +} + +- (MPPFaceDetector *)faceDetectorWithOptionsSucceeds:(MPPFaceDetectorOptions *)faceDetectorOptions { + MPPFaceDetector *faceDetector = [[MPPFaceDetector alloc] initWithOptions:faceDetectorOptions + error:nil]; + XCTAssertNotNil(faceDetector); + + return faceDetector; +} + +#pragma mark Assert Detection Results + +- (MPPImage *)imageWithFileInfo:(NSDictionary *)fileInfo { + UIImageOrientation orientation = (UIImageOrientation)[fileInfo[@"orientation"] intValue]; + MPPImage *image = [MPPImage imageFromBundleWithClass:[MPPFaceDetectorTests class] + fileName:fileInfo[@"name"] + ofType:fileInfo[@"type"] + orientation:orientation]; + XCTAssertNotNil(image); + return image; +} + +- (void)assertResultsOfDetectInImage:(MPPImage *)mppImage + usingFaceDetector:(MPPFaceDetector *)faceDetector + containsExpectedKeypoints:(NSArray *)expectedKeypoints { + NSError *error; + MPPFaceDetectorResult *faceDetectorResult = [faceDetector detectInImage:mppImage error:&error]; + XCTAssertNil(error); + XCTAssertNotNil(faceDetectorResult); + [self assertFaceDetectorResult:faceDetectorResult containsExpectedKeypoints:expectedKeypoints]; +} + +- (void)assertResultsOfDetectInImageWithFileInfo:(NSDictionary *)fileInfo + usingFaceDetector:(MPPFaceDetector *)faceDetector + containsExpectedKeypoints:(NSArray *)expectedKeypoints { + MPPImage *mppImage = [self imageWithFileInfo:fileInfo]; + + [self assertResultsOfDetectInImage:mppImage + usingFaceDetector:faceDetector + containsExpectedKeypoints:expectedKeypoints]; +} + +@end From 7facc925ba57ead64b2ad9ceee920868d3bea97f Mon Sep 17 00:00:00 2001 From: Jiuqiang Tang Date: Wed, 24 May 2023 11:12:20 -0700 Subject: [PATCH 324/753] 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 --- .../face_stylizer/face_stylizer_graph.cc | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc index d7265a146..d4057467b 100644 --- a/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc +++ b/mediapipe/tasks/cc/vision/face_stylizer/face_stylizer_graph.cc @@ -231,18 +231,26 @@ class FaceStylizerGraph : public core::ModelTaskGraph { SubgraphContext* sc) override { bool output_stylized = HasOutput(sc->OriginalNode(), kStylizedImageTag); bool output_alignment = HasOutput(sc->OriginalNode(), kFaceAlignmentTag); - ASSIGN_OR_RETURN( - const auto* model_asset_bundle_resources, - CreateModelAssetBundleResources(sc)); - // Copies the file content instead of passing the pointer of file in - // memory if the subgraph model resource service is not available. auto face_stylizer_external_file = absl::make_unique(); - MP_RETURN_IF_ERROR(SetSubTaskBaseOptions( - *model_asset_bundle_resources, - sc->MutableOptions(), - output_stylized ? face_stylizer_external_file.get() : nullptr, - !sc->Service(::mediapipe::tasks::core::kModelResourcesCacheService) - .IsAvailable())); + if (sc->Options().has_base_options()) { + ASSIGN_OR_RETURN( + const auto* model_asset_bundle_resources, + CreateModelAssetBundleResources(sc)); + // Copies the file content instead of passing the pointer of file in + // memory if the subgraph model resource service is not available. + MP_RETURN_IF_ERROR(SetSubTaskBaseOptions( + *model_asset_bundle_resources, + sc->MutableOptions(), + output_stylized ? face_stylizer_external_file.get() : nullptr, + !sc->Service(::mediapipe::tasks::core::kModelResourcesCacheService) + .IsAvailable())); + } else if (output_stylized) { + return CreateStatusWithPayload( + absl::StatusCode::kInvalidArgument, + "Face stylizer must specify its base options when the " + "\"STYLIZED_IMAGE\" output stream is connected.", + MediaPipeTasksStatus::kInvalidArgumentError); + } Graph graph; ASSIGN_OR_RETURN( auto face_landmark_lists, @@ -347,7 +355,7 @@ class FaceStylizerGraph : public core::ModelTaskGraph { auto& image_to_tensor = graph.AddNode("ImageToTensorCalculator"); auto& image_to_tensor_options = image_to_tensor.GetOptions(); - image_to_tensor_options.mutable_output_tensor_float_range()->set_min(-1); + image_to_tensor_options.mutable_output_tensor_float_range()->set_min(0); image_to_tensor_options.mutable_output_tensor_float_range()->set_max(1); image_to_tensor_options.set_output_tensor_width(kFaceAlignmentOutputSize); image_to_tensor_options.set_output_tensor_height( @@ -363,7 +371,7 @@ class FaceStylizerGraph : public core::ModelTaskGraph { graph.AddNode("mediapipe.tasks.TensorsToImageCalculator"); auto& tensors_to_image_options = tensors_to_image.GetOptions(); - tensors_to_image_options.mutable_input_tensor_float_range()->set_min(-1); + tensors_to_image_options.mutable_input_tensor_float_range()->set_min(0); tensors_to_image_options.mutable_input_tensor_float_range()->set_max(1); face_alignment_image >> tensors_to_image.In(kTensorsTag); face_alignment = tensors_to_image.Out(kImageTag).Cast(); From a7b81c7d108efaa595a3f9dc11c3c121a6e45fd0 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 24 May 2023 11:52:27 -0700 Subject: [PATCH 325/753] Change "numberOfHands" property name to "numHands". PiperOrigin-RevId: 534927982 --- .../gesture_recognizer/sources/MPPGestureRecognizerOptions.h | 2 +- .../gesture_recognizer/sources/MPPGestureRecognizerOptions.m | 4 ++-- .../utils/sources/MPPGestureRecognizerOptions+Helpers.mm | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h index b896e3756..323763cb5 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.h @@ -87,7 +87,7 @@ NS_SWIFT_NAME(GestureRecognizerOptions) gestureRecognizerLiveStreamDelegate; /** Sets the maximum number of hands can be detected by the GestureRecognizer. */ -@property(nonatomic) NSInteger numberOfHands NS_SWIFT_NAME(numHands); +@property(nonatomic) NSInteger numHands; /** Sets minimum confidence score for the hand detection to be considered successful */ @property(nonatomic) float minHandDetectionConfidence; diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.m b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.m index 099ab33e1..71b85cc83 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.m +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/sources/MPPGestureRecognizerOptions.m @@ -19,7 +19,7 @@ - (instancetype)init { self = [super init]; if (self) { - _numberOfHands = 1; + _numHands = 1; _minHandDetectionConfidence = 0.5f; _minHandPresenceConfidence = 0.5f; _minTrackingConfidence = 0.5f; @@ -33,7 +33,7 @@ gestureRecognizerOptions.runningMode = self.runningMode; gestureRecognizerOptions.gestureRecognizerLiveStreamDelegate = self.gestureRecognizerLiveStreamDelegate; - gestureRecognizerOptions.numberOfHands = self.numberOfHands; + gestureRecognizerOptions.numHands = self.numHands; gestureRecognizerOptions.minHandDetectionConfidence = self.minHandDetectionConfidence; gestureRecognizerOptions.minHandPresenceConfidence = self.minHandPresenceConfidence; gestureRecognizerOptions.minTrackingConfidence = self.minTrackingConfidence; diff --git a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.mm b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.mm index d234d86a0..5f8d25d7c 100644 --- a/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.mm +++ b/mediapipe/tasks/ios/vision/gesture_recognizer/utils/sources/MPPGestureRecognizerOptions+Helpers.mm @@ -60,7 +60,7 @@ using ClassifierOptionsProto = ::mediapipe::tasks::components::processors::proto HandDetectorGraphOptionsProto *handDetectorGraphOptionsProto = handLandmarkerGraphOptionsProto->mutable_hand_detector_graph_options(); handDetectorGraphOptionsProto->Clear(); - handDetectorGraphOptionsProto->set_num_hands(self.numberOfHands); + handDetectorGraphOptionsProto->set_num_hands(self.numHands); handDetectorGraphOptionsProto->set_min_detection_confidence(self.minHandDetectionConfidence); HandLandmarksDetectorGraphOptionsProto *handLandmarksDetectorGraphOptionsProto = From c8ee09796bd36766550d2d6df69de8369644ecfb Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 24 May 2023 13:24:32 -0700 Subject: [PATCH 326/753] Internal change PiperOrigin-RevId: 534959867 --- mediapipe/calculators/tensor/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/calculators/tensor/BUILD b/mediapipe/calculators/tensor/BUILD index 4893b3b79..59102585c 100644 --- a/mediapipe/calculators/tensor/BUILD +++ b/mediapipe/calculators/tensor/BUILD @@ -394,7 +394,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"], From 7800d238e916d7b74ba019c254c33999cae834e1 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Wed, 24 May 2023 20:15:30 -0700 Subject: [PATCH 327/753] add needed enum type for choose fuse pipeline. PiperOrigin-RevId: 535076733 --- mediapipe/calculators/core/BUILD | 4 ++-- mediapipe/calculators/core/begin_loop_calculator.cc | 4 ++++ mediapipe/calculators/core/end_loop_calculator.cc | 4 ++++ mediapipe/calculators/core/split_vector_calculator.cc | 9 +++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/mediapipe/calculators/core/BUILD b/mediapipe/calculators/core/BUILD index 3294c0383..4e32ed59f 100644 --- a/mediapipe/calculators/core/BUILD +++ b/mediapipe/calculators/core/BUILD @@ -194,6 +194,7 @@ cc_library( "//mediapipe/framework:calculator_framework", "//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", @@ -225,10 +226,8 @@ cc_library( "//mediapipe/framework/formats:rect_cc_proto", "//mediapipe/framework/formats:tensor", "//mediapipe/framework/port:ret_check", - "//mediapipe/framework/port:status", "//mediapipe/gpu:gpu_buffer", "//mediapipe/util:render_data_cc_proto", - "@com_google_absl//absl/memory", "@com_google_absl//absl/status", "@org_tensorflow//tensorflow/lite:framework", ], @@ -907,6 +906,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", diff --git a/mediapipe/calculators/core/begin_loop_calculator.cc b/mediapipe/calculators/core/begin_loop_calculator.cc index ac74bb382..7da90989b 100644 --- a/mediapipe/calculators/core/begin_loop_calculator.cc +++ b/mediapipe/calculators/core/begin_loop_calculator.cc @@ -17,6 +17,7 @@ #include #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" @@ -72,4 +73,7 @@ typedef BeginLoopCalculator> BeginLoopGpuBufferCalculator; REGISTER_CALCULATOR(BeginLoopGpuBufferCalculator); +// A calculator to process std::vector. +typedef BeginLoopCalculator> BeginLoopImageCalculator; +REGISTER_CALCULATOR(BeginLoopImageCalculator); } // namespace mediapipe diff --git a/mediapipe/calculators/core/end_loop_calculator.cc b/mediapipe/calculators/core/end_loop_calculator.cc index dea2b6cad..752580cfd 100644 --- a/mediapipe/calculators/core/end_loop_calculator.cc +++ b/mediapipe/calculators/core/end_loop_calculator.cc @@ -80,4 +80,8 @@ typedef EndLoopCalculator> EndLoopImageCalculator; REGISTER_CALCULATOR(EndLoopImageCalculator); +typedef EndLoopCalculator>> + EndLoopAffineMatrixCalculator; +REGISTER_CALCULATOR(EndLoopAffineMatrixCalculator); + } // namespace mediapipe diff --git a/mediapipe/calculators/core/split_vector_calculator.cc b/mediapipe/calculators/core/split_vector_calculator.cc index b76722de9..67fc38ce9 100644 --- a/mediapipe/calculators/core/split_vector_calculator.cc +++ b/mediapipe/calculators/core/split_vector_calculator.cc @@ -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 SplitFloatVectorCalculator; REGISTER_CALCULATOR(SplitFloatVectorCalculator); +typedef SplitVectorCalculator + SplitImageVectorCalculator; +REGISTER_CALCULATOR(SplitImageVectorCalculator); + +typedef SplitVectorCalculator, false> + SplitAffineMatrixVectorCalculator; +REGISTER_CALCULATOR(SplitAffineMatrixVectorCalculator); + } // namespace mediapipe From 1baf72e46b3c38cb3b39093ccf13aa577a5a5f15 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 24 May 2023 23:42:59 -0700 Subject: [PATCH 328/753] Internal change PiperOrigin-RevId: 535131938 --- .../vision/face_landmarker/face_landmarker.ts | 22 ++++++++++--------- .../face_landmarker_result.d.ts | 4 ++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts index 9dc8626c9..e2e25c71b 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts +++ b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker.ts @@ -59,7 +59,11 @@ const DEFAULT_SCORE_THRESHOLD = 0.5; * This API expects a pre-trained face landmarker model asset bundle. */ export class FaceLandmarker extends VisionTaskRunner { - private result: FaceLandmarkerResult = {faceLandmarks: []}; + private result: FaceLandmarkerResult = { + faceLandmarks: [], + faceBlendshapes: [], + facialTransformationMatrixes: [] + }; private outputFaceBlendshapes = false; private outputFacialTransformationMatrixes = false; @@ -256,13 +260,11 @@ export class FaceLandmarker extends VisionTaskRunner { } private resetResults(): void { - this.result = {faceLandmarks: []}; - if (this.outputFaceBlendshapes) { - this.result.faceBlendshapes = []; - } - if (this.outputFacialTransformationMatrixes) { - this.result.facialTransformationMatrixes = []; - } + this.result = { + faceLandmarks: [], + faceBlendshapes: [], + facialTransformationMatrixes: [] + }; } /** Sets the default values for the graph. */ @@ -286,7 +288,7 @@ export class FaceLandmarker extends VisionTaskRunner { /** Adds new blendshapes from the given proto. */ private addBlenshape(data: Uint8Array[]): void { - if (!this.result.faceBlendshapes) { + if (!this.outputFaceBlendshapes) { return; } @@ -300,7 +302,7 @@ export class FaceLandmarker extends VisionTaskRunner { /** Adds new transformation matrixes from the given proto. */ private addFacialTransformationMatrixes(data: Uint8Array[]): void { - if (!this.result.facialTransformationMatrixes) { + if (!this.outputFacialTransformationMatrixes) { return; } diff --git a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_result.d.ts b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_result.d.ts index 4bbe3b0c9..4af483ab3 100644 --- a/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_result.d.ts +++ b/mediapipe/tasks/web/vision/face_landmarker/face_landmarker_result.d.ts @@ -29,8 +29,8 @@ export declare interface FaceLandmarkerResult { faceLandmarks: NormalizedLandmark[][]; /** Optional face blendshapes results. */ - faceBlendshapes?: Classifications[]; + faceBlendshapes: Classifications[]; /** Optional facial transformation matrix. */ - facialTransformationMatrixes?: Matrix[]; + facialTransformationMatrixes: Matrix[]; } From 3ac903787a16422c054a1f9c83214f0ef096df40 Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Thu, 25 May 2023 01:47:16 -0700 Subject: [PATCH 329/753] Internal change PiperOrigin-RevId: 535162357 --- mediapipe/calculators/tensor/BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediapipe/calculators/tensor/BUILD b/mediapipe/calculators/tensor/BUILD index 59102585c..4893b3b79 100644 --- a/mediapipe/calculators/tensor/BUILD +++ b/mediapipe/calculators/tensor/BUILD @@ -394,7 +394,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 "InferenceCalculator" in your graphs. +# In all cases, use "InferenceCalulator" in your graphs. cc_library_with_tflite( name = "inference_calculator_interface", srcs = ["inference_calculator.cc"], From 952021f497cf1bbea88487ada1d2839906cf8ee7 Mon Sep 17 00:00:00 2001 From: Khanh LeViet Date: Thu, 25 May 2023 08:02:25 -0700 Subject: [PATCH 330/753] Remove unused MediaPipe Tasks Android sample PiperOrigin-RevId: 535259478 --- mediapipe/tasks/examples/android/BUILD | 21 -- .../src/main/AndroidManifest.xml | 37 --- .../android/objectdetector/src/main/BUILD | 49 ---- .../examples/objectdetector/MainActivity.java | 239 ------------------ .../ObjectDetectionResultImageView.java | 77 ------ .../drawable-v24/ic_launcher_foreground.xml | 34 --- .../res/drawable/ic_launcher_background.xml | 74 ------ .../android/res/layout/activity_main.xml | 40 --- .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 - .../android/res/mipmap-hdpi/ic_launcher.png | Bin 1354 -> 0 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 2257 -> 0 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 3246 -> 0 bytes .../android/res/mipmap-mdpi/ic_launcher.png | Bin 959 -> 0 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 900 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 1955 -> 0 bytes .../android/res/mipmap-xhdpi/ic_launcher.png | Bin 1971 -> 0 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 1845 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 4658 -> 0 bytes .../android/res/mipmap-xxhdpi/ic_launcher.png | Bin 3562 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 5655 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 7745 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher.png | Bin 5004 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 8278 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 11062 -> 0 bytes .../examples/android/res/values/colors.xml | 6 - .../examples/android/res/values/strings.xml | 6 - .../examples/android/res/values/styles.xml | 11 - 28 files changed, 604 deletions(-) delete mode 100644 mediapipe/tasks/examples/android/BUILD delete mode 100644 mediapipe/tasks/examples/android/objectdetector/src/main/AndroidManifest.xml delete mode 100644 mediapipe/tasks/examples/android/objectdetector/src/main/BUILD delete mode 100644 mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/MainActivity.java delete mode 100644 mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/ObjectDetectionResultImageView.java delete mode 100644 mediapipe/tasks/examples/android/res/drawable-v24/ic_launcher_foreground.xml delete mode 100644 mediapipe/tasks/examples/android/res/drawable/ic_launcher_background.xml delete mode 100644 mediapipe/tasks/examples/android/res/layout/activity_main.xml delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-hdpi/ic_launcher.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-hdpi/ic_launcher_foreground.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-hdpi/ic_launcher_round.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-mdpi/ic_launcher.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-mdpi/ic_launcher_foreground.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-mdpi/ic_launcher_round.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-xhdpi/ic_launcher_foreground.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-xhdpi/ic_launcher_round.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-xxhdpi/ic_launcher_foreground.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-xxhdpi/ic_launcher_round.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-xxxhdpi/ic_launcher_foreground.png delete mode 100644 mediapipe/tasks/examples/android/res/mipmap-xxxhdpi/ic_launcher_round.png delete mode 100644 mediapipe/tasks/examples/android/res/values/colors.xml delete mode 100644 mediapipe/tasks/examples/android/res/values/strings.xml delete mode 100644 mediapipe/tasks/examples/android/res/values/styles.xml diff --git a/mediapipe/tasks/examples/android/BUILD b/mediapipe/tasks/examples/android/BUILD deleted file mode 100644 index f2c90236b..000000000 --- a/mediapipe/tasks/examples/android/BUILD +++ /dev/null @@ -1,21 +0,0 @@ -# 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. -# 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. - -licenses(["notice"]) - -filegroup( - name = "resource_files", - srcs = glob(["res/**"]), - visibility = ["//mediapipe/tasks/examples/android:__subpackages__"], -) diff --git a/mediapipe/tasks/examples/android/objectdetector/src/main/AndroidManifest.xml b/mediapipe/tasks/examples/android/objectdetector/src/main/AndroidManifest.xml deleted file mode 100644 index 5c53dc269..000000000 --- a/mediapipe/tasks/examples/android/objectdetector/src/main/AndroidManifest.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mediapipe/tasks/examples/android/objectdetector/src/main/BUILD b/mediapipe/tasks/examples/android/objectdetector/src/main/BUILD deleted file mode 100644 index 28bd38f9f..000000000 --- a/mediapipe/tasks/examples/android/objectdetector/src/main/BUILD +++ /dev/null @@ -1,49 +0,0 @@ -# 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. -# 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. - -licenses(["notice"]) - -package(default_visibility = ["//visibility:private"]) - -android_binary( - name = "objectdetector", - srcs = glob(["**/*.java"]), - assets = [ - "//mediapipe/tasks/testdata/vision:test_models", - ], - assets_dir = "", - custom_package = "com.google.mediapipe.tasks.examples.objectdetector", - manifest = "AndroidManifest.xml", - manifest_values = { - "applicationId": "com.google.mediapipe.tasks.examples.objectdetector", - }, - multidex = "native", - resource_files = ["//mediapipe/tasks/examples/android:resource_files"], - deps = [ - "//mediapipe/java/com/google/mediapipe/framework:android_framework", - "//mediapipe/java/com/google/mediapipe/framework/image", - "//mediapipe/tasks/java/com/google/mediapipe/tasks/components/containers:detection", - "//mediapipe/tasks/java/com/google/mediapipe/tasks/core", - "//mediapipe/tasks/java/com/google/mediapipe/tasks/vision:core", - "//mediapipe/tasks/java/com/google/mediapipe/tasks/vision:objectdetector", - "//third_party:androidx_appcompat", - "//third_party:androidx_constraint_layout", - "//third_party:opencv", - "@maven//:androidx_activity_activity", - "@maven//:androidx_concurrent_concurrent_futures", - "@maven//:androidx_exifinterface_exifinterface", - "@maven//:androidx_fragment_fragment", - "@maven//:com_google_guava_guava", - ], -) diff --git a/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/MainActivity.java b/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/MainActivity.java deleted file mode 100644 index abfd7c7d1..000000000 --- a/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/MainActivity.java +++ /dev/null @@ -1,239 +0,0 @@ -// 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. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.mediapipe.tasks.examples.objectdetector; - -import android.content.Intent; -import android.graphics.Bitmap; -import android.media.MediaMetadataRetriever; -import android.os.Bundle; -import android.provider.MediaStore; -import androidx.appcompat.app.AppCompatActivity; -import android.util.Log; -import android.view.View; -import android.widget.Button; -import android.widget.FrameLayout; -import androidx.activity.result.ActivityResultLauncher; -import androidx.activity.result.contract.ActivityResultContracts; -import androidx.exifinterface.media.ExifInterface; -// ContentResolver dependency -import com.google.mediapipe.framework.MediaPipeException; -import com.google.mediapipe.framework.image.BitmapImageBuilder; -import com.google.mediapipe.framework.image.MPImage; -import com.google.mediapipe.tasks.core.BaseOptions; -import com.google.mediapipe.tasks.vision.core.ImageProcessingOptions; -import com.google.mediapipe.tasks.vision.core.RunningMode; -import com.google.mediapipe.tasks.vision.objectdetector.ObjectDetectionResult; -import com.google.mediapipe.tasks.vision.objectdetector.ObjectDetector; -import com.google.mediapipe.tasks.vision.objectdetector.ObjectDetector.ObjectDetectorOptions; -import java.io.IOException; -import java.io.InputStream; - -/** Main activity of MediaPipe Task Object Detector reference app. */ -public class MainActivity extends AppCompatActivity { - private static final String TAG = "MainActivity"; - private static final String MODEL_FILE = "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.tflite"; - - private ObjectDetector objectDetector; - - private enum InputSource { - UNKNOWN, - IMAGE, - VIDEO, - CAMERA, - } - - private InputSource inputSource = InputSource.UNKNOWN; - - // Image mode demo component. - private ActivityResultLauncher imageGetter; - // Video mode demo component. - private ActivityResultLauncher videoGetter; - private ObjectDetectionResultImageView imageView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - setupImageModeDemo(); - setupVideoModeDemo(); - // TODO: Adds live camera demo. - } - - /** Sets up the image mode demo. */ - private void setupImageModeDemo() { - imageView = new ObjectDetectionResultImageView(this); - // The Intent to access gallery and read images as bitmap. - imageGetter = - registerForActivityResult( - new ActivityResultContracts.StartActivityForResult(), - result -> { - Intent resultIntent = result.getData(); - if (resultIntent != null) { - if (result.getResultCode() == RESULT_OK) { - Bitmap bitmap = null; - int rotation = 0; - try { - bitmap = - downscaleBitmap( - MediaStore.Images.Media.getBitmap( - this.getContentResolver(), resultIntent.getData())); - } catch (IOException e) { - Log.e(TAG, "Bitmap reading error:" + e); - } - try { - InputStream imageData = - this.getContentResolver().openInputStream(resultIntent.getData()); - rotation = getImageRotation(imageData); - } catch (IOException | MediaPipeException e) { - Log.e(TAG, "Bitmap rotation error:" + e); - } - if (bitmap != null) { - MPImage image = new BitmapImageBuilder(bitmap).build(); - ObjectDetectionResult detectionResult = - objectDetector.detect( - image, - ImageProcessingOptions.builder().setRotationDegrees(rotation).build()); - imageView.setData(image, detectionResult); - runOnUiThread(() -> imageView.update()); - } - } - } - }); - Button loadImageButton = findViewById(R.id.button_load_picture); - loadImageButton.setOnClickListener( - v -> { - if (inputSource != InputSource.IMAGE) { - createObjectDetector(RunningMode.IMAGE); - this.inputSource = InputSource.IMAGE; - updateLayout(); - } - // Reads images from gallery. - Intent pickImageIntent = new Intent(Intent.ACTION_PICK); - pickImageIntent.setDataAndType(MediaStore.Images.Media.INTERNAL_CONTENT_URI, "image/*"); - imageGetter.launch(pickImageIntent); - }); - } - - /** Sets up the video mode demo. */ - private void setupVideoModeDemo() { - imageView = new ObjectDetectionResultImageView(this); - // The Intent to access gallery and read a video file. - videoGetter = - registerForActivityResult( - new ActivityResultContracts.StartActivityForResult(), - result -> { - Intent resultIntent = result.getData(); - if (resultIntent != null) { - if (result.getResultCode() == RESULT_OK) { - MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever(); - metaRetriever.setDataSource(this, resultIntent.getData()); - long duration = - Long.parseLong( - metaRetriever.extractMetadata( - MediaMetadataRetriever.METADATA_KEY_DURATION)); - int numFrames = - Integer.parseInt( - metaRetriever.extractMetadata( - MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT)); - long frameIntervalMs = duration / numFrames; - for (int i = 0; i < numFrames; ++i) { - MPImage image = - new BitmapImageBuilder(metaRetriever.getFrameAtIndex(i)).build(); - ObjectDetectionResult detectionResult = - objectDetector.detectForVideo(image, frameIntervalMs * i); - // Currently only annotates the detection result on the first video frame and - // display it to verify the correctness. - // TODO: Annotates the detection result on every frame, save the - // annotated frames as a video file, and play back the video afterwards. - if (i == 0) { - imageView.setData(image, detectionResult); - runOnUiThread(() -> imageView.update()); - } - } - } - } - }); - Button loadVideoButton = findViewById(R.id.button_load_video); - loadVideoButton.setOnClickListener( - v -> { - createObjectDetector(RunningMode.VIDEO); - updateLayout(); - this.inputSource = InputSource.VIDEO; - - // Reads a video from gallery. - Intent pickVideoIntent = new Intent(Intent.ACTION_PICK); - pickVideoIntent.setDataAndType(MediaStore.Video.Media.INTERNAL_CONTENT_URI, "video/*"); - videoGetter.launch(pickVideoIntent); - }); - } - - private void createObjectDetector(RunningMode mode) { - if (objectDetector != null) { - objectDetector.close(); - } - // Initializes a new MediaPipe ObjectDetector instance - ObjectDetectorOptions options = - ObjectDetectorOptions.builder() - .setBaseOptions(BaseOptions.builder().setModelAssetPath(MODEL_FILE).build()) - .setScoreThreshold(0.5f) - .setMaxResults(5) - .setRunningMode(mode) - .build(); - objectDetector = ObjectDetector.createFromOptions(this, options); - } - - private void updateLayout() { - // Updates the preview layout. - FrameLayout frameLayout = findViewById(R.id.preview_display_layout); - frameLayout.removeAllViewsInLayout(); - imageView.setImageDrawable(null); - frameLayout.addView(imageView); - imageView.setVisibility(View.VISIBLE); - } - - private Bitmap downscaleBitmap(Bitmap originalBitmap) { - double aspectRatio = (double) originalBitmap.getWidth() / originalBitmap.getHeight(); - int width = imageView.getWidth(); - int height = imageView.getHeight(); - if (((double) imageView.getWidth() / imageView.getHeight()) > aspectRatio) { - width = (int) (height * aspectRatio); - } else { - height = (int) (width / aspectRatio); - } - return Bitmap.createScaledBitmap(originalBitmap, width, height, false); - } - - private int getImageRotation(InputStream imageData) throws IOException, MediaPipeException { - int orientation = - new ExifInterface(imageData) - .getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); - switch (orientation) { - case ExifInterface.ORIENTATION_NORMAL: - return 0; - case ExifInterface.ORIENTATION_ROTATE_90: - return 90; - case ExifInterface.ORIENTATION_ROTATE_180: - return 180; - case ExifInterface.ORIENTATION_ROTATE_270: - return 270; - default: - // TODO: use getRotationDegrees() and isFlipped() instead of switch once flip - // is supported. - throw new MediaPipeException( - MediaPipeException.StatusCode.UNIMPLEMENTED.ordinal(), - "Flipped images are not supported yet."); - } - } -} diff --git a/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/ObjectDetectionResultImageView.java b/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/ObjectDetectionResultImageView.java deleted file mode 100644 index e37c64156..000000000 --- a/mediapipe/tasks/examples/android/objectdetector/src/main/java/com/google/mediapipe/tasks/examples/objectdetector/ObjectDetectionResultImageView.java +++ /dev/null @@ -1,77 +0,0 @@ -// 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. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.mediapipe.tasks.examples.objectdetector; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Matrix; -import android.graphics.Paint; -import androidx.appcompat.widget.AppCompatImageView; -import com.google.mediapipe.framework.image.BitmapExtractor; -import com.google.mediapipe.framework.image.MPImage; -import com.google.mediapipe.tasks.components.containers.Detection; -import com.google.mediapipe.tasks.vision.objectdetector.ObjectDetectionResult; - -/** An ImageView implementation for displaying {@link ObjectDetectionResult}. */ -public class ObjectDetectionResultImageView extends AppCompatImageView { - private static final String TAG = "ObjectDetectionResultImageView"; - - private static final int BBOX_COLOR = Color.GREEN; - private static final int BBOX_THICKNESS = 5; // Pixels - private Bitmap latest; - - public ObjectDetectionResultImageView(Context context) { - super(context); - setScaleType(AppCompatImageView.ScaleType.FIT_CENTER); - } - - /** - * Sets a {@link MPImage} and an {@link ObjectDetectionResult} to render. - * - * @param image a {@link MPImage} object for annotation. - * @param result an {@link ObjectDetectionResult} object that contains the detection result. - */ - public void setData(MPImage image, ObjectDetectionResult result) { - if (image == null || result == null) { - return; - } - latest = BitmapExtractor.extract(image); - Canvas canvas = new Canvas(latest); - canvas.drawBitmap(latest, new Matrix(), null); - for (int i = 0; i < result.detections().size(); ++i) { - drawDetectionOnCanvas(result.detections().get(i), canvas); - } - } - - /** Updates the image view with the latest {@link ObjectDetectionResult}. */ - public void update() { - postInvalidate(); - if (latest != null) { - setImageBitmap(latest); - } - } - - private void drawDetectionOnCanvas(Detection detection, Canvas canvas) { - // TODO: Draws the category and the score per bounding box. - // Draws bounding box. - Paint bboxPaint = new Paint(); - bboxPaint.setColor(BBOX_COLOR); - bboxPaint.setStyle(Paint.Style.STROKE); - bboxPaint.setStrokeWidth(BBOX_THICKNESS); - canvas.drawRect(detection.boundingBox(), bboxPaint); - } -} diff --git a/mediapipe/tasks/examples/android/res/drawable-v24/ic_launcher_foreground.xml b/mediapipe/tasks/examples/android/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index c7bd21dbd..000000000 --- a/mediapipe/tasks/examples/android/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - diff --git a/mediapipe/tasks/examples/android/res/drawable/ic_launcher_background.xml b/mediapipe/tasks/examples/android/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 01f0af0ad..000000000 --- a/mediapipe/tasks/examples/android/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mediapipe/tasks/examples/android/res/layout/activity_main.xml b/mediapipe/tasks/examples/android/res/layout/activity_main.xml deleted file mode 100644 index 834e9a3e6..000000000 --- a/mediapipe/tasks/examples/android/res/layout/activity_main.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - -