Skip to content

Commit

Permalink
IOS face landmarker add choose delegate (#361)
Browse files Browse the repository at this point in the history
  • Loading branch information
st-tuanmai authored Mar 26, 2024
1 parent 2a712f8 commit f07b875
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="52l-qN-uG0">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="52l-qN-uG0">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22684"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="UIMenu" message="Requires Xcode 11 or later." minToolsVersion="11.0" requiredIntegratedClassName="UICommandDiff"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
Expand Down Expand Up @@ -260,6 +261,44 @@
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ncO-a4-P4g">
<rect key="frame" x="0.0" y="264.66666666666669" width="393" height="32"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Delegate" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nzM-Za-BTW">
<rect key="frame" x="16" y="7.3333333333333144" width="58" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" showsMenuAsPrimaryAction="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="K43-wJ-xI8">
<rect key="frame" x="353" y="0.0" width="24" height="32"/>
<color key="backgroundColor" red="0.0" green="0.49803921569999998" blue="0.5450980392" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="32" id="XCw-VM-RIa"/>
</constraints>
<color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<menu key="menu" id="k0Y-Uu-EyI">
<children>
<command title="item1" id="nLW-62-17q"/>
<command title="item2" id="YS2-JJ-5o6"/>
</children>
</menu>
<buttonConfiguration key="configuration" style="plain"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="layer.cornerRadius" value="8"/>
</userDefinedRuntimeAttributes>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="K43-wJ-xI8" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="nzM-Za-BTW" secondAttribute="trailing" id="Bin-ou-0gP"/>
<constraint firstItem="nzM-Za-BTW" firstAttribute="leading" secondItem="ncO-a4-P4g" secondAttribute="leading" constant="16" id="OcI-fm-9xd"/>
<constraint firstAttribute="bottom" secondItem="K43-wJ-xI8" secondAttribute="bottom" id="Spr-hh-Lxt"/>
<constraint firstItem="nzM-Za-BTW" firstAttribute="centerY" secondItem="K43-wJ-xI8" secondAttribute="centerY" id="WqV-2b-QKs"/>
<constraint firstItem="K43-wJ-xI8" firstAttribute="top" secondItem="ncO-a4-P4g" secondAttribute="top" id="soh-79-j1x"/>
<constraint firstAttribute="trailing" secondItem="K43-wJ-xI8" secondAttribute="trailing" constant="16" id="zFi-Xg-zDM"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
Expand All @@ -268,6 +307,7 @@
<constraint firstItem="1fr-hY-4II" firstAttribute="trailing" secondItem="0nH-Zx-p69" secondAttribute="trailing" id="5T6-MD-Uko"/>
<constraint firstAttribute="trailing" secondItem="0nH-Zx-p69" secondAttribute="trailing" constant="16" id="5xr-fC-LfQ"/>
<constraint firstItem="jCg-YX-6ga" firstAttribute="leading" secondItem="iaZ-s2-My0" secondAttribute="leading" id="6kr-Ui-TIb"/>
<constraint firstItem="ncO-a4-P4g" firstAttribute="leading" secondItem="AOI-Gh-SLK" secondAttribute="leading" id="7L8-t4-1uR"/>
<constraint firstItem="jCg-YX-6ga" firstAttribute="centerY" secondItem="tad-jn-O5U" secondAttribute="centerY" id="9dd-nl-UN1"/>
<constraint firstItem="0nH-Zx-p69" firstAttribute="leading" secondItem="s05-yK-gXh" secondAttribute="trailing" constant="4" id="Bda-ye-Je2"/>
<constraint firstItem="J1Y-43-5yW" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="06h-cY-2bs" secondAttribute="trailing" id="GMM-8D-3Gb"/>
Expand Down Expand Up @@ -297,7 +337,9 @@
<constraint firstItem="iaZ-s2-My0" firstAttribute="top" secondItem="d2C-9O-82c" secondAttribute="bottom" constant="26" id="pPe-bR-0qO"/>
<constraint firstItem="0Hl-aV-l7w" firstAttribute="top" secondItem="AOI-Gh-SLK" secondAttribute="top" id="rl8-eu-Q06"/>
<constraint firstItem="tad-jn-O5U" firstAttribute="leading" secondItem="ME8-eS-OTB" secondAttribute="trailing" constant="4" id="txK-t9-38i"/>
<constraint firstAttribute="trailing" secondItem="ncO-a4-P4g" secondAttribute="trailing" id="uFa-hO-jLo"/>
<constraint firstItem="dzb-pb-2Oi" firstAttribute="leading" secondItem="iaZ-s2-My0" secondAttribute="leading" id="uPl-xe-HGE"/>
<constraint firstItem="ncO-a4-P4g" firstAttribute="top" secondItem="tad-jn-O5U" secondAttribute="bottom" constant="12" id="uuD-Lq-tTO"/>
<constraint firstItem="1fr-hY-4II" firstAttribute="centerY" secondItem="06h-cY-2bs" secondAttribute="centerY" id="whL-o0-qmm"/>
<constraint firstAttribute="trailing" secondItem="tZo-oH-ToE" secondAttribute="trailing" id="xSe-Ss-8WB"/>
<constraint firstItem="tZo-oH-ToE" firstAttribute="top" secondItem="AOI-Gh-SLK" secondAttribute="top" id="yoR-Hn-w9J"/>
Expand All @@ -316,6 +358,7 @@
</view>
<navigationItem key="navigationItem" id="BIS-1q-gQH"/>
<connections>
<outlet property="chooseDelegateButton" destination="K43-wJ-xI8" id="vHs-yd-RCg"/>
<outlet property="inferenceTimeLabel" destination="cRO-ho-FXh" id="E3e-km-74r"/>
<outlet property="inferenceTimeNameLabel" destination="d2C-9O-82c" id="O7p-Pr-lsE"/>
<outlet property="minFaceDetectionConfidenceStepper" destination="0nH-Zx-p69" id="UPk-Tc-SO0"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import Foundation
import UIKit
import MediaPipeTasksVision

// MARK: Define default constants
struct DefaultConstants {
Expand All @@ -35,4 +36,41 @@ struct DefaultConstants {
static var minFacePresenceConfidence: Float = 0.5
static var minTrackingConfidence: Float = 0.5
static let modelPath: String? = Bundle.main.path(forResource: "face_landmarker", ofType: "task")
static let delegate: FaceLandmarkerDelegate = .CPU
}

// MARK: FaceLandmarkerDelegate
enum FaceLandmarkerDelegate: CaseIterable {
case GPU
case CPU

var name: String {
switch self {
case .GPU:
return "GPU"
case .CPU:
return "CPU"
}
}

var delegate: Delegate {
switch self {
case .GPU:
return .GPU
case .CPU:
return .CPU
}
}

init?(name: String) {
switch name {
case FaceLandmarkerDelegate.CPU.name:
self = FaceLandmarkerDelegate.CPU
case FaceLandmarkerDelegate.GPU.name:
self = FaceLandmarkerDelegate.GPU
default:
return nil
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class InferenceConfigurationManager: NSObject {
didSet { postConfigChangedNotification() }
}

var delegate: FaceLandmarkerDelegate = DefaultConstants.delegate {
didSet { postConfigChangedNotification() }
}

static let sharedInstance = InferenceConfigurationManager()

static let notificationName = Notification.Name.init(rawValue: "com.google.mediapipe.inferenceConfigChanged")
Expand All @@ -46,5 +50,4 @@ class InferenceConfigurationManager: NSObject {
NotificationCenter.default
.post(name: InferenceConfigurationManager.notificationName, object: nil)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,26 @@ class FaceLandmarkerService: NSObject {
private var minFaceDetectionConfidence: Float
private var minFacePresenceConfidence: Float
private var minTrackingConfidence: Float
var modelPath: String
private var modelPath: String
private var delegate: FaceLandmarkerDelegate


// MARK: - Custom Initializer
private init?(modelPath: String?,
runningMode:RunningMode,
numFaces: Int,
minFaceDetectionConfidence: Float,
minFacePresenceConfidence: Float,
minTrackingConfidence: Float) {
minTrackingConfidence: Float,
delegate: FaceLandmarkerDelegate) {
guard let modelPath = modelPath else { return nil }
self.modelPath = modelPath
self.runningMode = runningMode
self.numFaces = numFaces
self.minFaceDetectionConfidence = minFaceDetectionConfidence
self.minFacePresenceConfidence = minFacePresenceConfidence
self.minTrackingConfidence = minTrackingConfidence
self.delegate = delegate
super.init()

createFaceLandmarker()
Expand All @@ -77,6 +81,7 @@ class FaceLandmarkerService: NSObject {
faceLandmarkerOptions.minFacePresenceConfidence = minFacePresenceConfidence
faceLandmarkerOptions.minTrackingConfidence = minTrackingConfidence
faceLandmarkerOptions.baseOptions.modelAssetPath = modelPath
faceLandmarkerOptions.baseOptions.delegate = delegate.delegate
if runningMode == .liveStream {
faceLandmarkerOptions.faceLandmarkerLiveStreamDelegate = self
}
Expand All @@ -95,14 +100,16 @@ class FaceLandmarkerService: NSObject {
minFaceDetectionConfidence: Float,
minFacePresenceConfidence: Float,
minTrackingConfidence: Float,
videoDelegate: FaceLandmarkerServiceVideoDelegate?) -> FaceLandmarkerService? {
videoDelegate: FaceLandmarkerServiceVideoDelegate?,
delegate: FaceLandmarkerDelegate) -> FaceLandmarkerService? {
let faceLandmarkerService = FaceLandmarkerService(
modelPath: modelPath,
runningMode: .video,
numFaces: numFaces,
minFaceDetectionConfidence: minFaceDetectionConfidence,
minFacePresenceConfidence: minFacePresenceConfidence,
minTrackingConfidence: minTrackingConfidence)
minTrackingConfidence: minTrackingConfidence,
delegate: delegate)
faceLandmarkerService?.videoDelegate = videoDelegate
return faceLandmarkerService
}
Expand All @@ -113,14 +120,16 @@ class FaceLandmarkerService: NSObject {
minFaceDetectionConfidence: Float,
minFacePresenceConfidence: Float,
minTrackingConfidence: Float,
liveStreamDelegate: FaceLandmarkerServiceLiveStreamDelegate?) -> FaceLandmarkerService? {
liveStreamDelegate: FaceLandmarkerServiceLiveStreamDelegate?,
delegate: FaceLandmarkerDelegate) -> FaceLandmarkerService? {
let faceLandmarkerService = FaceLandmarkerService(
modelPath: modelPath,
runningMode: .liveStream,
numFaces: numFaces,
minFaceDetectionConfidence: minFaceDetectionConfidence,
minFacePresenceConfidence: minFacePresenceConfidence,
minTrackingConfidence: minTrackingConfidence)
minTrackingConfidence: minTrackingConfidence,
delegate: delegate)
faceLandmarkerService?.liveStreamDelegate = liveStreamDelegate

return faceLandmarkerService
Expand All @@ -131,14 +140,16 @@ class FaceLandmarkerService: NSObject {
numFaces: Int,
minFaceDetectionConfidence: Float,
minFacePresenceConfidence: Float,
minTrackingConfidence: Float) -> FaceLandmarkerService? {
minTrackingConfidence: Float,
delegate: FaceLandmarkerDelegate) -> FaceLandmarkerService? {
let faceLandmarkerService = FaceLandmarkerService(
modelPath: modelPath,
runningMode: .image,
numFaces: numFaces,
minFaceDetectionConfidence: minFaceDetectionConfidence,
minFacePresenceConfidence: minFacePresenceConfidence,
minTrackingConfidence: minTrackingConfidence)
minTrackingConfidence: minTrackingConfidence,
delegate: delegate)

return faceLandmarkerService
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class BottomSheetViewController: UIViewController {
@IBOutlet weak var minTrackingConfidenceValueLabel: UILabel!

@IBOutlet weak var toggleBottomSheetButton: UIButton!
@IBOutlet weak var chooseDelegateButton: UIButton!

// MARK: Instance Variables
var isUIEnabled: Bool = false {
Expand Down Expand Up @@ -77,8 +78,29 @@ class BottomSheetViewController: UIViewController {

minTrackingConfidenceStepper.value = Double(InferenceConfigurationManager.sharedInstance.minTrackingConfidence)
minTrackingConfidenceValueLabel.text = "\(InferenceConfigurationManager.sharedInstance.minTrackingConfidence)"

// Chose delegate option
let selectedDelegateAction = {(action: UIAction) in
self.updateDelegate(title: action.title)
}
let delegateActions: [UIAction] = FaceLandmarkerDelegate.allCases.compactMap { delegate in
return UIAction(
title: delegate.name,
state: (InferenceConfigurationManager.sharedInstance.delegate == delegate) ? .on : .off,
handler: selectedDelegateAction
)
}

chooseDelegateButton.menu = UIMenu(children: delegateActions)
chooseDelegateButton.showsMenuAsPrimaryAction = true
chooseDelegateButton.changesSelectionAsPrimaryAction = true
}


private func updateDelegate(title: String) {
guard let delegate = FaceLandmarkerDelegate(name: title) else { return }
InferenceConfigurationManager.sharedInstance.delegate = delegate
}

private func enableOrDisableClicks() {
numFacesStepper.isEnabled = isUIEnabled
minFaceDetectionConfidenceStepper.isEnabled = isUIEnabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ class CameraViewController: UIViewController {
minFaceDetectionConfidence: InferenceConfigurationManager.sharedInstance.minFaceDetectionConfidence,
minFacePresenceConfidence: InferenceConfigurationManager.sharedInstance.minFacePresenceConfidence,
minTrackingConfidence: InferenceConfigurationManager.sharedInstance.minTrackingConfidence,
liveStreamDelegate: self)
liveStreamDelegate: self,
delegate: InferenceConfigurationManager.sharedInstance.delegate)
}

private func clearFaceLandmarkerServiceOnSessionInterruption() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,15 +300,17 @@ extension MediaLibraryViewController: UIImagePickerControllerDelegate, UINavigat
numFaces: InferenceConfigurationManager.sharedInstance.numFaces,
minFaceDetectionConfidence: InferenceConfigurationManager.sharedInstance.minFaceDetectionConfidence,
minFacePresenceConfidence: InferenceConfigurationManager.sharedInstance.minFacePresenceConfidence,
minTrackingConfidence: InferenceConfigurationManager.sharedInstance.minTrackingConfidence)
minTrackingConfidence: InferenceConfigurationManager.sharedInstance.minTrackingConfidence,
delegate: InferenceConfigurationManager.sharedInstance.delegate)
case .video:
faceLandmarkerService = FaceLandmarkerService.videoFaceLandmarkerService(
modelPath: InferenceConfigurationManager.sharedInstance.modelPath,
numFaces: InferenceConfigurationManager.sharedInstance.numFaces,
minFaceDetectionConfidence: InferenceConfigurationManager.sharedInstance.minFaceDetectionConfidence,
minFacePresenceConfidence: InferenceConfigurationManager.sharedInstance.minFacePresenceConfidence,
minTrackingConfidence: InferenceConfigurationManager.sharedInstance.minTrackingConfidence,
videoDelegate: self)
videoDelegate: self,
delegate: InferenceConfigurationManager.sharedInstance.delegate)
default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class RootViewController: UIViewController {

// MARK: Constants
private struct Constants {
static let inferenceBottomHeight = 260.0
static let inferenceBottomHeight = 304.0
static let expandButtonHeight = 41.0
static let expandButtonTopSpace = 10.0
static let mediaLibraryViewControllerStoryBoardId = "MEDIA_LIBRARY_VIEW_CONTROLLER"
Expand Down
2 changes: 1 addition & 1 deletion examples/face_landmarker/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ target 'FaceLandmarker' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!

pod 'MediaPipeTasksVision', '0.10.5'
pod 'MediaPipeTasksVision', '0.10.12'

end

Expand Down
Loading

0 comments on commit f07b875

Please sign in to comment.