使用 Google ML Kit 实现图片文字识别(提取美国驾照信息)

Google ML Kit 是一个现代、功能强大、跨平台的机器学习 SDK。在这篇文章中,我们将使用 ML Kit 在 Android 应用中识别图片文字,以提取美国驾照上的关键信息:DL(驾照号)EXP(有效日期)


🛠️ 步骤一:项目配置

1. 添加依赖

打开 app/build.gradle,添加以下 ML Kit 的文字识别依赖:

Kotlin 复制代码
dependencies { implementation 'com.google.mlkit:text-recognition:16.0.0' }

2. 添加权限(可选)

如果你需要从相册或相机中读取图片,还需要添加读取权限:

Kotlin 复制代码
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

🧾 示例功能说明

我们将:

  • 加载一张美国驾照图片(假设叫 license.jpg

  • 使用 ML Kit 提取图片上的文字

  • 使用正则表达式提取出驾驶证号(DL ABC1234567)和出生日期(DOB 05/01/1990


📄 布局文件:activity_main.xml

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="303dp"
        android:layout_height="189dp"
        android:layout_marginStart="54dp"
        android:layout_marginTop="62dp"
        android:layout_marginEnd="54dp"
        android:layout_marginBottom="105dp"
        app:layout_constraintBottom_toTopOf="@+id/textView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:src="@tools:sample/backgrounds/scenic" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="165dp"
        android:layout_marginTop="264dp"
        android:layout_marginEnd="156dp"
        android:layout_marginBottom="43dp"
        android:text="Loading"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

</androidx.constraintlayout.widget.ConstraintLayout>

🔧 主逻辑:MainActivity.kt

Kotlin 复制代码
package com.example.ml

import android.graphics.BitmapFactory
import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.google.mlkit.vision.common.InputImage
import com.google.mlkit.vision.text.TextRecognition
import java.io.InputStream
import com.google.mlkit.vision.text.latin.TextRecognizerOptions

class MainActivity : AppCompatActivity() { 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)

        val imageView = findViewById<ImageView>(R.id.imageView)

        val button = findViewById<Button>(R.id.button)

        // 加载图片(assets 文件夹中的 jiazhao.webp)
        val inputStream: InputStream = assets.open("license.jpg")
        val bitmap = BitmapFactory.decodeStream(inputStream)
        imageView.setImageBitmap(bitmap)

        button.setOnClickListener {
            extractTextFromBitmap(bitmap)
        }
    }

    private fun extractTextFromBitmap(bitmap: android.graphics.Bitmap) {
        val image = InputImage.fromBitmap(bitmap, 0)
        val textView = findViewById<TextView>(R.id.textView)
        val recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)

        recognizer.process(image)
            .addOnSuccessListener { visionText ->
                val fullText = visionText.text

                // 提取 DOB 和 DL
                val expRegex = Regex("""EXP\s+\d{2}/\d{2}/\d{4}""")
                val dlRegex = Regex("""DL\s+[A-Z0-9]+""")

                val exp = expRegex.find(fullText)?.value ?: "未识别到有效日期"
                val dl = dlRegex.find(fullText)?.value ?: "未识别到驾驶证号"

                textView.text =  "有效日期: $exp" + "\n" + "驾驶证号: $dl"
            }
            .addOnFailureListener { e ->
                textView.text = "识别失败:${e.message}"
            }
    }
}

🧪 测试效果

确保你将美国驾照样本命名为 license.jpg 并放入 res/drawable/ 目录。点击按钮后,在日志中可以看到类似如下输出:

Kotlin 复制代码
有效日期: EXP 08/31/2026
驾驶证号: DL I1234568
相关推荐
好学人14 小时前
Kotlin object 关键字详解
kotlin
好学人14 小时前
Kotlin sealed 关键字介绍
kotlin
岸芷漫步15 小时前
Kotlin中的序列化应用
kotlin
zimoyin17 小时前
整活 kotlin + springboot3 + sqlite 配置一个 SQLiteCache
jvm·sqlite·kotlin
alexhilton1 天前
Jetpack Compose的性能优化建议
android·kotlin·android jetpack
天枢破军2 天前
【KMP】桌面端打包指南
kotlin
_一条咸鱼_2 天前
深度解析 Android MVI 架构原理
android·面试·kotlin
好学人2 天前
Android MVVM 架构中的重要概念
kotlin·mvvm
好学人2 天前
一文弄懂 repeatOnLifecycle
kotlin·mvvm
天枢破军2 天前
【KMP】解决桌面端打包异常无法运行
kotlin