Android-MLKit之二维码识别

2018年,Google推出了移动端机器学习框架ML Kit,ML Kit 正式版在2020年发布。目前包括:视觉(条形码扫描、面部识别、图片标签分类、物体识别和追踪、文字识别、手写识别、姿态识别、自拍人像分离)和自然语言(语言识别、文字翻译、智能回复、实体抽取)两大部分。

苹果也有Core ML框架,这两者一时间也成为对比的热门对象。有文章做过细致对比分析

这里以二维码识别为例,做简单的使用说明。

库引用

由于ML KIT属于Firebase的机器学习模块,天然可以搭配Google Play Services使用,以达到最小包引用。但是由于‘你懂得’原因,咱们只能使用模型库捆绑包。对比如下(官方):

Feature Unbundled Bundled
Implementation Model is dynamically downloaded via Google Play Services. Model is statically linked to your app at build time.
App size About 600 KB size increase. About 3.2 MB size increase.
Initialization time Might have to wait for model to download before first use. Model is available immediately.
Performance V1 model. V3 model is faster and more accurate.
V3 model detects more correct results from bad-quality inputs and have more stable bounding boxes in streaming mode. Recall is improved by 17.1%.
1
2
3
4
5
6
   dependencies {
     // ...
     // Use this dependency to bundle the model with your app
     implementation 'com.google.mlkit:barcode-scanning:17.0.2'
   }
   

Kotlin使用说明

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
   BarcodeScanning
       .getClient()
       .process(inputImage)
       .addOnSuccessListener { barcodes ->
           barcodes.forEach { barcode ->
               val bounds = barcode.boundingBox
               val corners = barcode.cornerPoints
               val rawValue = barcode.rawValue

               val valueType = barcode.valueType
               // See API reference for complete list of supported types
               when (valueType) {
                   Barcode.TYPE_WIFI -> {
                       val ssid = barcode.wifi!!.ssid
                       val password = barcode.wifi!!.password
                       val type = barcode.wifi!!.encryptionType
                   }
                   Barcode.TYPE_URL -> {
                       val title = barcode.url!!.title
                       val url = barcode.url!!.url
                   }
               }
           }
       }
       .addOnFailureListener {

       }

具体使用可以参看Google的代码:BarcodeScanningActivity.kt

扫描配置

BarcodeScanning通过getClient()获取BarcodeScanner时,可以传入BarcodeScannerOptions配置扫描格式参数。

1
2
3
4
5
6
val options = BarcodeScannerOptions.Builder()
   .setBarcodeFormats(
           Barcode.FORMAT_QR_CODE,
           Barcode.FORMAT_AZTEC,
   )
   .build()

支持的格式:

  • Code 128 (FORMAT_CODE_128)
  • Code 39 (FORMAT_CODE_39)
  • Code 93 (FORMAT_CODE_93)
  • Codabar (FORMAT_CODABAR)
  • EAN-13 (FORMAT_EAN_13)
  • EAN-8 (FORMAT_EAN_8)
  • ITF (FORMAT_ITF)
  • UPC-A (FORMAT_UPC_A)
  • UPC-E (FORMAT_UPC_E)
  • QR Code (FORMAT_QR_CODE)
  • PDF417 (FORMAT_PDF417)
  • Aztec (FORMAT_AZTEC)
  • Data Matrix (FORMAT_DATA_MATRIX)

InputImage对象获取

BarcodeScanner在使用时,process()处理函数需要传入包含数据的InputImage对象。InputImage可以通过Image、Bitmap、URI、ByteBuffer、ByteArray获取。而这里是实现摄像头扫码功能,故会涉及YUV数据转InputImage。因为大部分实现都是类似微信那种可以扫描多个二维码,所以摄像头的数据最终也要转成Bitmap做结果背景展示,那么流程应该是YUV -> Bitmap -> InputImage。具体实现可以看另外一篇文章《Android-YUV转Bitmap》

1
val inputImage = InputImage.fromBitmap(bitmap, 0)

其他

Built with Hugo
主题 StackJimmy 设计