You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android相机预览正常但imageAnalysis.setAnalyzer代码块未触发求助

问题:相机预览正常但ImageAnalysis分析器未触发

我能在屏幕上看到相机预览画面,但imageAnalysis.setAnalyzer(Executors.newSingleThreadExecutor()) { imageProxy ->对应的代码块始终没有触发,相关实现代码如下:

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

val previewSurface = Surface(surfaceTexture)

// Set up ImageReader for image analysis
val 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) // for image analysis
}

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

val imageAnalysis = ImageAnalysis.Builder()
    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
    .build()

imageAnalysis.setAnalyzer(Executors.newSingleThreadExecutor()) { imageProxy ->
    Log.d("my", "Analyzer is running")
    val mediaImage = imageProxy.image ?: return@setAnalyzer
    val rotationDegrees = 0
    val image = InputImage.fromMediaImage(mediaImage, rotationDegrees)

    faceDetector.process(image)
        .addOnSuccessListener { faces ->
            for (face in faces) {
                Log.e("my", "Face detection")
            }
        }
        .addOnFailureListener { e ->
            Log.e("my", "Face detection failed", e)
        }
        .addOnCompleteListener {
            imageProxy.close()
        }
}

问题原因

你同时使用了ImageReader和ImageAnalysis两种图像捕获逻辑,二者存在冲突:ImageAnalysis本身已经封装了图像流的获取与处理,不需要额外创建ImageReader并将其Surface加入捕获请求。相机的帧数据被导向了ImageReader,而非ImageAnalysis,导致分析器代码块无法触发。

修复方案

步骤1:移除冗余的ImageReader代码

删除所有与ImageReader相关的代码,包括实例化、Surface获取以及捕获请求中添加该Surface的语句。

步骤2:将ImageAnalysis的Surface加入捕获请求

修改captureRequestBuilder,把ImageAnalysis的Surface添加为捕获目标,让相机帧数据流向ImageAnalysis。

修改后的核心代码

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

val previewSurface = Surface(surfaceTexture)

val captureRequestBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW).apply {
    addTarget(previewSurface)
    addTarget(imageAnalysis.surface) // 替换原imageReader.surface,将帧数据导向ImageAnalysis
}

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

val imageAnalysis = ImageAnalysis.Builder()
    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
    .build()

imageAnalysis.setAnalyzer(Executors.newSingleThreadExecutor()) { imageProxy ->
    Log.d("my", "Analyzer is running")
    val mediaImage = imageProxy.image ?: return@setAnalyzer
    // 注意:此处rotationDegrees不能硬设为0,需根据设备旋转角度和相机传感器方向计算
    val rotationDegrees = calculateCorrectRotation() 
    val image = InputImage.fromMediaImage(mediaImage, rotationDegrees)

    faceDetector.process(image)
        .addOnSuccessListener { faces ->
            for (face in faces) {
                Log.e("my", "Face detection")
            }
        }
        .addOnFailureListener { e ->
            Log.e("my", "Face detection failed", e)
        }
        .addOnCompleteListener {
            imageProxy.close()
        }
}

额外提示

  • 旋转角度rotationDegrees需动态计算,硬设为0会导致人脸检测结果与预览画面方向不匹配,可通过Display.getRotation()和相机传感器方向来推导正确值。
  • 确保ImageAnalysis的尺寸与预览尺寸一致,避免因尺寸不匹配导致的帧数据丢失。

内容的提问来源于stack exchange,提问作者Hope

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 08:12:07