145 lines
5.5 KiB
Kotlin
145 lines
5.5 KiB
Kotlin
package com.example.livingai.camera
|
|
|
|
import android.Manifest
|
|
import android.content.pm.ActivityInfo
|
|
import android.graphics.Bitmap
|
|
import android.graphics.Color
|
|
import android.os.Bundle
|
|
import android.util.Log
|
|
import android.view.View
|
|
import androidx.activity.result.contract.ActivityResultContracts
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
import androidx.camera.core.ExperimentalGetImage
|
|
import androidx.camera.core.ImageProxy
|
|
import androidx.core.content.edit
|
|
import androidx.core.graphics.toColorInt
|
|
import com.example.livingai.R
|
|
import com.example.livingai.analysis.Analyzer
|
|
import com.example.livingai.analysis.FrameProcessor
|
|
import com.example.livingai.analysis.SavedMaskProcessor
|
|
import com.example.livingai.analysis.SegmentProcessor
|
|
import com.example.livingai.commons.Constants
|
|
import com.example.livingai.ui.page.HomeActivity
|
|
import com.google.android.material.button.MaterialButton
|
|
|
|
class CameraActivity : AppCompatActivity(), Analyzer.AnalysisListener {
|
|
|
|
private lateinit var overlayManager: OverlayManager
|
|
private lateinit var cameraProcessor: CameraProcessor
|
|
private lateinit var frameProcessor: FrameProcessor
|
|
private lateinit var segmentProcessor: SegmentProcessor
|
|
private lateinit var savedMaskProcessor: SavedMaskProcessor
|
|
|
|
private var cowName: String? = null
|
|
private var orientation: String? = null
|
|
private var savedMaskBitmap: Bitmap? = null
|
|
private var matchThreshold = 75
|
|
private var algorithm = HomeActivity.ALGORITHM_HAMMING
|
|
private var isAutoCapture = true
|
|
private var isMaskDisplayEnabled = false
|
|
private var isPhotoTaken = false
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
setContentView(R.layout.activity_main)
|
|
|
|
cowName = intent.getStringExtra(Constants.COW_NAME)
|
|
orientation = intent.getStringExtra(Constants.ORIENTATION)
|
|
|
|
// Load settings
|
|
val prefs = getSharedPreferences("AnimalRatingPrefs", MODE_PRIVATE)
|
|
matchThreshold = prefs.getInt("THRESHOLD", 75)
|
|
algorithm = prefs.getString("ALGORITHM", HomeActivity.ALGORITHM_HAMMING) ?: HomeActivity.ALGORITHM_HAMMING
|
|
isAutoCapture = prefs.getBoolean(Constants.PREF_AUTO_CAPTURE, true)
|
|
isMaskDisplayEnabled = prefs.getBoolean(Constants.PREF_MASK_DISPLAY, false)
|
|
|
|
// Set orientation
|
|
if (orientation == "front" || orientation == "back") {
|
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
|
} else {
|
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
|
|
}
|
|
|
|
// Initialize Managers and Processors
|
|
overlayManager = OverlayManager(
|
|
findViewById(R.id.silhouetteOverlay),
|
|
findViewById(R.id.segmentationOverlay),
|
|
findViewById(R.id.savedMaskOverlay)
|
|
)
|
|
|
|
cameraProcessor = CameraProcessor(this, findViewById(R.id.cameraPreview), this)
|
|
frameProcessor = FrameProcessor()
|
|
segmentProcessor = SegmentProcessor()
|
|
savedMaskProcessor = SavedMaskProcessor(this)
|
|
|
|
setupUI()
|
|
loadMasks()
|
|
|
|
requestPermissionLauncher.launch(Manifest.permission.CAMERA)
|
|
}
|
|
|
|
private fun setupUI() {
|
|
findViewById<MaterialButton>(R.id.btnExit).setOnClickListener { finish() }
|
|
|
|
val btnShutter = findViewById<MaterialButton>(R.id.btnShutter)
|
|
|
|
btnShutter.setOnClickListener {
|
|
cameraProcessor.takePhoto(
|
|
cowName, orientation,
|
|
intent.getIntExtra(Constants.SILHOUETTE_ID, 0),
|
|
intent.getStringExtra("RETAKE_IMAGE_PATH")
|
|
)
|
|
isPhotoTaken = true
|
|
}
|
|
|
|
val silhouetteId = intent.getIntExtra(Constants.SILHOUETTE_ID, 0)
|
|
overlayManager.setSilhouette(silhouetteId)
|
|
}
|
|
|
|
private fun loadMasks() {
|
|
savedMaskBitmap = savedMaskProcessor.loadSavedMask(orientation ?: "unknown")
|
|
overlayManager.showSavedMask(savedMaskBitmap, isMaskDisplayEnabled)
|
|
}
|
|
|
|
private val requestPermissionLauncher =
|
|
registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
|
|
if (granted) cameraProcessor.startCamera()
|
|
}
|
|
|
|
@ExperimentalGetImage
|
|
override fun onFrame(imageProxy: ImageProxy) {
|
|
if (isPhotoTaken) {
|
|
imageProxy.close()
|
|
return
|
|
}
|
|
|
|
val rotationDegrees = imageProxy.imageInfo.rotationDegrees
|
|
val inputImage = frameProcessor.prepareInputImage(imageProxy, rotationDegrees)
|
|
|
|
if (inputImage != null) {
|
|
segmentProcessor.process(inputImage, savedMaskBitmap, matchThreshold, algorithm)
|
|
.addOnSuccessListener { result ->
|
|
runOnUiThread {
|
|
overlayManager.showSegmentationMask(result.mask, isMaskDisplayEnabled)
|
|
}
|
|
if (isAutoCapture && result.isMatch && !isPhotoTaken) {
|
|
isPhotoTaken = true
|
|
cameraProcessor.takePhoto(
|
|
cowName, orientation,
|
|
intent.getIntExtra(Constants.SILHOUETTE_ID, 0),
|
|
intent.getStringExtra("RETAKE_IMAGE_PATH")
|
|
)
|
|
}
|
|
}
|
|
.addOnFailureListener { e ->
|
|
Log.e("CameraActivity", "Frame processing error", e)
|
|
}
|
|
.addOnCompleteListener {
|
|
imageProxy.close()
|
|
}
|
|
} else {
|
|
imageProxy.close()
|
|
}
|
|
}
|
|
}
|