Fix/classification streaming support#448
Conversation
Add classification result processing in convertResultToStreamData() to enable real-time classification streaming via YOLOView. Previously, classification worked for single image prediction (PR ultralytics#418) but returned empty results for real-time streaming because convertResultToStreamData() didn't process result.probs. This change adds classification handling that: - Checks config.includeClassifications and result.probs - Creates detection object with classification results - Adds full-image bounding box for consistency - Includes appropriate debug logging Tested with yolo11n-cls.tflite model on Android device. Related to: PR ultralytics#418
Add classification result processing (top5) in convertResultToStreamData() to enable real-time classification streaming via YOLOView on iOS. This complements the Android fix (commit bb98008).
|
👋 Hello @dmjtian, thank you for submitting a -✅ Define a Purpose: Clearly explain the purpose of your fix or feature in your PR description, and link to any relevant issues. Ensure your commit messages are clear, concise, and adhere to the project's conventions. For more guidance, please refer to our Contributing Guide. Don't hesitate to leave a comment if you have any questions. Thank you for contributing to Ultralytics! 🚀 |
UltralyticsAssistant
left a comment
There was a problem hiding this comment.
🔍 PR Review
Made with ❤️ by Ultralytics Actions
Overall looks good and aligns with the goal. One issue: the Android classification block can drop existing detections due to a narrow cast; switching to a generic list copy will preserve prior detections.
💬 Posted 1 inline comment
Co-authored-by: Ultralytics Assistant <135830346+UltralyticsAssistant@users.noreply.github.com> Signed-off-by: dmjtian <31685068+dmjtian@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Logs:
Classifier succeeds but results array is empty because
convertResultToStreamData()doesn't processresult.probs.Root Cause
The
convertResultToStreamData()method in both platforms handles:result.boxes)result.keypointsList)result.obb)result.probs) - MISSINGAffected files:
android/src/main/kotlin/com/ultralytics/yolo/YOLOView.ktios/Classes/YOLOView.swiftSolution
Add classification result processing in
convertResultToStreamData()method on both platforms, similar to how other task types are handled.Code Changes
Android Implementation
File:
android/src/main/kotlin/com/ultralytics/yolo/YOLOView.ktLocation: After line ~1668 (after the
includeDetectionsblock ends)Status: ✅ Completed (Commit: bb98008)
Add this code block:
iOS Implementation
File:
ios/Classes/YOLOView.swiftLocation: After line ~1768 (after the
includeDetectionsblock ends)Status: ✅ Completed (Commit: dced377)
Add this code block:
Key Difference: iOS returns top5 results while Android returns top1 only.
Optional but recommended: Update the log message to include probs count:
Before:
After:
Testing
Test Environment
yolo11n-cls.tflite(Android) /yolo11n-cls.mlpackage(iOS)YOLOTask.classifyBefore Fix
After Fix
Android:
iOS:
Test Code
Design Decisions
Why add to
detectionsarray?YOLOResult.fromMap()deserializationWhy use full image bounding box?
Why check
config.includeClassifications?YOLOStreamingConfigsettingsImpact
Fixed
YOLOViewwithonResultreturns classification resultsNot Affected
YOLO.predict()) - already works (PR Fix Android CLASSIFY task: ensure FloatArray compatibility (Issue #413 follow-up) #418)Platform Differences
Related
Checklist
Notes
This PR implements classification streaming support for both Android and iOS platforms.
Implementation Details:
YOLOView.kt): Returns top1 classification resultYOLOView.swift): Returns top5 classification resultsCommits:
bb98008: Android implementation (2026-02-14)dced377: iOS implementation (2026-02-25)Both implementations follow the same design pattern and maintain consistency with other task types.
Author: @dmjtian (original contributor of PR #418)