使用 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
相关推荐
Kapaseker14 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
A0微声z3 天前
Kotlin Multiplatform (KMP) 中使用 Protobuf
kotlin
alexhilton3 天前
使用FunctionGemma进行设备端函数调用
android·kotlin·android jetpack
lhDream3 天前
Kotlin 开发者必看!JetBrains 开源 LLM 框架 Koog 快速上手指南(含示例)
kotlin
RdoZam3 天前
Android-封装基类Activity\Fragment,从0到1记录
android·kotlin
Kapaseker4 天前
研究表明,开发者对Kotlin集合的了解不到 20%
android·kotlin
糖猫猫cc4 天前
Kite:两种方式实现动态表名
java·kotlin·orm·kite
如此风景5 天前
kotlin协程学习小计
android·kotlin
Kapaseker5 天前
你搞得懂这 15 个 Android 架构问题吗
android·kotlin
zh_xuan5 天前
kotlin 高阶函数用法
开发语言·kotlin