Tutorial deteksi teks dokumen yang rapat

Audience

Tujuan tutorial ini adalah untuk membantu Anda mengembangkan aplikasi menggunakan Deteksi Teks Dokumen Google Cloud Vision API. Tutorial ini mengasumsikan bahwa Anda telah memahami konstruksi dan teknik pemrograman dasar. Tetapi, meskipun Anda adalah programmer pemula, Anda seharusnya dapat mengikuti dan menjalankan tutorial ini tanpa kesulitan. Selanjutnya, Anda dapat menggunakan dokumentasi referensi Cloud Vision API untuk membuat aplikasi dasar.

Prasyarat

Membuat anotasi gambar menggunakan OCR Teks Dokumen

Tutorial ini membahas aplikasi Vision API dasar yang membuat permintaan DOCUMENT_TEXT_DETECTION, lalu memproses respons fullTextAnnotation.

fullTextAnnotation adalah respons hierarki terstruktur untuk teks UTF-8 yang diekstrak dari gambar dan disusun menjadi Pages→Blocks→Paragraphs→Words→Symbols:

  • Page adalah kumpulan blok, dengan tambahan informasi meta tentang halaman: ukuran dan resolusi (resolusi X dan resolusi Y dapat berbeda).

  • Block mewakili satu elemen logis dari halaman tersebut—misalnya. area yang tertutup teks, gambar, atau pemisah antar kolom. Blok teks dan tabel berisi informasi utama yang diperlukan untuk mengekstrak teks.

  • Paragraph adalah unit struktural teks yang mewakili rangkaian kata yang teratur. Secara default, kata-kata dianggap dipisahkan oleh jeda kata.

  • Word adalah unit terkecil dari teks. Kata direpresentasikan sebagai array Symbols.

  • Symbol mewakili karakter atau tanda baca.

fullTextAnnotation juga dapat memberikan URL ke gambar Web yang sebagian atau sepenuhnya cocok dengan gambar dalam permintaan.

Melengkapi daftar kode

Saat membaca kode, sebaiknya Anda mengikuti dengan melihat referensi Python Cloud Vision API Python.

import argparse
from enum import Enum

from google.cloud import vision
from PIL import Image, ImageDraw

class FeatureType(Enum):
    PAGE = 1
    BLOCK = 2
    PARA = 3
    WORD = 4
    SYMBOL = 5

def draw_boxes(image, bounds, color):
    """Draws a border around the image using the hints in the vector list.

    Args:
        image: the input image object.
        bounds: list of coordinates for the boxes.
        color: the color of the box.

    Returns:
        An image with colored bounds added.
    """
    draw = ImageDraw.Draw(image)

    for bound in bounds:
        draw.polygon(
            [
                bound.vertices[0].x,
                bound.vertices[0].y,
                bound.vertices[1].x,
                bound.vertices[1].y,
                bound.vertices[2].x,
                bound.vertices[2].y,
                bound.vertices[3].x,
                bound.vertices[3].y,
            ],
            None,
            color,
        )
    return image

def get_document_bounds(image_file, feature):
    """Finds the document bounds given an image and feature type.

    Args:
        image_file: path to the image file.
        feature: feature type to detect.

    Returns:
        List of coordinates for the corresponding feature type.
    """
    client = vision.ImageAnnotatorClient()

    bounds = []

    with open(image_file, "rb") as image_file:
        content = image_file.read()

    image = vision.Image(content=content)

    response = client.document_text_detection(image=image)
    document = response.full_text_annotation

    # Collect specified feature bounds by enumerating all document features
    for page in document.pages:
        for block in page.blocks:
            for paragraph in block.paragraphs:
                for word in paragraph.words:
                    for symbol in word.symbols:
                        if feature == FeatureType.SYMBOL:
                            bounds.append(symbol.bounding_box)

                    if feature == FeatureType.WORD:
                        bounds.append(word.bounding_box)

                if feature == FeatureType.PARA:
                    bounds.append(paragraph.bounding_box)

            if feature == FeatureType.BLOCK:
                bounds.append(block.bounding_box)

    # The list `bounds` contains the coordinates of the bounding boxes.
    return bounds

def render_doc_text(filein, fileout):
    """Outlines document features (blocks, paragraphs and words) given an image.

    Args:
        filein: path to the input image.
        fileout: path to the output image.
    """
    image = Image.open(filein)
    bounds = get_document_bounds(filein, FeatureType.BLOCK)
    draw_boxes(image, bounds, "blue")
    bounds = get_document_bounds(filein, FeatureType.PARA)
    draw_boxes(image, bounds, "red")
    bounds = get_document_bounds(filein, FeatureType.WORD)
    draw_boxes(image, bounds, "yellow")

    if fileout != 0:
        image.save(fileout)
    else:
        image.show()

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("detect_file", help="The image for text detection.")
    parser.add_argument("-out_file", help="Optional output file", default=0)
    args = parser.parse_args()

    render_doc_text(args.detect_file, args.out_file)

Aplikasi sederhana ini melakukan tugas-tugas berikut:

  • Mengimpor library yang diperlukan untuk menjalankan aplikasi
  • Mengambil tiga argumen untuk meneruskannya ke fungsi main():
    • image_file— file gambar input yang akan dianotasi
    • output_file—nama file output yang akan digunakan Cloud Vision untuk menghasilkan gambar output dengan polybox yang digambar
  • Membuat instance ImageAnnotatorClient untuk berinteraksi dengan layanan
  • Mengirim permintaan dan menampilkan respons
  • Membuat gambar output dengan kotak yang digambar di sekitar teks

Mempelajari kode lebih lanjut

Mengimpor library

import argparse
from enum import Enum

from google.cloud import vision
from PIL import Image, ImageDraw

Kami mengimpor library standar:

  • argparse untuk mengizinkan aplikasi menerima nama file input sebagai argumen
  • enum untuk enumerasi FeatureType
  • io untuk File I/O

Impor lainnya:

  • Class ImageAnnotatorClient dalam library google.cloud.vision untuk mengakses Vision API.
  • Modul types dalam library google.cloud.vision untuk membuat permintaan.
  • Library Image dan ImageDraw dari library PIL digunakan untuk membuat gambar output dengan kotak yang digambar pada gambar input.

Menjalankan aplikasi

parser = argparse.ArgumentParser()
parser.add_argument("detect_file", help="The image for text detection.")
parser.add_argument("-out_file", help="Optional output file", default=0)
args = parser.parse_args()

render_doc_text(args.detect_file, args.out_file)

Di sini, kita cukup mengurai argumen yang diteruskan, kemudian meneruskannya ke fungsi render_doc_text().

Mengautentikasi ke API

Sebelum berkomunikasi dengan layanan Vision API, Anda harus mengautentikasi layanan Anda menggunakan kredensial yang diperoleh sebelumnya. Dalam aplikasi, cara termudah untuk mendapatkan kredensial adalah dengan menggunakan Kredensial Default Aplikasi (ADC). Secara default, library klien Cloud akan mencoba mendapatkan kredensial dari variabel lingkungan GOOGLE_APPLICATION_CREDENTIALS, yang harus ditetapkan agar mengarah ke file kunci JSON akun layanan Anda (lihat Setting Up a Service Account for more information).

Membuat permintaan API dan membaca batas teks dari respons

Setelah layanan Vision API kami sudah siap, kita dapat mengakses layanan dengan memanggil metode document_text_detection dari instance ImageAnnotatorClient.

Library klien melakukan enkapsulasi detail permintaan dan respons ke API. Lihat Reference Vision API untuk mengetahui informasi lengkap tentang struktur permintaan.

def get_document_bounds(image_file, feature):
    """Finds the document bounds given an image and feature type.

    Args:
        image_file: path to the image file.
        feature: feature type to detect.

    Returns:
        List of coordinates for the corresponding feature type.
    """
    client = vision.ImageAnnotatorClient()

    bounds = []

    with open(image_file, "rb") as image_file:
        content = image_file.read()

    image = vision.Image(content=content)

    response = client.document_text_detection(image=image)
    document = response.full_text_annotation

    # Collect specified feature bounds by enumerating all document features
    for page in document.pages:
        for block in page.blocks:
            for paragraph in block.paragraphs:
                for word in paragraph.words:
                    for symbol in word.symbols:
                        if feature == FeatureType.SYMBOL:
                            bounds.append(symbol.bounding_box)

                    if feature == FeatureType.WORD:
                        bounds.append(word.bounding_box)

                if feature == FeatureType.PARA:
                    bounds.append(paragraph.bounding_box)

            if feature == FeatureType.BLOCK:
                bounds.append(block.bounding_box)

    # The list `bounds` contains the coordinates of the bounding boxes.
    return bounds

Setelah library klien menangani permintaan, respons kami akan berisi AnnotateImageResponse yang terdiri dari daftar hasil Anotasi Gambar, satu untuk setiap gambar yang dikirim dalam permintaan. Karena hanya mengirim satu gambar dalam permintaan, kita akan menelusuri full TextAnnotation, dan mengumpulkan batas untuk fitur dokumen yang ditentukan.

Menjalankan aplikasi

Untuk menjalankan aplikasi, Anda dapat mendownload file receipt.jpg ini (Anda mungkin perlu mengklik kanan link), lalu meneruskan lokasi tempat Anda mendownload di komputer lokal Anda ke aplikasi tutorial (doctext.py).

Berikut adalah perintah Python, diikuti dengan gambar output Anotasi Teks.

$ python doctext.py receipt.jpg -out_file out.jpg

Gambar berikut menampilkan kata dalam kotak kuning dan kalimat dalam kotak merah.

Selamat! Anda telah melakukan Deteksi Teks menggunakan Anotasi Teks Lengkap Google Cloud Vision!