mediapipe/mediapipe/examples/ios/posetracking-lindera/PoseTrackingLindera/ViewController.swift
2022-11-10 03:02:13 +05:00

214 lines
6.3 KiB
Swift

//
// ViewController.swift
// PoseTrackingLindera
//
// Created by Mautisim Munir on 17/10/2022.
//
import UIKit
import LinderaDetection
//import LinderaDetection
import PhotosUI
class ViewController: UIViewController, PHPickerViewControllerDelegate {
// Video Picker
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
for result in results {
result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier){url,err in
if let url = url {
DispatchQueue.main.async {
[weak self] in
picker.dismiss(animated: true)
self?.inputSourceView.isHidden = true
}
let asset = AVAsset(url: url)
self.lindera.startVideo(asset: asset)
}
}
}
//
}
//MARK: - UI Elements
@IBOutlet var liveView : UIView!
@IBOutlet var showLandmarksButton: UIButton!
@IBOutlet var chooseModelButton: UIButton!
@IBOutlet var startCameraButton: UIButton!
@IBOutlet var titleview: UIView!
@IBOutlet var fpsLabel: UILabel!
@IBOutlet var inputSourceView: UIView!
//MARK: - UI Actions
@IBAction func startCamera(){
lindera.startCamera()
inputSourceView.isHidden = true
}
@IBAction func pickVideo(){
var configuration = PHPickerConfiguration(photoLibrary: .shared())
let filter = PHPickerFilter.any(of: [ .videos])
configuration.filter = filter
configuration.selectionLimit = 1
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
present(picker, animated: true)
}
@IBAction func setModelComplexity(){
let alert = UIAlertController(
title: nil,
message: nil,
preferredStyle: .actionSheet
)
alert.addAction(
.init(title: "MODEL (LITE)", style: .default) {[weak self] _ in
self?.lindera.setModelComplexityNow(complexity: 0)
self?.updateModelButtonText()
}
)
alert.addAction(
.init(title: "MODEL (FULL)", style: .default) { [weak self] _ in
self?.lindera.setModelComplexityNow(complexity: 1)
self?.updateModelButtonText()
}
)
alert.addAction(
.init(title: "MODEL (HEAVY)", style: .default) { [weak self] _ in
self?.lindera.setModelComplexityNow(complexity: 2)
self?.updateModelButtonText()
}
)
present(alert, animated: true)
}
@IBAction func showLandmarksButtonTouch(sender: UIButton){
lindera.showLandmarks(value: !lindera.areLandmarksShown());
updateLandmarksButtonText()
}
// MARK: - LinderaDelegate
/// A simple LinderaDelegate implementation that prints nose coordinates if detected
class LinderaDelegateImpl:LinderaDelegate{
func lindera(_ lindera: Lindera, didDetect event: Asensei3DPose.Event) {
// if let kpt = event.pose.nose{
// // Printing causes large drops in FPS
// print("LinderaDelegateImpl: Nose Keypoint (\(String(describing: kpt.position.x)),\(String(describing: kpt.position.y)),\(kpt.position.z)) with confidence \(kpt.confidence)")
// }
}
}
// MARK: - UI Text Modifications
func updateLandmarksButtonText(){
if (lindera.areLandmarksShown()){
showLandmarksButton.setTitle("LANDMARKS (ON)", for: UIControl.State.normal)
}else{
showLandmarksButton.setTitle("LANDMARKS (OFF)", for: UIControl.State.normal)
}
}
func updateModelButtonText(){
var text = "MODEL "
switch(lindera.getModelComplexity()){
case 0:
text += "(LITE)"
break;
case 1:
text += "(FULL)"
break;
case 2:
text += "(HEAVY)"
break;
default:
text += "(Unknown)"
}
chooseModelButton.setTitle(text, for: UIControl.State.normal)
}
// MARK: - State Objects
let lindera = Lindera()
let linderaDelegate = LinderaDelegateImpl()
// MARK: - UI Setup
override func viewDidLoad() {
super.viewDidLoad()
self.lindera.delegate = linderaDelegate
if let view = self.liveView{
// add lindera camera view to our app's UIView i.e. liveView
view.addSubview(lindera.cameraView)
// Expand our cameraView frame to liveView frame
self.lindera.cameraView.frame = view.bounds
// Setting Up Constraints (No necessary with above statement)
self.lindera.cameraView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
self.lindera.cameraView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
self.lindera.cameraView.topAnchor.constraint(equalTo: view.topAnchor),
self.lindera.cameraView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
self.lindera.cameraView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
}
// This function is called whenver there is an fps update
self.lindera.setFpsDelegate(fpsDelegate: {[weak self] fps in
DispatchQueue.main.async {
self?.fpsLabel.text = "\(Int(fps)) fps"
}
})
// Otherwise they are hidden
self.liveView.bringSubviewToFront(titleview)
self.liveView.bringSubviewToFront(fpsLabel)
self.liveView.bringSubviewToFront(inputSourceView)
// Make the Landmarks and Model button text reflect the state in lindera object
updateLandmarksButtonText()
updateModelButtonText()
}
}