214 lines
6.3 KiB
Swift
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()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|