Google ML Kit人脸检测无法识别图库Uri图片问题求助
解决Google ML Kit图库选图人脸检测失败问题
问题核心错误
- 逻辑判断倒置:人脸检测成功回调中,你用
faces.isNullOrEmpty()触发裁剪逻辑,这会导致检测到人脸时反而进入“未识别”分支,空列表时调用faces[0]还会直接抛出异常。 - 旋转处理重复:手动读取Exif旋转角度传入
InputImage.fromBitmap,但ImageDecoder/MediaStore获取Bitmap时可能已自动应用旋转,导致ML Kit接收到的图片旋转角度错误,人脸检测失效。 - 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
相关产品推荐
相关产品推荐

