简介:本文详细讲解在Android Studio中实现人脸识别的完整流程,涵盖环境配置、ML Kit集成、代码实现与性能优化,帮助开发者快速构建高效的人脸检测应用。
人脸识别作为计算机视觉的核心应用,在移动端具有广泛场景:从用户身份验证到表情分析,从AR滤镜到健康监测。Android平台通过ML Kit和CameraX API提供了高效的人脸检测解决方案,开发者无需深度学习背景即可快速集成。
相比传统OpenCV方案,ML Kit的优势在于:
在app/build.gradle中添加核心依赖:
dependencies {// ML Kit核心库implementation 'com.google.mlkit:face-detection:17.0.0'// CameraX基础组件def camerax_version = "1.2.0"implementation "androidx.camera:camera-core:${camerax_version}"implementation "androidx.camera:camera-camera2:${camerax_version}"implementation "androidx.camera:camera-lifecycle:${camerax_version}"implementation "androidx.camera:camera-view:${camerax_version}"// 权限处理库implementation 'com.github.permissions-dispatcher:permissionsdispatcher:4.9.1'annotationProcessor 'com.github.permissions-dispatcher:permissionsdispatcher-processor:4.9.1'}
在AndroidManifest.xml中添加必要权限:
<uses-permission android:name="android.permission.CAMERA" /><uses-feature android:name="android.hardware.camera" /><uses-feature android:name="android.hardware.camera.autofocus" />
private fun startCamera() {val cameraProviderFuture = ProcessCameraProvider.getInstance(this)cameraProviderFuture.addListener({val cameraProvider = cameraProviderFuture.get()val preview = Preview.Builder().setTargetResolution(Size(1280, 720)).build()val cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_FRONT).build()preview.setSurfaceProvider(binding.viewFinder.surfaceProvider)try {cameraProvider.unbindAll()val camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview)} catch (e: Exception) {Log.e(TAG, "Camera bind failed", e)}}, ContextCompat.getMainExecutor(this))}
private lateinit var faceDetector: FaceDetectorprivate fun initFaceDetector() {val options = FaceDetectorOptions.Builder().setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_FAST).setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_ALL).setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_ALL).setMinDetectionConfidence(0.7f).build()faceDetector = FaceDetection.getClient(options)}
private fun analyzeImage(imageProxy: ImageProxy) {val mediaImage = imageProxy.image ?: returnval inputImage = InputImage.fromMediaImage(mediaImage,imageProxy.imageInfo.rotationDegrees)faceDetector.process(inputImage).addOnSuccessListener { faces ->// 处理检测结果processFaces(faces)imageProxy.close()}.addOnFailureListener { e ->Log.e(TAG, "Detection failed", e)imageProxy.close()}}private fun processFaces(faces: List<Face>) {runOnUiThread {if (faces.isEmpty()) {binding.faceOverlay.visibility = View.GONEreturn@runOnUiThread}binding.faceOverlay.visibility = View.VISIBLEval face = faces[0] // 简化处理,实际应遍历所有检测到的人脸// 获取关键点坐标(归一化值0-1)val leftEye = face.getBoundingLandmark(Face.Landmark.LEFT_EYE)val rightEye = face.getBoundingLandmark(Face.Landmark.RIGHT_EYE)// 转换为屏幕坐标val screenWidth = binding.viewFinder.widthval screenHeight = binding.viewFinder.heightleftEye?.let {val x = it.position.x * screenWidthval y = it.position.y * screenHeight// 在此处绘制眼睛标记}// 检测表情状态val smilingProb = face.smilingProbabilityval leftEyeOpen = face.leftEyeOpenProbabilityval rightEyeOpen = face.rightEyeOpenProbability// 更新UI显示binding.smilingText.text = "Smile: ${(smilingProb * 100).toInt()}%"}}
性能模式选择:
FAST模式:适合实时应用,延迟<100msACCURATE模式:适合拍照后处理,精度更高置信度阈值:
.setMinDetectionConfidence(0.7f) // 平衡误检率和漏检率
setTargetFrameRate限制处理帧率
imageProxy.close() // 必须调用防止内存泄漏
class FaceDetectionActivity : AppCompatActivity() {private lateinit var binding: ActivityFaceDetectionBindingprivate lateinit var faceDetector: FaceDetectoroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityFaceDetectionBinding.inflate(layoutInflater)setContentView(binding.root)if (allPermissionsGranted()) {startCamera()} else {requestPermissions()}initFaceDetector()}private fun startCamera() {val cameraProviderFuture = ProcessCameraProvider.getInstance(this)cameraProviderFuture.addListener({val cameraProvider = cameraProviderFuture.get()val preview = Preview.Builder().setTargetResolution(Size(1280, 720)).build()val imageAnalysis = ImageAnalysis.Builder().setTargetResolution(Size(1280, 720)).setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).build().also {it.setAnalyzer(ContextCompat.getMainExecutor(this)) { image ->analyzeImage(image)}}val cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_FRONT).build()preview.setSurfaceProvider(binding.viewFinder.surfaceProvider)try {cameraProvider.unbindAll()cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis)} catch (e: Exception) {Log.e(TAG, "Camera bind failed", e)}}, ContextCompat.getMainExecutor(this))}// 其他方法实现...}
class FaceGraphicOverlay(context: Context, attrs: AttributeSet) : View(context, attrs) {private val paint = Paint().apply {color = Color.REDstyle = Paint.Style.STROKEstrokeWidth = 5f}private val facePointsPaint = Paint().apply {color = Color.GREENstrokeWidth = 10f}private var faces: List<Face> = emptyList()fun setFaces(newFaces: List<Face>) {faces = newFacesinvalidate()}override fun onDraw(canvas: Canvas) {super.onDraw(canvas)faces.forEach { face ->// 绘制人脸边界框val bounds = face.boundingBoxval left = bounds.left.toFloat()val top = bounds.top.toFloat()val right = bounds.right.toFloat()val bottom = bounds.bottom.toFloat()canvas.drawRect(left, top, right, bottom, paint)// 绘制关键点listOf(Face.Landmark.LEFT_EYE,Face.Landmark.RIGHT_EYE,Face.Landmark.NOSE_BASE,Face.Landmark.LEFT_CHEEK,Face.Landmark.RIGHT_CHEEK).forEach { landmark ->face.getBoundingLandmark(landmark)?.let {val x = it.position.x * widthval y = it.position.y * heightcanvas.drawCircle(x, y, 20f, facePointsPaint)}}}}}
cameraProvider.unbindAll()faceDetector.close()
ML Kit默认支持多人脸检测,只需遍历faces列表:
faces.forEachIndexed { index, face ->// 处理第index个人脸}
结合ARCore实现3D效果:
implementation 'com.google.ar1.30.0'
val faceMesh = face.getContour(Face.Contour.FACE).points
通过眨眼检测实现基础活体判断:
val isBlinking = face.leftEyeOpenProbability < 0.3 &&face.rightEyeOpenProbability < 0.3
通过本文提供的完整实现方案,开发者可以在Android Studio中快速构建稳定的人脸识别应用。实际开发中建议从基础功能开始,逐步添加复杂特性,并通过性能分析工具持续优化用户体验。