This repository has no description
0

Configure Feed

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

fix: correctly handle no model being set for object detection

+74 -90
+1 -1
posedetection/src/androidMain/kotlin/com/performancecoachlab/posedetection/camera/Utils.android.kt
··· 58 58 println(e) 59 59 } 60 60 61 - Tasks.whenAllComplete(objectDetectionTask, poseDetectionTask).addOnCompleteListener { 61 + Tasks.whenAllComplete(listOfNotNull(objectDetectionTask, poseDetectionTask)).addOnCompleteListener { 62 62 onComplete( 63 63 AnalysisResult( 64 64 skeleton = skeleton,
+69 -74
posedetection/src/iosMain/kotlin/com/performancecoachlab/posedetection/camera/FrameProcessor.kt
··· 446 446 } 447 447 memScoped { 448 448 val errorPtr = alloc<ObjCObjectVar<NSError?>>() 449 - if (modelObj == null) { 450 - onObjectsProcessed(emptyList()) 451 - onSkeletonProcessed(null) 452 - return@memScoped 453 - } 454 449 try { 455 - val requestForObjects = VNCoreMLRequest(modelObj) { request, error -> 456 - if (error != null) { 457 - onObjectsProcessed(emptyList()) 458 - return@VNCoreMLRequest 459 - } 460 - val results = request?.results as? List<*> ?: emptyList<Any>() 461 - val recognized = results.filterIsInstance<VNRecognizedObjectObservation>() 462 - val analysisObjects = recognized.map { observation -> 463 - val confidence = observation.confidence 464 - val boundingBox = observation.boundingBox.useContents { 465 - val w = width.toFloat() 466 - val h = height.toFloat() 467 - val left = origin.x * w 468 - val top = (1.0 - origin.y) * h 469 - val right = (origin.x + size.width) * w 470 - val bottom = (1.0 - (origin.y + size.height)) * h 471 - Rect( 472 - left = left.toFloat(), 473 - top = top.toFloat(), 474 - right = right.toFloat(), 475 - bottom = bottom.toFloat() 476 - ) 450 + val requestForObjects = modelObj?.let { 451 + VNCoreMLRequest(it) { request, error -> 452 + if (error != null) { 453 + onObjectsProcessed(emptyList()) 454 + return@VNCoreMLRequest 477 455 } 478 - val labels = observation.labels.mapNotNull { 479 - (it as VNClassificationObservation).let { ca -> 480 - if (ca.confidence > 0.0) Label(ca.identifier,ca.confidence) else null 456 + val results = request?.results as? List<*> ?: emptyList<Any>() 457 + val recognized = results.filterIsInstance<VNRecognizedObjectObservation>() 458 + val analysisObjects = recognized.map { observation -> 459 + val confidence = observation.confidence 460 + val boundingBox = observation.boundingBox.useContents { 461 + val w = width.toFloat() 462 + val h = height.toFloat() 463 + val left = origin.x * w 464 + val top = (1.0 - origin.y) * h 465 + val right = (origin.x + size.width) * w 466 + val bottom = (1.0 - (origin.y + size.height)) * h 467 + Rect( 468 + left = left.toFloat(), 469 + top = top.toFloat(), 470 + right = right.toFloat(), 471 + bottom = bottom.toFloat() 472 + ) 481 473 } 474 + val labels = observation.labels.mapNotNull { 475 + (it as VNClassificationObservation).let { ca -> 476 + if (ca.confidence > 0.0) Label(ca.identifier,ca.confidence) else null 477 + } 478 + } 479 + AnalysisObject( 480 + trackingId = observation.identityHashCode(), 481 + labels = labels, 482 + boundingBox = boundingBox, 483 + ) 482 484 } 483 - AnalysisObject( 484 - trackingId = observation.identityHashCode(), 485 - labels = labels, 486 - boundingBox = boundingBox, 487 - ) 485 + onObjectsProcessed(analysisObjects) 488 486 } 489 - onObjectsProcessed(analysisObjects) 490 487 } 491 488 val options = mapOf<Any?, Any?>( 492 489 "orientation" to AVCaptureVideoOrientationLandscapeRight ··· 546 543 requestForSkeleton.regionOfInterest = regionOfInterest 547 544 val handler = VNImageRequestHandler(cgImage, options) 548 545 handler.performRequests( 549 - listOf(requestForObjects, requestForSkeleton), errorPtr.ptr 546 + listOfNotNull(requestForObjects, requestForSkeleton), errorPtr.ptr 550 547 ) 551 548 if (errorPtr.value != null) { 552 549 println("Error performing object detection request: ${errorPtr.value}") ··· 579 576 val height = 360uL // You may want to get actual height from buffer if needed 580 577 memScoped { 581 578 val errorPtr = alloc<ObjCObjectVar<NSError?>>() 582 - if (modelObj == null) { 583 - onObjectsProcessed(emptyList()) 584 - onSkeletonProcessed(null) 585 - return@memScoped 586 - } 587 579 try { 588 - val requestForObjects = VNCoreMLRequest(modelObj) { request, error -> 589 - if (error != null) { 590 - onObjectsProcessed(emptyList()) 591 - return@VNCoreMLRequest 592 - } 593 - val results = request?.results as? List<*> ?: emptyList<Any>() 594 - val recognized = results.filterIsInstance<VNRecognizedObjectObservation>() 595 - val analysisObjects = recognized.map { observation -> 596 - val confidence = observation.confidence 597 - val boundingBox = observation.boundingBox.useContents { 598 - val w = width.toFloat() 599 - val h = height.toFloat() 600 - val left = origin.x * w 601 - val top = (1.0 - origin.y) * h 602 - val right = (origin.x + size.width) * w 603 - val bottom = (1.0 - (origin.y + size.height)) * h 604 - Rect( 605 - left = left.toFloat(), 606 - top = top.toFloat(), 607 - right = right.toFloat(), 608 - bottom = bottom.toFloat() 609 - ) 580 + val requestForObjects = modelObj?.let { 581 + VNCoreMLRequest(it) { request, error -> 582 + if (error != null) { 583 + onObjectsProcessed(emptyList()) 584 + return@VNCoreMLRequest 610 585 } 611 - val labels = observation.labels.mapNotNull { 612 - (it as VNClassificationObservation).let { ca -> 613 - if (ca.confidence > 0.0) Label(ca.identifier,ca.confidence) else null 586 + val results = request?.results as? List<*> ?: emptyList<Any>() 587 + val recognized = results.filterIsInstance<VNRecognizedObjectObservation>() 588 + val analysisObjects = recognized.map { observation -> 589 + val confidence = observation.confidence 590 + val boundingBox = observation.boundingBox.useContents { 591 + val w = width.toFloat() 592 + val h = height.toFloat() 593 + val left = origin.x * w 594 + val top = (1.0 - origin.y) * h 595 + val right = (origin.x + size.width) * w 596 + val bottom = (1.0 - (origin.y + size.height)) * h 597 + Rect( 598 + left = left.toFloat(), 599 + top = top.toFloat(), 600 + right = right.toFloat(), 601 + bottom = bottom.toFloat() 602 + ) 614 603 } 604 + val labels = observation.labels.mapNotNull { 605 + (it as VNClassificationObservation).let { ca -> 606 + if (ca.confidence > 0.0) Label(ca.identifier,ca.confidence) else null 607 + } 608 + } 609 + AnalysisObject( 610 + trackingId = observation.identityHashCode(), 611 + labels = labels, 612 + boundingBox = boundingBox, 613 + ) 615 614 } 616 - AnalysisObject( 617 - trackingId = observation.identityHashCode(), 618 - labels = labels, 619 - boundingBox = boundingBox, 620 - ) 615 + onObjectsProcessed(analysisObjects) 621 616 } 622 - onObjectsProcessed(analysisObjects) 623 617 } 618 + 624 619 val options = mapOf<Any?, Any?>( 625 620 "orientation" to AVCaptureVideoOrientationLandscapeRight 626 621 ) ··· 679 674 requestForSkeleton.regionOfInterest = regionOfInterest 680 675 val handler = VNImageRequestHandler(buffer, options) 681 676 handler.performRequests( 682 - listOf(requestForObjects, requestForSkeleton), errorPtr.ptr 677 + listOfNotNull(requestForObjects, requestForSkeleton), errorPtr.ptr 683 678 ) 684 679 if (errorPtr.value != null) { 685 680 println("Error performing object detection request: ${errorPtr.value}")
+4 -15
posedetection/src/iosMain/kotlin/com/performancecoachlab/posedetection/recording/InputFrame.ios.kt
··· 36 36 37 37 @OptIn(ExperimentalForeignApi::class) 38 38 fun createObjectDetector(model: String?): VNCoreMLModel? { 39 + if(model == null) { 40 + println("Model path is null") 41 + return null 42 + } 39 43 println("Model input: $model") 40 44 val path = NSBundle.mainBundle.pathForResource(model, "mlmodelc") 41 45 println("Model path: $path") ··· 59 63 return suspendCancellableCoroutine { continuation -> 60 64 var poseResult: Skeleton? = null 61 65 var objectResults: List<AnalysisObject> = emptyList() 62 - /*var completed = 0 63 - fun tryResume() { 64 - completed++ 65 - if (completed == 2) { 66 - continuation.resume(AnalysisResult(poseResult, objectResults)) 67 - } 68 - } 69 - frameProcessor.analyseFrame(img, inputFrame.timestamp, onProccessed = { 70 - poseResult = it 71 - tryResume() 72 - }) 73 - frameProcessor.analyseFrameForObjects(img, inputFrame.timestamp, onProccessed = { 74 - objectResults = it 75 - tryResume() 76 - })*/ 77 66 78 67 frameProcessor.analyseFrameForAll(img, inputFrame.timestamp, onSkeletonProcessed = { 79 68 poseResult = it