diff --git a/mediapipe/tasks/ios/components/containers/BUILD b/mediapipe/tasks/ios/components/containers/BUILD index 36c8ef2e0..06df9576a 100644 --- a/mediapipe/tasks/ios/components/containers/BUILD +++ b/mediapipe/tasks/ios/components/containers/BUILD @@ -44,3 +44,10 @@ objc_library( hdrs = ["sources/MPPEmbeddingResult.h"], deps = [":MPPEmbedding"], ) + +objc_library( + name = "MPPDetection", + srcs = ["sources/MPPDetection.m"], + hdrs = ["sources/MPPDetection.h"], + deps = [":MPPCategory"], +) diff --git a/mediapipe/tasks/ios/components/containers/sources/MPPDetection.h b/mediapipe/tasks/ios/components/containers/sources/MPPDetection.h new file mode 100644 index 000000000..cc7c2ebeb --- /dev/null +++ b/mediapipe/tasks/ios/components/containers/sources/MPPDetection.h @@ -0,0 +1,100 @@ +// Copyright 2023 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import +#import "mediapipe/tasks/ios/components/containers/sources/MPPCategory.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * Normalized keypoint represents a point in 2D space with x, y coordinates. x and y are normalized + * to [0.0, 1.0] by the image width and height respectively. + */ +NS_SWIFT_NAME(NormalizedKeypoint) +@interface MPPNormalizedKeypoint : NSObject + +/** The (x,y) coordinates location of the normalized keypoint. */ +@property(nonatomic, readonly) CGPoint location; + +/** The optional label of the normalized keypoint. */ +@property(nonatomic, readonly, nullable) NSString *label; + +/** The optional score of the normalized keypoint. If score is absent, it will be equal to 0.0. */ +@property(nonatomic, readonly) float score; + +/** + * Initializes a new `MPPNormalizedKeypoint` object with the given location, label and score. + * You must pass 0.0 for `score` if it is not present. + * + * @param location The (x,y) coordinates location of the normalized keypoint. + * @param label The optional label of the normalized keypoint. + * @param score The optional score of the normalized keypoint. You must pass 0.0 for score if it + * is not present. + * + * @return An instance of `MPPNormalizedKeypoint` initialized with the given given location, label + * and score. + */ +- (instancetype)initWithLocation:(CGPoint)location + label:(nullable NSString *)label + score:(float)score NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + +@end + +/** Represents one detected object in the results of `MPPObjectDetector`. */ +NS_SWIFT_NAME(Detection) +@interface MPPDetection : NSObject + +/** An array of `MPPCategory` objects containing the predicted categories. */ +@property(nonatomic, readonly) NSArray *categories; + +/** The bounding box of the detected object. */ +@property(nonatomic, readonly) CGRect boundingBox; + +/** An optional array of `MPPNormalizedKeypoint` objects associated with the detection. Keypoints + * represent interesting points related to the detection. For example, the keypoints represent the + * eyes, 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. */ +@property(nonatomic, readonly, nullable) NSArray *keypoints; + +/** + * Initializes a new `MPPDetection` object with the given array of categories, bounding box and + * optional array of keypoints; + * + * @param categories A list of `MPPCategory` objects that contain category name, display name, + * score, and the label index. + * @param boundingBox A `CGRect` that represents the bounding box. + * @param keypoints: An optional array of `MPPNormalizedKeypoint` objects associated with the + * detection. Keypoints represent interesting points related to the detection. For example, the + * keypoints represent the eyes, 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. + * + * @return An instance of `MPPDetection` initialized with the given array of categories, bounding + * box and `nil` keypoints. + */ +- (instancetype)initWithCategories:(NSArray *)categories + boundingBox:(CGRect)boundingBox + keypoints:(nullable NSArray *)keypoints + 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/MPPDetection.m b/mediapipe/tasks/ios/components/containers/sources/MPPDetection.m new file mode 100644 index 000000000..42259ffde --- /dev/null +++ b/mediapipe/tasks/ios/components/containers/sources/MPPDetection.m @@ -0,0 +1,70 @@ +// Copyright 2023 The 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/MPPDetection.h" + +@implementation MPPNormalizedKeypoint + +- (instancetype)initWithLocation:(CGPoint)location + label:(nullable NSString *)label + score:(float)score { + self = [super init]; + if (self) { + _location = location; + _label = label; + _score = score; + } + return self; +} + +// TODO: Implement hash + +- (BOOL)isEqual:(nullable id)object { + if (!object) { + return NO; + } + + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[MPPNormalizedKeypoint class]]) { + return NO; + } + + MPPNormalizedKeypoint *otherKeypoint = (MPPNormalizedKeypoint *)object; + + if (CGPointEqualToPoint(self.location, otherKeypoint.location) && + (self.label == otherKeypoint.label) && (self.score == otherKeypoint.score)) { + return YES; + } +} + +@end + +@implementation MPPDetection + +- (instancetype)initWithCategories:(NSArray *)categories + boundingBox:(CGRect)boundingBox + keypoints:(nullable NSArray *)keypoints { + self = [super init]; + if (self) { + _categories = categories; + _boundingBox = boundingBox; + _keypoints = keypoints; + } + return self; +} + +@end \ No newline at end of file