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

Google ML Kit人脸检测无法识别图库Uri图片问题求助

解决Google ML Kit图库选图人脸检测失败问题

问题核心错误

  1. 逻辑判断倒置:人脸检测成功回调中,你用faces.isNullOrEmpty()触发裁剪逻辑,这会导致检测到人脸时反而进入“未识别”分支,空列表时调用faces[0]还会直接抛出异常。
  2. 旋转处理重复:手动读取Exif旋转角度传入InputImage.fromBitmap,但ImageDecoder/MediaStore获取Bitmap时可能已自动应用旋转,导致ML Kit接收到的图片旋转角度错误,人脸检测失效。
  3. Uri处理复杂化:手动转换Bitmap的过程可能丢失图片元数据,不如直接用ML Kit提供的API简化流程。

修正后的实现代码

private fun selectImage() {
    val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
        type = "image/*"
    }
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), 11)
}

@RequiresApi(Build.VERSION_CODES.N)
@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == RESULT_OK && requestCode == 11) {
        data?.data?.let { uri ->
            selectedImageAnalyser(uri)
        }
    }
}

private fun selectedImageAnalyser(uri: Uri) {
    try {
        // 直接从Uri创建InputImage,自动处理Exif旋转与元数据
        val inputImage = InputImage.fromFilePath(this, uri)
        
        binding!!.ivFace.apply {
            visibility = View.VISIBLE
            setImageURI(uri)
        }

        faceDetector.process(inputImage)
            .addOnSuccessListener { faces ->
                if (faces.isNotEmpty()) {
                    val rotation = inputImage.rotationDegrees
                    // 基于ML Kit处理后的图片与Bounding Box进行裁剪
                    val croppedFace = cropToBox(inputImage.bitmapInternal, faces[0].boundingBox, rotation)
                    startEnrollDialog(croppedFace)
                } else {
                    Log.d(TAG, "selectedImageAnalyser: 未检测到人脸")
                }
            }
            .addOnFailureListener { 
                Log.d(TAG, "selectedImageAnalyser: 检测失败,原因: ${it.cause}, 消息: ${it.message}") 
            }
    } catch (e: IOException) {
        e.printStackTrace()
        Log.d(TAG, "selectedImageAnalyser: 创建输入图片失败")
    }
}

// 适配旋转角度的人脸裁剪方法
private fun cropToBox(bitmap: Bitmap, boundingBox: Rect, rotation: Int): Bitmap {
    val rotatedBitmap = when (rotation) {
        90 -> rotateBitmap(bitmap, 90f)
        180 -> rotateBitmap(bitmap, 180f)
        270 -> rotateBitmap(bitmap, 270f)
        else -> bitmap
    }
    return Bitmap.createBitmap(rotatedBitmap, boundingBox.left, boundingBox.top, boundingBox.width(), boundingBox.height())
}

private fun rotateBitmap(bitmap: Bitmap, degrees: Float): Bitmap {
    val matrix = Matrix().apply { postRotate(degrees) }
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}

关键优化点

  • 简化Uri处理:使用InputImage.fromFilePath直接从Uri生成检测用图片,自动读取Exif旋转信息,避免手动处理Bitmap的误差。
  • 修正逻辑判断:确保检测到人脸时才执行裁剪操作,空列表时输出正确日志。
  • 适配旋转裁剪:根据ML Kit返回的旋转角度调整Bitmap,保证Bounding Box裁剪区域的准确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:31:19