我正在使用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的新手,并且第一次使用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的创建放在这之外(很明显,因为他只想要一个实例,所以google对我大吼大叫)。
现在,我在CameraDevice.StateCallback()的侦听器“onOpened”的开头获得了它。
我认为最好的方法是将检测器设置为null作为类的私有(private)属性,然后将其加载到onOpened()的侦听器中,并在onDisconnected()的侦听器中将其关闭。

09-11 03:20