diff --git a/mediapipe/tasks/ios/components/containers/BUILD b/mediapipe/tasks/ios/components/containers/BUILD index 3ed7669cb..8873847af 100644 --- a/mediapipe/tasks/ios/components/containers/BUILD +++ b/mediapipe/tasks/ios/components/containers/BUILD @@ -54,3 +54,9 @@ objc_library( "//third_party/apple_frameworks:UIKit", ], ) + +objc_library( + name = "MPPLandmark", + srcs = ["sources/MPPLandmark.m"], + hdrs = ["sources/MPPLandmark.h"], +) diff --git a/mediapipe/tasks/ios/components/containers/sources/MPPLandmark.h b/mediapipe/tasks/ios/components/containers/sources/MPPLandmark.h new file mode 100644 index 000000000..bb1dbc2c8 --- /dev/null +++ b/mediapipe/tasks/ios/components/containers/sources/MPPLandmark.h @@ -0,0 +1,126 @@ +// Copyright 2023 The 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 + +NS_ASSUME_NONNULL_BEGIN + +/** + * Landmark represents a point in 3D space with x, y, z coordinates. The landmark coordinates are in + * meters. z represents the landmark depth, and the smaller the value the closer the world landmark + * is to the camera. + */ +NS_SWIFT_NAME(Landmark) +@interface MPPLandmark : NSObject + +/** The x coordinates of the landmark. */ +@property(nonatomic, readonly) float x; + +/** The y coordinates of the landmark. */ +@property(nonatomic, readonly) float y; + +/** The z coordinates of the landmark. */ +@property(nonatomic, readonly) float z; + +/** + * Landmark visibility. Should be `nil` if not supported. Float score of whether landmark is visible + * or occluded by other objects. Landmark considered as invisible also if it is not present on the + * screen (out of scene bounds). Depending on the model, visibility value is either a sigmoid or an + * argument of sigmoid. + */ +@property(nonatomic, readonly, nullable) NSNumber *visibility; + +/** + * Landmark presence. Should stay unset if not supported. Float score of whether landmark is present + * on the scene (located within scene bounds). Depending on the model, presence value is either a + * result of sigmoid or an argument of sigmoid function to get landmark presence probability. + */ +@property(nonatomic, readonly) NSNumber *presence; + +/** + * Initializes a new `MPPLandmark` object with the given x, y and z coordinates. + * + * @param x The x coordinates of the landmark. + * @param y The y coordinates of the landmark. + * @param z The z coordinates of the landmark. + * + * @return An instance of `MPPLandmark` initialized with the given x, y and z coordinates. + */ +- (instancetype)initWithX:(float)x + y:(float)y + z:(float)z + visibility:(nullable NSNumber *)visibility + presence:(nullable NSNumber *)presence NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + +@end + +/** + * Normalized Landmark represents a point in 3D space with x, y, z coordinates. x and y are + * normalized to [0.0, 1.0] by the image width and height respectively. z represents the landmark + * depth, and the smaller the value the closer the landmark is to the camera. The magnitude of z + * uses roughly the same scale as x. + */ +NS_SWIFT_NAME(NormalizedLandmark) +@interface MPPNormalizedLandmark : NSObject + +/** The x coordinates of the landmark. */ +@property(nonatomic, readonly) float x; + +/** The y coordinates of the landmark. */ +@property(nonatomic, readonly) float y; + +/** The z coordinates of the landmark. */ +@property(nonatomic, readonly) float z; + +/** + * Landmark visibility. Should be `nil` if not supported. Float score of whether landmark is visible + * or occluded by other objects. Landmark considered as invisible also if it is not present on the + * screen (out of scene bounds). Depending on the model, visibility value is either a sigmoid or an + * argument of sigmoid. + */ +@property(nonatomic, readonly, nullable) NSNumber *visibility; + +/** + * Landmark presence. Should stay unset if not supported. Float score of whether landmark is present + * on the scene (located within scene bounds). Depending on the model, presence value is either a + * result of sigmoid or an argument of sigmoid function to get landmark presence probability. + */ +@property(nonatomic, readonly) NSNumber *presence; + +/** + * Initializes a new `MPPNormalizedLandmark` object with the given x, y and z coordinates. + * + * @param x The x coordinates of the landmark. + * @param y The y coordinates of the landmark. + * @param z The z coordinates of the landmark. + * + * @return An instance of `MPPNormalizedLandmark` initialized with the given x, y and z coordinates. + */ +- (instancetype)initWithX:(float)x + y:(float)y + z:(float)z + visibility:(nullable NSNumber *)visibility + presence:(nullable NSNumber *)presence NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/components/containers/sources/MPPLandmark.m b/mediapipe/tasks/ios/components/containers/sources/MPPLandmark.m new file mode 100644 index 000000000..2617c7b9d --- /dev/null +++ b/mediapipe/tasks/ios/components/containers/sources/MPPLandmark.m @@ -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. + +#import "mediapipe/tasks/ios/components/containers/sources/MPPLandmark.h" + +static const float kFloatDifferenceTolerance = 1e-6f; + +@implementation MPPLandmark + +- (instancetype)initWithX:(float)x + y:(float)y + z:(float)z + visibility:(NSNumber *)visibility + presence:(NSNumber *)presence { + self = [super init]; + if (self) { + _x = x; + _y = y; + _z = z; + _visibility = visibility; + _presence = presence; + } + return self; +} + +- (NSUInteger)hash { + return @(self.x).hash ^ @(self.y).hash ^ @(self.z).hash; +} + +- (BOOL)isEqual:(nullable id)object { + if (!object) { + return NO; + } + + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[MPPLandmark class]]) { + return NO; + } + + MPPLandmark *otherLandmark = (MPPLandmark *)object; + + return fabsf(otherLandmark.x - self.x) < kFloatDifferenceTolerance && + fabsf(otherLandmark.y - self.y) < kFloatDifferenceTolerance && + fabsf(otherLandmark.z - self.z) < kFloatDifferenceTolerance; +} + +@end + +@implementation MPPNormalizedLandmark + +- (instancetype)initWithX:(float)x + y:(float)y + z:(float)z + visibility:(NSNumber *)visibility + presence:(NSNumber *)presence { + self = [super init]; + if (self) { + _x = x; + _y = y; + _z = z; + _visibility = visibility; + _presence = presence; + } + return self; +} + +- (NSUInteger)hash { + return @(self.x).hash ^ @(self.y).hash ^ @(self.z).hash; +} + +- (BOOL)isEqual:(nullable id)object { + if (!object) { + return NO; + } + + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[MPPNormalizedLandmark class]]) { + return NO; + } + + MPPNormalizedLandmark *otherLandmark = (MPPNormalizedLandmark *)object; + + return fabsf(otherLandmark.x - self.x) < kFloatDifferenceTolerance && + fabsf(otherLandmark.y - self.y) < kFloatDifferenceTolerance && + fabsf(otherLandmark.z - self.z) < kFloatDifferenceTolerance; +} + +@end