Site icon AppTractor

Распознаем текст на изображении с помощью фреймворка 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:

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)
        }
    }
}

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

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

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

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

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)
    }
}

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

Затем в представлении 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 для обнаружения и определения местоположения текста на изображениях. Это послужит хорошей отправной точкой для расширения возможностей распознавания текста за счёт внедрения более продвинутых функций.

Источник

Exit mobile version