This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

refactor: combine logic to shared function for analysis in android

+80 -82
+8 -35
posedetection/src/androidMain/kotlin/com.performancecoachlab/posedetection/camera/CameraView.android.kt
··· 50 50 import com.performancecoachlab.posedetection.objects.createObjectDetector 51 51 import com.performancecoachlab.posedetection.recording.AnalysisObject 52 52 import com.performancecoachlab.posedetection.recording.AnalysisResult 53 - import kotlinx.coroutines.delay 54 53 import kotlinx.coroutines.launch 55 54 56 55 @OptIn(ExperimentalGetImage::class) ··· 140 139 val img = InputImage.fromMediaImage( 141 140 image, imageProxy.imageInfo.rotationDegrees 142 141 ) 143 - val objectDetectionTask = objectDetector?.process(img)?.addOnSuccessListener { detectedObjects -> 144 - detectedObjects.map { detectedObject -> 145 - AnalysisObject( 146 - boundingBox = Rect( 147 - left = detectedObject.boundingBox.left.toFloat(), 148 - top = detectedObject.boundingBox.top.toFloat(), 149 - right = detectedObject.boundingBox.right.toFloat(), 150 - bottom = detectedObject.boundingBox.bottom.toFloat() 151 - ), 152 - trackingId = detectedObject.trackingId, 153 - labels = detectedObject.labels.mapNotNull { if(it.confidence>0)it.text else null } 154 - ) 155 - }.also { 156 - objectsDetected = it 157 - customObjectRepository.updateCustomObject(it) 142 + img.process(objectDetector, poseDetector,timestamp){ 143 + customObjectRepository.updateCustomObject(it.objects) 144 + it.skeleton?.let { skel -> 145 + skeletonRepository.updateSkeleton(skel.mirror()) 158 146 } 159 - }?.addOnFailureListener { e -> 160 - println(e) 161 - } 162 - 163 - val poseDetectionTask = poseDetector.process(img).addOnSuccessListener { pose -> 164 - skeleton = skeleton(pose, timestamp, img.width, img.height) 165 - skeletonRepository.updateSkeleton(skeleton.mirror()) 166 - }.addOnFailureListener { e -> 167 - println(e) 168 - } 169 - 170 - Tasks.whenAllComplete(objectDetectionTask, poseDetectionTask).addOnCompleteListener { 171 147 bitmap = 172 148 imageProxy.toBitmap().rotate(imageProxy.imageInfo.rotationDegrees.toFloat()) 173 - .asImageBitmap().let { 174 - addFrame(it,timestamp) 149 + .asImageBitmap().let { inbmp -> 150 + addFrame(inbmp,timestamp) 175 151 if( drawSkeleton) { 176 - it.drawAnalysisResults(AnalysisResult( 177 - skeleton = skeleton, 178 - objects = objectsDetected 179 - )) 152 + inbmp.drawAnalysisResults(it) 180 153 }else{ 181 - it.drawSkeleton(null) 154 + inbmp.drawSkeleton(null) 182 155 } 183 156 } 184 157 imageProxy.close()
+58
posedetection/src/androidMain/kotlin/com/performancecoachlab/posedetection/camera/Utils.android.kt
··· 1 1 package com.performancecoachlab.posedetection.camera 2 2 3 + import androidx.compose.runtime.getValue 4 + import androidx.compose.runtime.mutableStateOf 5 + import androidx.compose.runtime.remember 6 + import androidx.compose.runtime.setValue 7 + import androidx.compose.ui.geometry.Rect 8 + import androidx.compose.ui.graphics.asImageBitmap 9 + import com.google.android.gms.tasks.Tasks 10 + import com.google.mlkit.vision.common.InputImage 11 + import com.google.mlkit.vision.objects.ObjectDetector 12 + import com.google.mlkit.vision.pose.PoseDetector 13 + import com.performancecoachlab.posedetection.recording.AnalysisObject 14 + import com.performancecoachlab.posedetection.recording.AnalysisResult 15 + import com.performancecoachlab.posedetection.skeleton.Skeleton 16 + 3 17 actual enum class PlatformType { 4 18 ANDROID, IOS; 5 19 ··· 7 21 actual fun getCurrentPlatform(): PlatformType = ANDROID 8 22 } 9 23 24 + } 25 + 26 + fun InputImage.process( 27 + objectDetector: ObjectDetector?, 28 + poseDetector: PoseDetector, 29 + timestamp: Long, 30 + onComplete: (AnalysisResult) -> Unit, 31 + ) { 32 + var skeleton: Skeleton? = null 33 + var objectsDetected :List<AnalysisObject> = emptyList() 34 + 35 + val objectDetectionTask = objectDetector?.process(this)?.addOnSuccessListener { detectedObjects -> 36 + detectedObjects.map { detectedObject -> 37 + AnalysisObject( 38 + boundingBox = Rect( 39 + left = detectedObject.boundingBox.left.toFloat(), 40 + top = detectedObject.boundingBox.top.toFloat(), 41 + right = detectedObject.boundingBox.right.toFloat(), 42 + bottom = detectedObject.boundingBox.bottom.toFloat() 43 + ), 44 + trackingId = detectedObject.trackingId, 45 + labels = detectedObject.labels.mapNotNull { if(it.confidence>0)it.text else null } 46 + ) 47 + }.also { 48 + objectsDetected = it 49 + } 50 + }?.addOnFailureListener { e -> 51 + println(e) 52 + } 53 + 54 + val poseDetectionTask = poseDetector.process(this).addOnSuccessListener { pose -> 55 + skeleton = skeleton(pose, timestamp, width, height) 56 + }.addOnFailureListener { e -> 57 + println(e) 58 + } 59 + 60 + Tasks.whenAllComplete(objectDetectionTask, poseDetectionTask).addOnCompleteListener { 61 + onComplete( 62 + AnalysisResult( 63 + skeleton = skeleton, 64 + objects = objectsDetected 65 + ) 66 + ) 67 + } 10 68 }
+8 -42
posedetection/src/androidMain/kotlin/com/performancecoachlab/posedetection/recording/InputFrame.android.kt
··· 9 9 import com.google.mlkit.vision.pose.defaults.PoseDetectorOptions 10 10 import com.performancecoachlab.posedetection.camera.drawAnalysisResults 11 11 import com.performancecoachlab.posedetection.camera.drawSkeleton 12 + import com.performancecoachlab.posedetection.camera.process 12 13 import com.performancecoachlab.posedetection.camera.skeleton 13 14 import com.performancecoachlab.posedetection.custom.CustomObjectModel 14 15 import com.performancecoachlab.posedetection.objects.createObjectDetector ··· 39 40 actual suspend fun analyseFrame(inputFrame: InputFrame): AnalysisResult = 40 41 suspendCancellableCoroutine { continuation -> 41 42 val img = InputImage.fromBitmap(inputFrame.bitmap, 0) 42 - var poseResult: Skeleton? = null 43 - var objectResults: List<AnalysisObject>? = null 44 - var completed = 0 45 - 46 - fun tryResume() { 47 - completed++ 48 - if (completed == 2) { 49 - continuation.resume(AnalysisResult(poseResult,objectResults?: emptyList())) 50 - } 51 - } 52 - objectDetector?.let { detector -> 53 - detector.process(img).addOnSuccessListener { 54 - objectResults = it.map { detectedObject -> 55 - val boundingBox = detectedObject.boundingBox.let{ bound-> 56 - Rect( 57 - left = bound.left.toFloat(), 58 - top = bound.top.toFloat(), 59 - right = bound.right.toFloat(), 60 - bottom = bound.bottom.toFloat() 61 - ) 62 - } 63 - val trackingId = detectedObject.trackingId 64 - val labels = detectedObject.labels.map { label -> 65 - label.text 66 - } 67 - AnalysisObject( 68 - boundingBox = boundingBox, 69 - trackingId = trackingId, 70 - labels = labels 71 - ) 72 - } 73 - tryResume() 74 - }.addOnFailureListener { 75 - println(it.message) 76 - tryResume() 43 + img.process( 44 + objectDetector = objectDetector, 45 + poseDetector = poseDetector, 46 + timestamp = inputFrame.timestamp, 47 + onComplete = { result -> 48 + continuation.resume(result) 77 49 } 78 - }?:tryResume() 79 - poseDetector.process(img).addOnSuccessListener { pose -> 80 - poseResult = skeleton(pose, inputFrame.timestamp, img.width, img.height) 81 - tryResume() 82 - }.addOnFailureListener { 83 - tryResume() 84 - } 50 + ) 85 51 } 86 52 }
+6 -5
sample/composeApp/src/commonMain/kotlin/com/nate/posedetection/App.kt
··· 70 70 iosModelPath = "YOLOv3FP16" 71 71 ) 72 72 73 - 74 73 Column { 75 74 TabRow(selectedTabIndex = selectedTabIndex) { 76 75 tabs.forEachIndexed { index, title -> ··· 276 275 var permissionGranted by remember { mutableStateOf(false) } 277 276 var isRecording by remember { mutableStateOf(false) } 278 277 var path by remember { mutableStateOf("") } 278 + var allDetected = remember { mutableListOf<String>() } 279 279 PermissionProvider().apply { 280 280 if (!hasCameraPermission()) RequestCameraPermission(onGranted = { 281 281 permissionGranted = true ··· 350 350 } 351 351 customObjects?.let { 352 352 if (it.isNotEmpty()) { 353 - println("Detected Objects") 354 353 it.forEach { obj -> 355 - println("${obj.labels.firstOrNull()}") 354 + val l = "${obj.labels.firstOrNull()}" 355 + if(!allDetected.contains(l)){ 356 + allDetected.add("${obj.labels.firstOrNull()}") 357 + println(allDetected) 358 + } 356 359 } 357 - } else { 358 - println("No Objects Detected") 359 360 } 360 361 } 361 362 }