Моя цель состоит в том, чтобы быть в состоянии активно обрабатывать изображение в фоновом режиме, но когда приложение находится на переднем плане, мне нужен предварительный просмотр, который показывает обработанное изображение, что означает исходный кадр, ограничивающие ящики и т. Д., Добавлены OpenCv. Один, который я нашел, так что да). Затем действие будет привязаться к службе и использовать представление камеры, но оно не сработало, или, по крайней мере, все прошло нормально, пока я не попытался вызовать enableview на представление камеры из ограниченного сервиса, затем приложение будет сбоем. Вот код, который я использовал (я знаю, что это мусор, и основное действие действительно похоже на половину инициализации OpenCV, что не должно): < /p>
Камера: < /p>
class CameraService: Service() {
private val binder = CameraBinder(this)
lateinit var openCvCameraView: CameraBridgeViewBase
inner class CameraBinder (
private val context: Context,
) : Binder() {
val service = this@CameraService
}
override fun onBind(intent: Intent?): IBinder {
return binder
}
private fun startCamera(): CameraBridgeViewBase {
val view = JavaCamera2View(this, -1)
view.visibility = SurfaceView.VISIBLE
view.setCameraPermissionGranted()
view.setCvCameraViewListener(DetectionRepository())
return view
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
when (intent?.action) {
Actions.START.toString() -> startService()
Actions.STOP.toString() -> stopSelf()
}
return super.onStartCommand(intent, flags, startId)
}
private fun startService() {
val notification = NotificationCompat.Builder(
this,
TestApp.NotificationChannels.PROCESSING_CAMERA.toString()
)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Processing the camera feed")
.setContentText("some text")
.build()
openCvCameraView = startCamera()
startForeground(1, notification)
}
enum class Actions {
START,
STOP,
}
}
< /code>
Основное действие: < /p>
class MainActivity : ComponentActivity() {
private lateinit var cameraService: CameraService
private var cameraServiceBound: Boolean = false
private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as CameraService.CameraBinder
cameraService = binder.service
cameraServiceBound = true
}
override fun onServiceDisconnected(arg0: ComponentName) {
cameraServiceBound = false
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
if (OpenCVLoader.initLocal()) {
Log.i("LOADED", "OpenCV loaded successfully")
} else {
Log.e("LOADED", "OpenCV initialization failed!")
(Toast.makeText(this, "OpenCV initialization failed!", Toast.LENGTH_LONG))
.show()
return
}
Intent(this, CameraService::class.java).also {
it.action = CameraService.Actions.START.toString()
startForegroundService(it)
bindService(it, connection, Context.BIND_AUTO_CREATE)
}
if (!hasRequiredPermissions()) {
ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, 0)
}
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
cameraService.openCvCameraView.setCameraPermissionGranted()
cameraService.openCvCameraView.enableView() // crashes because of this
setContent {
AppTheme {
Column {
if (cameraServiceBound) {
AndroidView(factory = { cameraService.openCvCameraView })
}
}
}
}
}
override fun onStart() {
Intent(this, CameraService::class.java).also {
it.action = CameraService.Actions.START.toString()
bindService(it, connection, Context.BIND_AUTO_CREATE)
}
super.onStart()
}
private fun hasRequiredPermissions(): Boolean {
return REQUIRED_PERMISSIONS.all {
ContextCompat.checkSelfPermission(
applicationContext,
it
) == PackageManager.PERMISSION_GRANTED
}
}
companion object {
val REQUIRED_PERMISSIONS = assemblePermissions()
private fun assemblePermissions(): Array {
val basePerms = mutableListOf(
Manifest.permission.CAMERA,
Manifest.permission.FOREGROUND_SERVICE,
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
basePerms.add(Manifest.permission.FOREGROUND_SERVICE_CAMERA)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
basePerms.add(Manifest.permission.POST_NOTIFICATIONS)
}
return basePerms.toTypedArray()
}
}
}
Еще одна вещь, которую я рассматривал, - это использование Camerax и просто преобразование каждого кадра в Mat , используя что -то похожее на реализацию Javacamera2frame в OpenCV. Но я не знаю, как я тогда изменил бы вывод PreviewView , чтобы использовать обработанные кадры, также мне нужно каким -то образом преобразовать обратно в Format Camerax. /> Я новичок в разработке Android и OpenCV в целом, я не знаю, как достичь своей цели в этой ситуации. < /p>
есть ли хорошее решение для достижения этого? Это даже возможно?
Моя цель состоит в том, чтобы быть в состоянии активно обрабатывать изображение в фоновом режиме, но когда приложение находится на переднем плане, мне нужен предварительный просмотр, который показывает обработанное изображение, что означает исходный кадр, ограничивающие ящики и т. Д., Добавлены OpenCv. Один, который я нашел, так что да). Затем действие будет привязаться к службе и использовать представление камеры, но оно не сработало, или, по крайней мере, все прошло нормально, пока я не попытался вызовать enableview на представление камеры из ограниченного сервиса, затем приложение будет сбоем. Вот код, который я использовал (я знаю, что это мусор, и основное действие действительно похоже на половину инициализации OpenCV, что не должно): < /p> Камера: < /p> [code]class CameraService: Service() { private val binder = CameraBinder(this) lateinit var openCvCameraView: CameraBridgeViewBase
inner class CameraBinder ( private val context: Context, ) : Binder() { val service = this@CameraService }
override fun onBind(intent: Intent?): IBinder { return binder }
private fun startCamera(): CameraBridgeViewBase { val view = JavaCamera2View(this, -1) view.visibility = SurfaceView.VISIBLE view.setCameraPermissionGranted() view.setCvCameraViewListener(DetectionRepository()) return view }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { when (intent?.action) { Actions.START.toString() -> startService() Actions.STOP.toString() -> stopSelf() }
private fun startService() { val notification = NotificationCompat.Builder( this, TestApp.NotificationChannels.PROCESSING_CAMERA.toString() ) .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentTitle("Processing the camera feed") .setContentText("some text") .build()
if (!hasRequiredPermissions()) { ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, 0) }
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) cameraService.openCvCameraView.setCameraPermissionGranted() cameraService.openCvCameraView.enableView() // crashes because of this
private fun hasRequiredPermissions(): Boolean { return REQUIRED_PERMISSIONS.all { ContextCompat.checkSelfPermission( applicationContext, it ) == PackageManager.PERMISSION_GRANTED } }
companion object { val REQUIRED_PERMISSIONS = assemblePermissions()
private fun assemblePermissions(): Array { val basePerms = mutableListOf( Manifest.permission.CAMERA, Manifest.permission.FOREGROUND_SERVICE, )
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { basePerms.add(Manifest.permission.FOREGROUND_SERVICE_CAMERA) }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { basePerms.add(Manifest.permission.POST_NOTIFICATIONS) }
return basePerms.toTypedArray() } } } [/code] Еще одна вещь, которую я рассматривал, - это использование Camerax и просто преобразование каждого кадра в Mat , используя что -то похожее на реализацию Javacamera2frame в OpenCV. Но я не знаю, как я тогда изменил бы вывод PreviewView , чтобы использовать обработанные кадры, также мне нужно каким -то образом преобразовать обратно в Format Camerax. /> Я новичок в разработке Android и OpenCV в целом, я не знаю, как достичь своей цели в этой ситуации. < /p> есть ли хорошее решение для достижения этого? Это даже возможно?