人脸检测在一段时间后会冻结屏幕上的摄像头画面

问题描述 投票:0回答:1

使用以下 Kotlin 循环,我们显示摄像头源、检测源中的人脸并在屏幕上的视频源上绘制人脸边界框。

使用 workReducer 计数器,我们在图像馈送中每 0.5 秒检查一次面部可用性。

问题是我们第一次激活摄像头几秒钟后,如果我们使用屏幕上的某些按钮重新启动摄像头,视频输入会在大约 20 秒后冻结。

我已经有一段时间一直在寻找解决方案但没有成功。

Ps:如果没有检测到人脸,它永远不会冻结。 另外:当我删除

   android.graphics.Rect( face.boundingBox.left,
                          face.boundingBox.top,
                          face.boundingBox.right,
                           face.boundingBox.bottom
                                        ) by commenting it freezes les often

                        
                        imageReader.setOnImageAvailableListener({ reader ->
                            
                            val image = reader.acquireLatestImage() ?: return@setOnImageAvailableListener
                            val bitImage = recordJpeg( image, cx)
                            
                            bitImage?.let { bitmapCallback.onBitmapUpdated(it) }

                            if (workReducer > workReducerLimit) {

                                workReducer = 0
                                val inputImage = InputImage.fromMediaImage(image, 270)
                                faceDetector.process(inputImage).addOnSuccessListener { faces ->

                                        val rects = faces.map { face ->

                                         
                                            android.graphics.Rect(
                                                face.boundingBox.left,
                                                face.boundingBox.top,
                                                face.boundingBox.right,
                                                face.boundingBox.bottom
                                            )
                                            
                                        }

                                        faceRectsCallback.onFaceRectsUpdated(rects)
                                    }
                                    .addOnFailureListener { e ->
                                        image.close()
                                    }
                                    .addOnCompleteListener {
                                        image.close()
                                    }

                            } else {
                                image.close()
                            }

                            workReducer += 1

                        // Camera image read loop
                        }, Handler(context.mainLooper))
android kotlin face-detection
1个回答
0
投票

嗯,冻结的事情发生是因为常量类型,而不是因为人脸检测功能或 API。

几个小时后我偶然发现冻结的原因是inputImage常量。

我将其声明为 private var imageReader : ImageReader? = null 在类之外我的函数在内部运行。

它显示来自相机的实时反馈,在其上绘制面部边界框并显示我用来录制并稍后顺利转换视频文件的位图图像。

当我尝试找出问题原因时,我必须升级许多与 Kotlin 和 Java 相关的东西。现在,在完成所有这些之后,Xcode 看起来非常漂亮。

                         override fun onOpened(camera : CameraDevice) {


                    Log.d("my", "onOpened")

                    currentCameraDevice = camera

                    val surfaceTexture = textureView.surfaceTexture?.apply {
                        setDefaultBufferSize(previewSize.width, previewSize.height)
                    }

                    val previewSurface = Surface(surfaceTexture)

                    
                    imageReader = ImageReader.newInstance(
                        previewSize.width,
                        previewSize.height,
                        ImageFormat.YUV_420_888, 
                        2 
                    )!!

                    
                    val imageReaderSurface = imageReader!!.surface

                    val captureRequestBuilder =
                        camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW).apply {
                            addTarget(previewSurface)
                            addTarget(imageReader!!.surface)
                        }


                    val faceDetector = FaceDetection.getClient(
                        FaceDetectorOptions.Builder()
                            .setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_FAST)
                            .build()
                    )

                    val sessionConfig = SessionConfiguration(

                        SessionConfiguration.SESSION_REGULAR,
                        listOf(
                            OutputConfiguration(previewSurface),
                            OutputConfiguration(imageReaderSurface)
                        ),
                        Executors.newSingleThreadExecutor(),
                        object : CameraCaptureSession.StateCallback() {
                            override fun onConfigured(session: CameraCaptureSession) {
                                currentCaptureSession = session
                                session.setRepeatingRequest(captureRequestBuilder.build(), null, null)
                                callback.onPreviewSizeAvailable(previewSize)
                            }

                            override fun onConfigureFailed(session: CameraCaptureSession) {
                                Log.e("my", "Failed to configure camera capture session")
                            }
                        }
                    )

                    camera.createCaptureSession(sessionConfig)


                    imageReader!!.setOnImageAvailableListener(
                        { reader ->

                            val image = reader.acquireLatestImage()
                                ?: return@setOnImageAvailableListener

                            try {

                                // To check if can produce bitmap.
                                val bitImage = recordJpeg(image, cx)
                                bitImage?.let { bitmapCallback.onBitmapUpdated(it) }


                                if(workReducer > workReducerLimit) {

                                    workReducer = 0




                                    val inputimage =  InputImage.fromMediaImage(image, 270)
                                    faceDetector.process(inputimage)
                                            .addOnSuccessListener { faces ->

                                                val rects = faces.map { face ->

                                                    if(!faceDetected && setup.recOn == 1) {
                                                        afterBitmapArray.clear()
                                                        preRecSize = bitmapArray.size
                                                        afterBitmapArray =
                                                            bitmapArray.toMutableList()
                                                        faceDetected = true
                                                    }

                                                    android.graphics.Rect(
                                                        face.boundingBox.left,
                                                        face.boundingBox.top,
                                                        face.boundingBox.right,
                                                        face.boundingBox.bottom
                                                    )


                                                }


                                                faceRectsCallback.onFaceRectsUpdated(rects)

                                            }
                                            .addOnFailureListener { e ->
                                                Log.d("my", "Face detection failed: ${e.message}", e)
                                            }
                                            .addOnCompleteListener { image.close() }


                                } else {
                                    image.close()
                                }

                                workReducer += 1


                            } catch (e : Exception) {
                                Log.d("my", "Error processing image: ${e.message}")
                            }


                           
                        }, Handler(context.mainLooper)
                    )


                }
© www.soinside.com 2019 - 2024. All rights reserved.