added fps support

This commit is contained in:
Mautisim Munir 2022-10-21 13:35:56 +05:00
parent 80815435ce
commit a49d98c171
7 changed files with 96 additions and 11 deletions

View File

@ -24,7 +24,7 @@
<rect key="frame" x="8" y="86" width="200" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="Show Landmarks (ON)" titleAlignment="center"/>
<buttonConfiguration key="configuration" style="plain" title="LANDMARKS (ON)" titleAlignment="center"/>
<connections>
<action selector="showLandmarksButtonTouchWithSender:" destination="BYZ-38-t0r" eventType="touchDown" id="rE9-Y7-U5g"/>
</connections>
@ -49,12 +49,20 @@
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hSQ-so-ykH">
<rect key="frame" x="20" y="133" width="374" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<connections>
<outlet property="chooseModelButton" destination="oaC-Ax-V0a" id="Knp-ll-Zgu"/>
<outlet property="fpsLabel" destination="hSQ-so-ykH" id="sw5-ik-ro9"/>
<outlet property="liveView" destination="8bC-Xf-vdC" id="COw-5j-lAL"/>
<outlet property="showLandmarksButton" destination="dv5-h1-tjP" id="xXW-UG-aSR"/>
<outlet property="titleview" destination="1BO-kg-lOt" id="uP4-0G-Gix"/>

View File

@ -14,6 +14,7 @@ class ViewController: UIViewController {
@IBOutlet var showLandmarksButton: UIButton!
@IBOutlet var chooseModelButton: UIButton!
@IBOutlet var titleview: UIView!
@IBOutlet var fpsLabel: UILabel!
func updateLandmarksButtonText(){
if (lindera.areLandmarksShown()){
@ -94,9 +95,10 @@ class ViewController: UIViewController {
/// 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{
print("LinderaDelegateImpl: Nose Keypoint (\(String(describing: kpt.position.x)),\(String(describing: kpt.position.y)),\(kpt.position.z)) with confidence \(kpt.confidence)")
}
// 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)")
// }
}
@ -131,8 +133,15 @@ class ViewController: UIViewController {
lindera.startCamera()
self.lindera.setFpsDelegate(fpsDelegate: {[weak self] fps in
DispatchQueue.main.async {
self?.fpsLabel.text = "\(Int(fps)) fps"
}
})
self.liveView.bringSubviewToFront(titleview)
self.liveView.bringSubviewToFront(fpsLabel)
updateLandmarksButtonText()
updateModelButtonText()

View File

@ -42,6 +42,9 @@
// Codeblock that runs whenever pose tracking results are available
@property(nonatomic) void(^poseTrackingResultsListener)(PoseTrackingResults*);
// Codeblock that runs whenever output is available
@property(nonatomic) void(^graphOutputStreamListener)();
- (instancetype) initWithPoseTrackingOptions: (PoseTrackingOptions*) poseTrackingOptions;
- (void)startGraph;
- (void) startWithCamera: (MPPCameraInputSource*) cameraSource;

View File

@ -16,6 +16,8 @@ static const char* kLandmarksOutputStream = "pose_landmarks";
@property (nonatomic) const char* graphOutputStream;
@property (nonatomic) MPPLayerRenderer* renderer;
@property(nonatomic) void(^poseTrackingResultsListener)(PoseTrackingResults*);
@property(nonatomic) void(^graphOutputStreamListener)();
-(id) initWithMediapipeGraph: (MPPGraph*) graph graphOutputStream: (const char*) graphOutputStream
renderer: (MPPLayerRenderer*) renderer;
@ -47,6 +49,8 @@ static const char* kLandmarksOutputStream = "pose_landmarks";
didOutputPixelBuffer:(CVPixelBufferRef)pixelBuffer
fromStream:(const std::string&)streamName {
if (streamName == self.graphOutputStream) {
self.graphOutputStreamListener();
// Display the captured image on the screen.
CVPixelBufferRetain(pixelBuffer);
dispatch_async(dispatch_get_main_queue(), ^{
@ -163,6 +167,11 @@ static const char* kLandmarksOutputStream = "pose_landmarks";
weakSelf.poseTrackingResultsListener(results);
};
self -> poseTrackingGraphDelegate.graphOutputStreamListener = ^(){
if (weakSelf.graphOutputStream != nil)
weakSelf.graphOutputStreamListener();
};

View File

@ -2,7 +2,7 @@ load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "lindera",
srcs = ["Lindera.swift","Asensei3D.swift"],
srcs = ["Lindera.swift","Asensei3D.swift","utils.swift"],
linkopts = [
"-lc++",
"-std=c++17",

View File

@ -8,6 +8,11 @@ import UIKit
public final class Lindera{
// initalize the PoseTracking api and load models
var poseTracking:PoseTracking = PoseTracking(poseTrackingOptions: PoseTrackingOptions(showLandmarks: true,modelComplexity: 1))
let fpsHelper = FPSHelper(smoothingFactor: 0.95)
public func setFpsDelegate(fpsDelegate: @escaping (_ fps:Double)->Void){
fpsHelper.onFpsUpdate = fpsDelegate;
}
// attach Mediapipe camera helper to our class
let cameraSource = MPPCameraInputSource()
@ -44,10 +49,7 @@ public final class Lindera{
}
// public func getModelComplexity() -> Int{
// return self.poseTracking
// }
// Initializes pipeline parameters and starts mediapipe graph
private lazy var linderaExerciseSession: UIView = {
// this will be the main camera view
@ -70,17 +72,26 @@ public final class Lindera{
}
// call LinderaDelegate on pose tracking results
self.poseTracking.poseTrackingResultsListener = {[weak self] results in
guard let self = self, let results = results else {
return
}
self.delegate?.lindera(self, didDetect: .init(pose: Asensei3DPose.init(results), timestamp: CMTimeGetSeconds(self.poseTracking.timeStamp)))
}
self.poseTracking.graphOutputStreamListener = {[weak self] in
self?.fpsHelper.logTime()
}
self.poseTracking.startGraph()
// attach camera's output with poseTracking object and its videoQueue
self.cameraSource.setDelegate(self.poseTracking, queue: self.poseTracking.videoQueue)
}
public required init(){}
public required init(){
}
public func startCamera(_ completion: ((Result<Void, Error>) -> Void)? = nil) {

View File

@ -0,0 +1,45 @@
//
// utils.swift
// Mediapipe
//
// Created by Mautisim Munir on 21/10/2022.
//
import Foundation
public class FPSHelper{
var smoothingFactor = 0.8
var _fps:Double? = nil
var time: CFAbsoluteTime? = nil
public var onFpsUpdate : ((_ fps:Double)->Void)? = nil
init(smoothingFactor:Double) {
self.smoothingFactor = smoothingFactor
}
public func logTime(){
let currTime = CFAbsoluteTimeGetCurrent()
if (time != nil){
let elapsedTime = currTime - time!
let fps = 1/Double(elapsedTime)
if (_fps == nil){
_fps = fps
}else{
_fps = (1-smoothingFactor)*fps + smoothingFactor*_fps!
}
if (onFpsUpdate != nil){
onFpsUpdate?(_fps!)
}
}
time = currTime
}
}