В этой статье мы будем извлекать текст из изображения с помощью Google ML-KIT в нашем приложении флаттера. В предыдущей статье мы узнали, как создать проект флаттера, используя очень быстрый и удобный способ GET & CLI, теперь мы создадим новый проект, используя Get & CLI, а также реализацию приложение для извлечения текста во флаттере.

Прежде чем мы начнем, давайте разберемся, зачем нам нужно извлечение текста из изображений.

Извлечение текста является одним из обязательных этапов перед распознаванием символов. Целью извлечения текста является разделение каждого символа, чтобы его можно было передать на этап распознавания, например безопасность, конфиденциальность, классификацию положительных и отрицательных отзывов в приложениях, незаконные тексты на изображениях и многие другие цели.

Теперь давайте начнем.

1-Создать новый проект Flutter

Создайте новый проект флаттера с именем по вашему выбору (ml_text_extractor_flutter).

Проект по умолчанию выглядит следующим образом;

2-Shift Project to GetX Pattern

Примечание. если вы хотите использовать простой проект без GetX, создайте собственный шаблон (Контроллеры (логика) или Представления (экраны)).

Я буду использовать шаблон GetX с помощью команд Get & CLI. Если вы не знакомы с GET & CLI, прочтите мою предыдущую статью и активируйте CLI здесь.

Чтобы переключить проект на шаблон GetX, перейдите в корневой терминал проекта Android Studios и запустите приведенные ниже команды.

получить инициализацию

Теперь структура проекта будет выглядеть так;

  • Папка Data содержит все данные, которые нам нужно хранить в нашем проекте.
  • Папка Module содержит все страницы приложения (экран)
  • Папка Маршруты будет содержать все маршруты проекта (автоматически создается при создании страницы)

Дополнительная папка Modules содержит Модели, Контроллеры и Представления для хранения соответствующих файлов.

3-Подключить проект к Firebase (необязательно)

Подключите свой проект к firebase.

Примечание: если вы не знаете, как подключиться, посмотрите мою статью здесь.

4-Установите необходимые пакеты в Pubspec.yaml

1- image_picker здесь

2- firebase_core здесь

3- google_ml_kit здесь

ПРИМЕЧАНИЕ. При установке пакета следуйте полному руководству для платформы (android, ios, веб) с сайта pub.dev.

5-Создание пользовательского интерфейса домашней страницы

1- Перейдите в lib/app/modules/home/views

2- создать пользовательский интерфейс с выбираемой коробкой мага, кнопкой Выбрать изображение, кнопкой Извлечь текст и поле, чтобы показать выделенный текст с изображения.

3- Код ниже для пользовательского интерфейса;

HomeView.dart

import 'package:flutter/material.dart';

import 'package:get/get.dart';

import '../controllers/home_controller.dart';

class HomeView extends GetView<HomeController> {
  const HomeView({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Text Extractor App'),
        centerTitle: true,
      ),
      body: Center(
        child: Padding(
          padding: EdgeInsets.all(12),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              ///image box container
              Container(
                height: 220,
                margin: EdgeInsets.all(12),
        decoration: BoxDecoration(
              color: Colors.white,
              border: Border.all(color: Colors.grey.shade300),
        ),

        ),
              ///button row
              Container(
                margin: const EdgeInsets.all(12),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    ElevatedButton(onPressed: (){}, child: const Text("Pick Image")),
                    ElevatedButton(onPressed: (){}, child: const Text("Extract Text")),
                  ],
                ),
              ),
              ///text box container
              Container(
import 'package:flutter/material.dart';

import 'package:get/get.dart';

import '../controllers/home_controller.dart';

class HomeView extends GetView<HomeController> {
  const HomeView({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Text Extractor App'),
        centerTitle: true,
      ),
      body: Center(
        child: Padding(
          padding: EdgeInsets.all(12),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              ///image box container
              Container(
                height: 220,
                margin: EdgeInsets.all(12),
        decoration: BoxDecoration(
              color: Colors.white,
              border: Border.all(color: Colors.grey.shade300),
        ),

        ),
              ///button row
              Container(
                margin: const EdgeInsets.all(12),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    ElevatedButton(onPressed: (){}, child: const Text("Pick Image")),
                    ElevatedButton(onPressed: (){}, child: const Text("Extract Text")),
                  ],
                ),
              ),
              ///text box container
              Container(
                height: 190,
                margin: EdgeInsets.all(12),
                decoration: BoxDecoration(
                  color: Colors.white,
                  border: Border.all(color: Colors.grey.shade300),
                ),

              ),
            ],
          ),
        )
      ),
    );
  }
}                height: 190,
                margin: EdgeInsets.all(12),
                decoration: BoxDecoration(
                  color: Colors.white,
                  border: Border.all(color: Colors.grey.shade300),
                ),

              ),
            ],
          ),
        )
      ),
    );
  }
}

Вывод:

6- Серверная часть

Теперь мы напишем внутреннюю функциональность в папке controllers'. В нашем HomeController.dart мы создадим два метода: один для getImage(), а второй для cognizedText().

HomeController.dart

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:google_ml_kit/google_ml_kit.dart';
import 'package:image_picker/image_picker.dart';

class HomeController extends GetxController {
  //TODO: Implement HomeController

  var selectedImagePath=''.obs;
  var extractedText=''.obs;
  ///get image method
  getImage(ImageSource imageSource) async{
    final pickedFile= await ImagePicker().pickImage(source: ImageSource.gallery);
    if(pickedFile!=null){
      selectedImagePath.value=pickedFile.path;
    }
    else{
       Get.snackbar(

           "Error", "image is not selected"
       ,
       backgroundColor: Colors.red);
    }

  }
  ///recognise image text method
  Future<void> recognizedText(String pickedImage) async {
    if (pickedImage == null) {
      Get.snackbar(

          "Error", "image is not selected"
          ,
          backgroundColor: Colors.red);
    }
    else {
      extractedText.value = '';
      var textRecognizer = GoogleMlKit.vision.textRecognizer();
      final visionImage = InputImage.fromFilePath(pickedImage);
      try{

        var visionText= await textRecognizer.processImage(visionImage);
        for(TextBlock textBlock in visionText.blocks){
          for(TextLine textLine in textBlock.lines){
            for(TextElement textElement in textLine.elements){
              extractedText.value=extractedText.value + textElement.text+' ';
            }
            extractedText.value=extractedText.value + " \n";
          }
        }
      }
      catch(e){
        Get.snackbar(

            "Error", e.toString()
            ,
            backgroundColor: Colors.red);
      }
    }
  }
  @override
  void onInit() {
    super.onInit();
  }

  @override
  void onReady() {
    super.onReady();
  }

  @override
  void onClose() {
    super.onClose();
  }


}

Примечание. Вам может потребоваться импортировать dart.io для приведенного выше кода (для файлов).

Объяснение обоих методов в бэкэнд-файле

1- getImage(ImageSource imageSource):›С помощью этого метода мы выбрали изображение из галереи с помощью пакета image_picker. Мы сохранили путь к файлу изображения в переменной с именем selectedImagePath.

2-cognizedText(String selectedImage):›Мы инициализировали textRognizer() из пакета google_ml_kit. Передал входное изображение в textRecognizer() для некоторой обработки. Затем с помощью цикла for мы обработали весь текст на изображении, например TextBlocks, TextLines, TextElements. . Сохранил извлеченный текст в текстовом виджете, вот и все.

7- Обновленный пользовательский интерфейс после бэкенда

HomeView.dart (окончательный)

import 'dart:io';

import 'package:flutter/material.dart';

import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';

import '../controllers/home_controller.dart';

class HomeView extends GetView<HomeController> {
  const HomeView({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Text Extractor App'),
        centerTitle: true,
      ),
      body: Center(
        child: Padding(
          padding: EdgeInsets.all(12),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              ///image box container
              Container(
                height: 220,
                margin: EdgeInsets.all(12),
        decoration: BoxDecoration(
              color: Colors.white,
              border: Border.all(color: Colors.grey.shade300),
        ),
child:
    ///image box scrollview
              SingleChildScrollView(
                child: Obx(()=>

                controller.selectedImagePath.value==''?
                const Center(child: Text("Select an image from Gallery / camera")):
                Image.file(
                  File(controller.selectedImagePath.value),
                  width: Get.width,
                  height: 300,
                ),


                ),
              )
        ),
              ///button row
              Container(
                margin: const EdgeInsets.all(12),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    ElevatedButton(onPressed: (){
                      controller.getImage(ImageSource.gallery);
                    }, child: const Text("Pick Image")),
                    ElevatedButton(onPressed: (){
                      controller.recognizedText(controller.selectedImagePath.value);
                    }, child: const Text("Extract Text")),
                  ],
                ),
              ),
              ///text box ScrollView
              SingleChildScrollView(
                child: Container(
                  height: 190,
                  margin: EdgeInsets.all(12),
                  decoration: BoxDecoration(
                    color: Colors.white,
                    border: Border.all(color: Colors.grey.shade300),
                  ),
                  child: Obx(()=>

                  controller.extractedText.value.isEmpty?
                  const Center(child: Text("Text Not Found")):
                  Center(child: Text(controller.extractedText.value))


                  ),
                ),
              )
            ],
          ),
        )
      ),
    );
  }
}

Вывод (окончательный)

1

2

Поздравляем! Вы научились извлекать текст из изображения, используя официальный и правильный способ, предложенный Google ML-KIT с шаблоном флаттера GetX. Следите за моей следующей статьей о машинном обучении с помощью флаттера.

Похлопайте статье и подпишитесь на меня, чтобы не пропустить новые флаттер-статьи.

Исходный код :

Посетите Github Здесь

Подпишитесь на меня на Github, чтобы узнать о большом банке проектов GetX.