Connect with us

Разработка

Распознаем текст на изображении с помощью фреймворка Vision

В этой статье вы узнали, как использовать встроенные функции Vision для обнаружения и определения местоположения текста на изображениях. Это послужит хорошей отправной точкой для расширения возможностей распознавания текста за счёт внедрения более продвинутых функций.

Опубликовано

/

     
     

Мы рассмотрим, как использовать машинное обучение для обнаружения и определения местоположения текста на изображении с помощью фреймворка Vision. Фреймворк Vision может гораздо больше, чем просто поиск текста на изображении. Он также способен изолировать определённые области на изображениях, отслеживать объекты в последовательности изображений, определять положение рук и тела и многое другое.

Если вы работали над проектами, связанными со сканированием QR- или штрихкодов, скорее всего, вы уже использовали Vision, возможно, даже не осознавая этого. Лично я впервые столкнулся с Vision, когда создал консольную утилиту на Swift для удаления фона с изображений.

Создание распознавателя текста

Давайте начнём с изучения того, как использовать ML-фреймворк Vision от Apple для извлечения текста из изображений.

Для начала настроим компонент распознавания текста:

import Foundation
import SwiftUI
import Vision
 
struct TextRecognizer {
    var recognizedText = ""
    var observations: [RecognizedTextObservation] = []
 
    init(imageResource: ImageResource) async {
        // Create a RecognizeTextRequest.
        var request = RecognizeTextRequest()
        // Set the request's recognitionLevel to .accurate.
        request.recognitionLevel = .accurate
        // Create a UIImage using the ImageResource.
        let image = UIImage(resource: imageResource)
        // Convert the UIImage to Data.
        if let imageData = image.pngData(),
           // The perform request can fail
           // so use try? to proceed only when results are available.
           let results = try? await request.perform(on: imageData) {
            // Store the observations that are returned by the RecognizeTextRequest.
            observations = results
        }
 
        // Iterate through the observations 
        // and get the top candidate of the potential text values.
        for observation in observations {
            let candidate = observation.topCandidates(1)
            if let observedText = candidate.first?.string {
                recognizedText += "\n\(observedText) "
            }
        }
    }
}

Вот краткий обзор того, что делает этот код:

  • Импортирует фреймворки SwiftUI и Vision
  • Создает RecognizeTextRequest, который является частью инструментов Vision для распознавания текста на изображениях.
  • Преобразует UIImage в Data. Этот шаг необходим, поскольку RecognizeTextRequest работает с данными, а не с типами изображений Swift, такими как UIImage.
  • Использует метод perform объекта текстового запроса для анализа изображения и сбора результатов. Поскольку это требует асинхронной обработки, функция инициализации должна быть помечена как async для корректного ожидания результата.
  • Сохраняет наблюдения, возвращаемые RecognizeTextRequest.
  • Проходит по наблюдениям и получает наиболее подходящий вариант потенциального текстового значения.
  • Всякий раз, когда распознанный текст найден, добавляет его к локальному свойству.

Вот как мы можем интегрировать его в представление SwiftUI:

import SwiftUI
 
struct TextRecognitionView: View {
    let imageResource: ImageResource
    @State private var textRecognizer: TextRecognizer?
 
    var body: some View {
        List {
            Section {
                Image(imageResource)
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .clipShape(RoundedRectangle(cornerRadius: 8))
            }
            .listRowBackground(Color.clear)
 
            Section {
                Text(textRecognizer?.recognizedText ?? "")
            } header: {
                Text("Identified text from image")
            }
        }
        .navigationTitle("Text Recognition")
        .task {
            // The initializer is async
            // so you need to call it from an async function or a task.
            textRecognizer = await TextRecognizer(imageResource: imageResource)
        }
    }
}

Ниже представлен скриншот, демонстрирующий эту функцию в действии:

Распознаем текст на изображении с помощью фреймворка Vision

Выделение найденного текста

Теперь, когда мы определили текст на изображении, следующим шагом будет его визуальное выделение путем рисования прямоугольников вокруг обнаруженных текстовых областей.

Для этого мы начнём с определения структуры, представляющей собой форму, которую можно нарисовать.

import Foundation
import SwiftUI
import Vision
 
struct BoundsRect: Shape {
    let normalizedRect: NormalizedRect
 
    func path(in rect: CGRect) -> Path {
        // Convert the normalized coordinates to the coordinates of the image.
        let imageCoordinatesRect = normalizedRect
            .toImageCoordinates(rect.size, origin: .upperLeft)
        return Path(imageCoordinatesRect)
    }
}

Вот краткий обзор того, что делает код:

  • Соответствие протоколу Shape.
  • Импортирует фреймворк Vision и определяет свойство NormalizedRect. Каждое распознанное текстовое наблюдение включает данные о местоположении, указывающие, где текст был обнаружен на изображении.
  • Преобразует нормализованные координаты в координаты изображения.

Затем в представлении SwiftUI мы можем добавить оверлей к изображению, чтобы нарисовать фигуры BoundsRect вокруг каждого блока распознанного текста.

Вот как это можно сделать:

struct TextRecognitionView: View {
    [...]
    let boundingColor = Color(red: 0.31, green: 0.11, blue: 0.11)
 
    var body: some View {
        List {
            Section {
                Image(imageResource)
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .clipShape(RoundedRectangle(cornerRadius: 8))
                    .overlay {
                        if let observations = textRecognizer?.observations {
                            ForEach(observations, id: \.uuid) { observation in
                                // Draw a BoundsRect around 
                                // each text item observed in the image.
                                BoundsRect(normalizedRect: observation.boundingBox)
                                    .stroke(boundingColor, lineWidth: 3)
                            }
                        }
                    }
            }
            [...]
        }
    }
}

Ниже представлен скриншот, демонстрирующий функцию выделения текста в действии:

Распознаем текст на изображении с помощью фреймворка Vision

Заключение

Фреймворк Vision — это мощный и универсальный инструмент, способный не только находить текст на изображении. Он также способен изолировать определённые области на изображениях, отслеживать объекты в последовательности изображений, определять положение рук и тела и многое другое.

В этой статье вы узнали, как использовать встроенные функции Vision для обнаружения и определения местоположения текста на изображениях. Это послужит хорошей отправной точкой для расширения возможностей распознавания текста за счёт внедрения более продвинутых функций.

Источник

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Telegram

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: