Changed iOS object detector async calls to delegates

This commit is contained in:
Prianka Liz Kariat 2023-05-02 07:28:42 +05:30
parent 86269722ba
commit eebe498ce1
3 changed files with 64 additions and 27 deletions

View File

@ -51,6 +51,7 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG
/** iOS Vision Task Runner */ /** iOS Vision Task Runner */
MPPVisionTaskRunner *_visionTaskRunner; MPPVisionTaskRunner *_visionTaskRunner;
} }
@property(nonatomic, weak) id<MPPObjectDetectorDelegate> objectDetectorDelegate;
@end @end
@implementation MPPObjectDetector @implementation MPPObjectDetector
@ -78,11 +79,15 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG
PacketsCallback packetsCallback = nullptr; PacketsCallback packetsCallback = nullptr;
if (options.completion) { if (options.objectDetectorDelegate) {
_objectDetectorDelegate = options.objectDetectorDelegate;
packetsCallback = [=](absl::StatusOr<PacketMap> statusOrPackets) { packetsCallback = [=](absl::StatusOr<PacketMap> statusOrPackets) {
NSError *callbackError = nil; NSError *callbackError = nil;
if (![MPPCommonUtils checkCppError:statusOrPackets.status() toError:&callbackError]) { if (![MPPCommonUtils checkCppError:statusOrPackets.status() toError:&callbackError]) {
options.completion(nil, Timestamp::Unset().Value(), callbackError); [_objectDetectorDelegate objectDetector:self
didFinishDetectionWithResult:nil
timestampInMilliseconds:Timestamp::Unset().Value()
error:callbackError];
return; return;
} }
@ -95,24 +100,28 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG
objectDetectionResultWithDetectionsPacket:statusOrPackets.value()[kDetectionsStreamName objectDetectionResultWithDetectionsPacket:statusOrPackets.value()[kDetectionsStreamName
.cppString]]; .cppString]];
options.completion(result, [_objectDetectorDelegate objectDetector:self
outputPacketMap[kImageOutStreamName.cppString].Timestamp().Value() / didFinishDetectionWithResult:result
kMicroSecondsPerMilliSecond, timestampInMilliseconds:outputPacketMap[kImageOutStreamName.cppString]
callbackError); .Timestamp()
}; .Value() /
} kMicroSecondsPerMilliSecond
error:callbackError];
_visionTaskRunner = }
[[MPPVisionTaskRunner alloc] initWithCalculatorGraphConfig:[taskInfo generateGraphConfig] };
runningMode:options.runningMode
packetsCallback:std::move(packetsCallback)
error:error];
if (!_visionTaskRunner) {
return nil;
}
} }
return self;
_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 { - (instancetype)initWithModelPath:(NSString *)modelPath error:(NSError **)error {
@ -224,5 +233,4 @@ static NSString *const kTaskGraphName = @"mediapipe.tasks.vision.ObjectDetectorG
return [_visionTaskRunner processLiveStreamPacketMap:inputPacketMap.value() error:error]; return [_visionTaskRunner processLiveStreamPacketMap:inputPacketMap.value() error:error];
} }
@end @end

View File

@ -20,19 +20,48 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class MPPObjectDetector;
/**
* This protocol defines an interface for the delegates of `MPPImageClassifier` object to receive
* results of performing asynchronous object detection on images
* (i.e, when `runningMode` = `MPPRunningModeLiveStream`).
*
* The delegate of `MPPImageClassifier` must adopt `MPPImageClassifierDelegate` protocol.
* The methods in this protocol are optional.
* TODO: Add parameter `MPPImage` in the callback.
*/
@protocol MPPObjectDetectorDelegate <NSObject>
@required
- (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`. */ /** Options for setting up a `MPPObjectDetector`. */
NS_SWIFT_NAME(ObjectDetectorOptions) NS_SWIFT_NAME(ObjectDetectorOptions)
@interface MPPObjectDetectorOptions : MPPTaskOptions <NSCopying> @interface MPPObjectDetectorOptions : MPPTaskOptions <NSCopying>
/**
* 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; @property(nonatomic) MPPRunningMode runningMode;
/** /**
* The user-defined result callback for processing live stream data. The result callback should only * An object that confirms to `MPPObjectDetectorDelegate` protocol. This object must implement
* be specified when the running mode is set to the live stream mode. * `objectDetector:didFinishDetectionWithResult:timestampInMilliseconds:error:`
* TODO: Add parameter `MPPImage` in the callback. * to receive the results of performing asynchronous object detection on images (i.e, when
* `runningMode` = `MPPRunningModeLiveStream`).
*/ */
@property(nonatomic, copy) void (^completion) @property(nonatomic, weak) id<MPPObjectDetectorDelegate> objectDetectorDelegate;
(MPPObjectDetectionResult *__nullable result, NSInteger timestampMs, NSError *error);
/** /**
* The locale to use for display names specified through the TFLite Model Metadata, if any. Defaults * The locale to use for display names specified through the TFLite Model Metadata, if any. Defaults

View File

@ -33,7 +33,7 @@
objectDetectorOptions.categoryDenylist = self.categoryDenylist; objectDetectorOptions.categoryDenylist = self.categoryDenylist;
objectDetectorOptions.categoryAllowlist = self.categoryAllowlist; objectDetectorOptions.categoryAllowlist = self.categoryAllowlist;
objectDetectorOptions.displayNamesLocale = self.displayNamesLocale; objectDetectorOptions.displayNamesLocale = self.displayNamesLocale;
objectDetectorOptions.completion = self.completion; objectDetectorOptions.objectDetectorDelegate = self.objectDetectorDelegate;
return objectDetectorOptions; return objectDetectorOptions;
} }