【问题标题】:FaceDetector was not released with FaceDetector.release()FaceDetector 没有通过 FaceDetector.release() 释放
【发布时间】:2023-03-11 03:18:01
【问题描述】:

我正在使用 ML 人脸检测器:https://developers.google.com/ml-kit/vision/face-detection/android#kotlin_2

然后我从 Camera2 拍摄图像并进行处理。但我经常遇到错误“FaceDetector 没有通过 FaceDetector.release() 发布”

更多细节:

W/FaceDetector: FaceDetector was not released with FaceDetector.release()
E/BufferQueueProducer: [ImageReader-960x1280f23m2-7166-0](id:1bfe00000000,api:4,p:386,c:7166) dequeueBuffer: BufferQueue has been abandoned

我已经按照本教程获得了 camera2:https://medium.com/@tylerwalker/integrating-camera2-api-on-android-feat-kotlin-4a4e65dc593f

这是我尝试为 ML 编写的代码:

val realTimeOps = FaceDetectorOptions.Builder()
.setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)
.build()
val detector = FaceDetection.getClient(realTimeOps)
imageReader.setOnImageAvailableListener({
    imageReader.acquireLatestImage()?.let { image ->
    val mlImage = InputImage.fromMediaImage(image, 0) // TODO change image for calculation


    val result = detector.process(mlImage)
        .addOnSuccessListener {faces ->
            Log.d("photo", "Face found!")
        }
        .addOnFailureListener { e ->
            Log.d("photo", "Error: $e")
        }

        image.close()
    }
}, Handler { true })

而且,我的“检测器”val 没有功能释放 :'(

我希望有人可以帮助我:)

【问题讨论】:

  • 使用标签前请阅读标签说明
  • 抱歉,这是我第一次发帖,下次会注意的

标签: android kotlin


【解决方案1】:

我终于弄清楚这个错误是怎么发生的!

必须只有一个检测器实例。错误出现在我的代码的另一部分(我是 android 新手,第一次使用 camera2):

 cameraCharacteristics[CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP]?.let { streamConfigurationMap ->
                streamConfigurationMap.getOutputSizes(ImageFormat.YUV_420_888)
                    ?.let { yuvSizes ->
                        val previewSize = yuvSizes.last()
                        val displayRotation = windowManager.defaultDisplay.rotation
                        val swappedDimensions = areDimensionsSwapped(displayRotation, cameraCharacteristics)
                        val rotatedPreviewWidth = if (swappedDimensions) previewSize.height else previewSize.width
                        val rotatedPreviewHeight = if (swappedDimensions) previewSize.width else previewSize.height
                        surfaceView.holder.setFixedSize(rotatedPreviewWidth, rotatedPreviewHeight)

                        
                        val imageReader = ImageReader.newInstance(rotatedPreviewWidth, rotatedPreviewHeight,
                            ImageFormat.YUV_420_888, 2)

                        val realTimeOps = FaceDetectorOptions.Builder()
                            .setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)
                            .build()
                        val detector: FaceDetector = FaceDetection.getClient(realTimeOps)
                        imageReader.setOnImageAvailableListener({
                            imageReader.acquireLatestImage()?.let { image ->

                                val mlImage = InputImage.fromMediaImage(image, getRotationCompensation(cameraDevice.id, getInstance(), true))


                                val result = detector.process(mlImage)
                                    .addOnSuccessListener {faces ->
                                        if (faces.size > 0)
                                            Log.d("photo", "Face found!")
                                        else
                                            Log.d("photo", "No face have been found")
                                    }
                                    .addOnFailureListener { e ->
                                        Log.d("photo", "Error: $e")
                                    }
                                    .addOnCompleteListener {
                                        image.close()
                                    }
                            }
                        }, Handler { true })


                        val previewSurface = surfaceView.holder.surface
                        val recordingSurface = imageReader.surface

                        val captureCallback = object : CameraCaptureSession.StateCallback() {
                            override fun onConfigureFailed(session: CameraCaptureSession) {

                            }

                            override fun onConfigured(session: CameraCaptureSession) {

                                val previewRequestBuilder = cameraDevice.createCaptureRequest(
                                    TEMPLATE_PREVIEW
                                ).apply {
                                    addTarget(previewSurface)
                                    addTarget(recordingSurface)
                                }

                                session.setRepeatingRequest(
                                    previewRequestBuilder.build(),
                                    object: CameraCaptureSession.CaptureCallback() {},
                                    Handler { true }
                                )
                            }
                        }

                        cameraDevice.createCaptureSession(mutableListOf(previewSurface, recordingSurface), captureCallback, Handler {true})
                    }

我将 FaceDetector 的创建放在 cameraCharacteristics 中,但每次捕获图像时都会调用此函数。我需要将 FaceDector 的创建放在这个之外(很明显,因为他只想要一个实例,所以谷歌对我大喊大叫)。

现在我在 CameraDevice.StateCallback() 的侦听器“onOpened”的开头得到了它。

我认为最好将检测器设置为 null 作为类的私有属性,然后将其加载到 onOpened() 的侦听器中并在 onDisconnected() 的侦听器处关闭它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-10
    • 2015-04-25
    • 2013-05-24
    • 1970-01-01
    • 2021-11-20
    • 2011-06-01
    • 2019-08-09
    • 1970-01-01
    相关资源
    最近更新 更多