ML Kit 入门学习&介绍

ML Kit 入门学习&介绍

1. ML Kit

ML Kit 是 Google 提供的一款机器学习 SDK,它包含了一系列预训练模型,可以帮助开发者在 Android 和 iOS 应用中快速添加机器学习功能,是 Google 提供的一款开源 SDK,它可以免费使用。ML Kit 支持 Android 和 iOS 平台。
1.1 ML Kit 支持的功能包括:
  • 图像识别:识别图像中的物体、场景和文本。
  • 面部识别:检测和识别人脸。
  • 物体检测:检测图像中的物体。
  • 姿势估计:估计人体姿势。
  • 语音识别:识别语音中的单词和短语。
  • 语言识别:识别语音中的语言。
  • 手势识别:识别手势。
  • 行为识别:识别行为。
  • 地理位置识别:识别地理位置。
  • 翻译:翻译文本。
  • 自然语言处理:处理自然语言。
  • 推荐系统:为用户推荐内容。
1.2 ML Kit 使用的好处
  • ML Kit 可以帮助开发者在应用中快速添加机器学习功能,而无需自己构建和训练模型。ML Kit 的使用非常简单,只需在应用中添加几行代码即可。ML Kit 还提供了丰富的 API 文档和示例代码,帮助开发者快速上手。
  • ML Kit 是 Google 提供的一款开源 SDK,它可以免费使用。ML Kit 支持 Android 和 iOS 平台。
  • ML Kit 是 Google 在机器学习领域的最新成果,它可以帮助开发者在应用中快速添加机器学习功能。
  • ML Kit 的使用非常简单,只需在应用中添加几行代码即可。ML Kit 还提供了丰富的 API 文档和示例代码,帮助开发者快速上手

2. ML Kit 文字识别

​ 机器学习套件文字识别 v2 API 可以识别任何中文、梵文、日语、韩语和拉丁语字符集中的文本。此 API 还可用于自动执行数据输入任务,例如处理信用卡、收据和名片

2.1主要功能

  • 识别各种文字和语言的文本 支持识别中文、梵文、日语、韩语和拉丁字母的文字
  • 分析文本结构支持检测符号、元素、行和段落
  • 识别文本的语言 识别识别出的文本的语言
  • 实时识别:可以在各种设备上实时识别文本

支持的语言查询地址:https://developers.google.com/ml-kit/vision/text-recognition/v2/languages?hl=zh-cn

2.3 准备工作

​ 我们需要将ML Kit的Android 版机器学习套件库的依赖项添加到模块的应用级 Gradle 文件

dependencies {
  // To recognize Latin script
  implementation 'com.google.mlkit:text-recognition:16.0.0'

  // To recognize Chinese script
  implementation 'com.google.mlkit:text-recognition-chinese:16.0.0'

  // To recognize Devanagari script
  implementation 'com.google.mlkit:text-recognition-devanagari:16.0.0'

  // To recognize Japanese script
  implementation 'com.google.mlkit:text-recognition-japanese:16.0.0'

  // To recognize Korean script
  implementation 'com.google.mlkit:text-recognition-korean:16.0.0'
}

2.4 创建 TextRecognizer 实例

创建对应需要识别的语言

// When using Latin script library
val recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)

// When using Chinese script library
val recognizer = TextRecognition.getClient(ChineseTextRecognizerOptions.Builder().build())

// When using Devanagari script library
val recognizer = TextRecognition.getClient(DevanagariTextRecognizerOptions.Builder().build())

// When using Japanese script library
val recognizer = TextRecognition.getClient(JapaneseTextRecognizerOptions.Builder().build())

// When using Korean script library
val recognizer = TextRecognition.getClient(KoreanTextRecognizerOptions.Builder().build())

2.4 处理图片

将图片传递给 process 方法

val result = recognizer.process(image)
        .addOnSuccessListener { visionText ->
            // Task completed successfully
            // ...
        }
        .addOnFailureListener { e ->
            // Task failed with an exception
            // ...
        }

2.5 从识别出的文本块中提取文本

如果文本识别操作成功完成,系统会向成功监听器传递一个 Text 对象。Text 对象包含图片中识别到的完整文本以及零个或零个以上的 TextBlock 对象。

每个 TextBlock 表示一个矩形文本块,其中包含零个或零个以上的 Line 对象。每个 Line 对象代表一行文本,其中包含零个或零个以上的 Element 对象。每个 Element 对象代表一个字词或类似字词的实体,其中包含零个或零个以上的 Symbol 对象。每个 Symbol 对象代表一个字符、一个数字或类似字词的实体。

对于每个 TextBlock、Line、Element 和 Symbol 对象,您可以获取区域中识别出的文本、区域的边界坐标以及旋转信息、置信度分数等许多其他属性。

val resultText = result.text
for (block in result.textBlocks) {
    val blockText = block.text
    val blockCornerPoints = block.cornerPoints
    val blockFrame = block.boundingBox
    for (line in block.lines) {
        val lineText = line.text
        val lineCornerPoints = line.cornerPoints
        val lineFrame = line.boundingBox
        for (element in line.elements) {
            val elementText = element.text
            val elementCornerPoints = element.cornerPoints
            val elementFrame = element.boundingBox
        }
    }
}

2.6 文字识别demo

创建识别中文的TextRecognizer 的实例

    val recognizer = TextRecognition.getClient(ChineseTextRecognizerOptions.Builder().build())

输入需要识别的图片方法

    private fun processImage(image: InputImage) {
        recognizer.process(image)
            .addOnSuccessListener { visionText ->
                // Task completed successfully
                var resultText = ""
                Log.e("MainActivity", "识别的文字:${visionText.text}")
                for (block in visionText.textBlocks) {
                    val blockText = block.text
                    val blockCornerPoints = block.cornerPoints
                    val blockFrame = block.boundingBox
                    for (line in block.lines) {
                        val lineText = line.text
                        val lineCornerPoints = line.cornerPoints
                        val lineFrame = line.boundingBox
                        for (element in line.elements) {
                            val elementText = element.text
                            val elementCornerPoints = element.cornerPoints
                            val elementFrame = element.boundingBox
                            resultText += "${elementText}==可信度判断:${element.confidence}\n"
                            Log.e(
                                "MainActivity",
                                "可信度判断:elementText:${elementText}==element:${element.confidence}"
                            )
                        }
                    }
                    Log.e(
                        "MainActivity",
                        "blockText:${blockText}==blockCornerPoints:${blockCornerPoints}==blockFrame:${blockFrame}"
                    )
                }
                textResult.value = resultText
            }
            .addOnFailureListener { e ->
                Log.e("MainActivity", "addOnFailureListener:${e.printStackTrace()}")
            }
    }

界面布局

    fun GreetingPreview() {
        MyApplicationTheme {
            Column(
                modifier = Modifier.fillMaxSize(),
                verticalArrangement = Arrangement.Top,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Image(
                    painter = painterResource(id = textImage.intValue),
                    contentDescription = "image",
                    modifier = Modifier.size(200.dp, 150.dp)
                )

                Button(onClick = {
                    val image = InputImage.fromBitmap(
                        resources.getDrawable(textImage.intValue).toBitmap(),
                        0
                    )
                    processImage(image)
                }) {
                    Text1(text = "识别")
                }

                Button(onClick = {
                    index += 1
                    if (index == imageList.size) {
                        index = 0
                    }
                    textImage.intValue = imageList[index]
                }) {
                    Text1(text = "切换图片")
                }
                Text1(
                    text = textResult.value,
                    fontSize = 20.sp, // 字体大小
                    color = colorResource(id = R.color.black), // 字体颜色
                )

            }

        }
    }

识别效果

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通过上面4张图片的文字识别,第1张和第4张的文字识别可信度都在0.6以上,识别出来的文字也是100%正确的。 第2张和第3张的文字识别可信度在0.6以下出现了文字识别错误的情况。可见只要是书写字体端庄、工整、规范的中文基本上都可以100%的识别成功。

2.7 输入图片准则

  • 为了使机器学习套件准确识别文本,输入图片必须包含由足够像素数据表示的文本。理想情况下,每个字符的大小至少应为 16x16 像素。字符像素大于 24x24 通常不会增加准确性。

    例如,640x480 的图片可能非常适合用于扫描占据图片整个宽度的名片。如需扫描打印在信纸大小纸张上的文档,可能需要 720x1280 像素的图片。

  • 图片聚焦不佳会影响文本识别的准确性。如果您未获得可接受的结果,请尝试让用户重新捕获图片。

  • 如果您是在实时应用中识别文本,则应考虑输入图片的整体尺寸。图片越小,处理速度就越快。为了缩短延迟时间,请确保文本在图片中占据尽可能多的空间,并以较低的分辨率捕获图片(请牢记上述准确性要求)

3. 图像识别

图像识别是计算机视觉的一个重要领域,简单说就是帮你提取图片中的有效信息。 MLKit 提供了 ImageLabeling 功能,可以识别图像信息并进行分类标注。

比如输入一张包含猫的图片,ImageLabeling 能识别出图片中的猫元素,并给出一个猫的标注,除了最显眼的猫 ImageLabeling还能识别出花、草等图片中所有可识别的事物,并分别给出出现的概率和占比,识别的结果以 List<ImageLabel> 返回。 基于预置的默认模型,ImageLabeling可以对图像元素进行超过 400 种以上的标注分类,当然你可以使用自己训练的模型扩充更多分类。

3.1 主要功能

  • 一个强大的通用基分类器,可以识别 400 多个描述照片中最常见对象的类别。
  • 使用自定义模型,根据您的使用场景量身定制 使用 TensorFlow Hub 中的其他预训练模型,或使用通过 TensorFlow、AutoML Vision Edge 或 TensorFlow Lite Model Maker 训练的自定义模型。
  • 易用的高级别 API 无需处理低级别模型输入/输出、图像预处理和后处理,也无需构建处理流水线。机器学习套件从 TensorFlow Lite 模型中提取标签,并以文本描述的形式提供这些标签。

支持标签查询地址:https://developers.google.com/ml-kit/vision/image-labeling/label-map?hl=zh-cn

3.2 准备工作

添加图像标签的依赖

dependencies {
  // ...
  // Use this dependency to bundle the model with your app
  implementation 'com.google.mlkit:image-labeling:17.0.7'
}

3.3 创建一个ImageLabeling实例

val labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS)

3.4 处理图片

将图片传递给 process 方法,成功和失败返回结果

labeler.process(image)
        .addOnSuccessListener { labels ->
            // Task completed successfully
            // ...
        }
        .addOnFailureListener { e ->
            // Task failed with an exception
            // ...
        }

3.5 图像识别demo

    val labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS)
	
    private fun imageLabeling() {
        val image = InputImage.fromBitmap(resources.getDrawable(textImage.intValue).toBitmap(), 0)
        labeler.process(image).addOnSuccessListener { labels: List<ImageLabel> ->
            // Task completed successfully
           val imageLabel = labels.scan("") { acc, label ->
                acc + "${label.text} : ${label.confidence}\n"
            }.last()
            textResult.value = imageLabel
        }.addOnFailureListener {
            // Task failed with an exception
        }
    }
    

识别效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ImageLabeling可以识别图像中的事物分类,可信度从高到底排列,3张图片都精准的进行了识别。第三张图片不光是识别出了人,还有手、团队、运动、肌肉、体育等事件分类。

3.6 图像目标检测(ObjectDetection)

  • 快速对象检测和跟踪 检测对象并获取它们在图片中的位置。跨连续图像帧跟踪对象。
  • 优化的设备端模型 对象检测和跟踪模型针对移动设备进行了优化,旨在用于实时应用,甚至可以在低端设备上使用。
  • 突出对象检测 自动确定图片中最突出的对象。
  • 粗略分类:将对象分为广泛的类别,您可以使用这些类别过滤掉您不感兴趣的对象。支持以下类别:家居用品、时尚商品、食品、植物和地点。
  • 使用自定义模型分类 使用您自己的自定义图片分类模型来识别或过滤特定的对象类别。您可以去掉图片背景,提升自定义模型的性能。

3.7 准备工作

添加图像目标检测的依赖

dependencies {
  implementation 'com.google.mlkit:object-detection:17.0.0'
}

3.8 配置对象检测器

val options = ObjectDetectorOptions.Builder()
        .setDetectorMode(ObjectDetectorOptions.SINGLE_IMAGE_MODE) // STREAM_MODE 无延迟模式,前几次的结果不完整 SINGLE_IMAGE_MODE 延迟模式结果一起返回
        .enableMultipleObjects() // 启用多个对象检测,是检测和跟踪最多五个对象,还是仅检测和跟踪最突出的对象(默认)。
        .enableClassification()  // 是否将检测到的对象分类为粗类别。 启用后,对象检测器会将对象分为以下类别:时尚商品、食品、家居用品、地点和植物。
        .build()

3.9 获取ObjectDetector实例

val objectDetector = ObjectDetection.getClient(options)
// 将图片传递给 process() 方法:
objectDetector.process(image)
    .addOnSuccessListener { detectedObjects ->
        // Task completed successfully
        // ...
    }
    .addOnFailureListener { e ->
        // Task failed with an exception
        // ...
    }

每个 DetectedObject 包含以下属性:
请添加图片描述

4.0 目标检测demo

    // 配置对象检测器
    val options = ObjectDetectorOptions.Builder()
        .setDetectorMode(ObjectDetectorOptions.SINGLE_IMAGE_MODE)
        .enableMultipleObjects() // 开启多人
        .enableClassification()  // 开启分类
        .build()
     // 获取objectDetector实例
    val objectDetector = ObjectDetection.getClient(options)
    // 将图片传入process进行目标检测
	private fun objectDetector() {
        val image = InputImage.fromBitmap(resources.getDrawable(objectDetectorImage.intValue).toBitmap(), 0)
        objectDetector.process(image)
            .addOnSuccessListener { detectedObjects ->
                mDetctedObject.clear()
                mDetctedObject.addAll(detectedObjects)
                mDetctedObject.forEach {
                    Log.e("detectedObjects", "boundingBox:${it.boundingBox}===id:${it.trackingId}")
                    it.labels.forEach {
                        Log.e("detectedObjects", "可信度==${it.confidence}==分类${it.text}")
                    }
                }

            }
            .addOnFailureListener { e ->
            }

    }

点击按钮变化图片,调用检测方法

    val objectDetectorImage = mutableIntStateOf(0) // 图片状态变化

	Button(onClick = {
                        objectDetectorImage.intValue = R.drawable.img_7
                        objectDetector()
                    }) {
                        Text1(text = "图像目标检测")
                    }

将拿到的目标检测结果Rect绘制在图片上面

        Column(Modifier.size(450.dp, 300.dp)) {
                val bmp = resources.getDrawable(objectDetectorImage.intValue).toBitmap()
                Canvas(Modifier.aspectRatio(
                    bmp.width.toFloat() / bmp.height.toFloat())) {

                    drawIntoCanvas { canvas ->
                        canvas.withSave {
                            canvas.scale(size.width / bmp.width)
                            canvas.drawImage( // 绘制 image
                                image = bmp.asImageBitmap(), Offset(0f, 0f), Paint()
                            )
                            mDetctedObject.forEach {
                                canvas.drawRect( //绘制目标检测的边框
                                    it.boundingBox.toComposeRect(),
                                    Paint().apply {
                                        color = Color.Red.copy(alpha = 0.5f)
                                        style = Stroke
                                        strokeWidth = bmp.width * 0.01f
                                    })
                            }
                        }
                    }
                }
            }

效果
在这里插入图片描述

在这里插入图片描述

一共检测到5个目标,可信度是0.5,分类是 Fashion good, 一共有5种粗略的分类
在这里插入图片描述

总结

ML Kit 的优势在于它易于使用,开发者只需几行代码即可在应用中添加机器学习功能,所有功能都遵循同样的API模式,如果你曾经使用过某个API那么使用其他API也是相当简单。

ML Kit 还支持多种平台,包括 Android、iOS 和 Flutter。

参考资料:https://developers.google.com/ml-kit/guides?hl=zh-cn

  • 24
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值