diff --git a/app/src/main/java/com/quillstudios/pokegoalshelper/ml/YOLOConfig.kt b/app/src/main/java/com/quillstudios/pokegoalshelper/ml/YOLOConfig.kt new file mode 100644 index 0000000..0cf34d2 --- /dev/null +++ b/app/src/main/java/com/quillstudios/pokegoalshelper/ml/YOLOConfig.kt @@ -0,0 +1,67 @@ +package com.quillstudios.pokegoalshelper.ml + +/** + * Configuration class for YOLO inference engine + * Consolidates all settings in one place for better maintainability + */ +data class YOLOConfig( + // Model settings + val modelFile: String = "best.onnx", + val inputSize: Int = 640, + val numChannels: Int = 3, + val numDetections: Int = 300, + val numClasses: Int = 95, + + // Confidence and NMS thresholds + val confidenceThreshold: Float = 0.55f, + val nmsThreshold: Float = 0.3f, + val iouThreshold: Float = 0.4f, + + // Preprocessing settings + val enableMultiPreprocessing: Boolean = false, // Disabled for mobile performance + val enableTTA: Boolean = true, // Test-time augmentation + val enableUltralyticsPreprocessing: Boolean = true, + val enableContrastEnhancement: Boolean = true, + val enableSharpening: Boolean = true, + val enableNoiseReduction: Boolean = true, + + // Performance settings + val maxInferenceTimeMs: Long = 4500L, // Leave 500ms for other processing + val threadPoolSize: Int = 3, + + // Coordinate transformation mode + val coordinateMode: CoordinateMode = CoordinateMode.HYBRID, + + // Debug settings + val showAllConfidences: Boolean = false, + val classFilter: String? = null +) + +/** + * Coordinate transformation modes + */ +enum class CoordinateMode(val modeName: String) +{ + HYBRID("HYBRID"), + LETTERBOX("LETTERBOX"), + DIRECT("DIRECT"); + + companion object + { + fun fromString(mode: String): CoordinateMode + { + return values().find { it.modeName == mode } ?: HYBRID + } + } +} + +/** + * Preprocessing technique enum + */ +enum class PreprocessingTechnique +{ + ULTRALYTICS, + ENHANCED, + SHARPENED, + ORIGINAL +} \ No newline at end of file diff --git a/app/src/main/java/com/quillstudios/pokegoalshelper/ml/YOLOInferenceEngine.kt b/app/src/main/java/com/quillstudios/pokegoalshelper/ml/YOLOInferenceEngine.kt index f60d271..89e09f6 100644 --- a/app/src/main/java/com/quillstudios/pokegoalshelper/ml/YOLOInferenceEngine.kt +++ b/app/src/main/java/com/quillstudios/pokegoalshelper/ml/YOLOInferenceEngine.kt @@ -27,7 +27,10 @@ import kotlin.math.min * - Weighted NMS and TTA * - Debug and testing features */ -class YOLOInferenceEngine(private val context: Context) : MLInferenceEngine +class YOLOInferenceEngine( + private val context: Context, + private val config: YOLOConfig = YOLOConfig() +) : MLInferenceEngine { companion object { @@ -93,10 +96,10 @@ class YOLOInferenceEngine(private val context: Context) : MLInferenceEngine private var isInitialized = false // Shared thread pool for preprocessing operations (prevents creating new pools per detection) - private val preprocessingExecutor = Executors.newFixedThreadPool(3) + private val preprocessingExecutor = Executors.newFixedThreadPool(config.threadPoolSize) - private var confidenceThreshold = CONFIDENCE_THRESHOLD - private var classFilter: String? = null + private var confidenceThreshold = config.confidenceThreshold + private var classFilter: String? = config.classFilter // Performance tracking private var lastInferenceTime = 0L @@ -215,8 +218,8 @@ class YOLOInferenceEngine(private val context: Context) : MLInferenceEngine ortEnvironment = OrtEnvironment.getEnvironment() // Copy model from assets to internal storage - Log.i(TAG, "📂 Copying model file: $MODEL_FILE") - val model_path = copyAssetToInternalStorage(MODEL_FILE) + Log.i(TAG, "📂 Copying model file: ${config.modelFile}") + val model_path = copyAssetToInternalStorage(config.modelFile) if (model_path == null) { Log.e(TAG, "❌ Failed to copy ONNX model from assets") @@ -493,7 +496,7 @@ class YOLOInferenceEngine(private val context: Context) : MLInferenceEngine Log.d(TAG, "🔧 Ultralytics preprocessing: input ${inputMat.cols()}x${inputMat.rows()}, type=${inputMat.type()}") // Step 1: Letterbox resize (preserves aspect ratio with padding) - val letterboxed = letterboxResize(inputMat, INPUT_SIZE, INPUT_SIZE) + val letterboxed = letterboxResize(inputMat, config.inputSize, config.inputSize) // Step 2: Apply slight noise reduction (Ultralytics uses this) val denoised = Mat() @@ -628,7 +631,7 @@ class YOLOInferenceEngine(private val context: Context) : MLInferenceEngine val resized = Mat() try { - Imgproc.resize(inputMat, resized, Size(INPUT_SIZE.toDouble(), INPUT_SIZE.toDouble())) + Imgproc.resize(inputMat, resized, Size(config.inputSize.toDouble(), config.inputSize.toDouble())) } catch (e: Exception) {