Есть ли способ указать структуру документа, чтобы Google Vision обрабатывал документ в определенном поместье? - PullRequest
1 голос
/ 01 июня 2019

Обнаружение текста документа Google Vision хорошо распознает символы и слова, но группирует текст строго по строкам и абзацам, и даже в этом случае иногда текст логически неуместен при обработке документа со структурированным текстом.

Я уже просмотрел документацию по API и не могу найти и примеры или ссылки для предоставления подсказок (кроме языка), чтобы изменить способ анализа документа. Одним из возможных решений может быть предварительная обработка документа и использование API Google для обработки документа по одному фрагменту за раз, но предпочтение отдается использованию API Google напрямую без промежуточных шагов.

Код, который я использую, был взят непосредственно из примера google vision pdf python и воспроизводится с использованием этого кода без каких-либо изменений:

https://cloud.google.com/vision/docs/pdf


from google.cloud import storage
import re

def async_detect_document(gcs_source_uri, gcs_destination_uri):
    """OCR with PDF/TIFF as source files on GCS"""
    from google.cloud import vision
    mime_type = 'application/pdf'
    batch_size = 2
    client = vision.ImageAnnotatorClient()

    feature = vision.types.Feature(
        type=vision.enums.Feature.Type.DOCUMENT_TEXT_DETECTION)

    gcs_source = vision.types.GcsSource(uri=gcs_source_uri)
    input_config = vision.types.InputConfig(
        gcs_source=gcs_source, mime_type=mime_type)

    gcs_destination = vision.types.GcsDestination(uri=gcs_destination_uri)
    output_config = vision.types.OutputConfig(
        gcs_destination=gcs_destination, batch_size=batch_size)

    async_request = vision.types.AsyncAnnotateFileRequest(
        features=[feature], input_config=input_config,
        output_config=output_config)

    operation = client.async_batch_annotate_files(
        requests=[async_request])

    print('Waiting for the operation to finish.')
    operation.result(timeout=180)
    storage_client = storage.Client()

    match = re.match(r'gs://([^/]+)/(.+)', gcs_destination_uri)
    bucket_name = match.group(1)
    prefix = match.group(2)

    bucket = storage_client.get_bucket(bucket_name)

    # List objects with the given prefix.
    blob_list = list(bucket.list_blobs(prefix=prefix))
    print('Output files:')
    for blob in blob_list:
        print(blob.name)

Результаты должны быть сгруппированы по-разному, логически, при просмотре документа адрес должен быть сгруппирован вместе. Вот как структурирован один документ (верхние 4 строки):

-----------------------------------------------------------------
| Active              |  2415 ST PETER STREET |  $500,000 (LP) 
| R2222222            |    Port Moody Centre  |           (SP) 
| Board: V, Attached  |       Port Moody      |
| House/Single Family |         V3G 2T5       |
-----------------------------------------------------------------

Вот пример документа, который показывает структуру документа

После использования примера, предоставленного Google, и распечатки результата вместе с номерами страниц, блоков и абзацев, чтобы, надеюсь, показать, что происходит. Мы видим, что текст в верхней части файла находится не в том месте, а показанная выше информация разбросана по нескольким абзацам и начинается в блоке 5, где он должен начинаться в блоке 0:

********* Page Number: 0*************
********* Block Number: 0*************
********* Paragraph Number: 0*************
MAIN FLOOR 
BASEMENT 
TOTAL FINISHED AREA 
UNFINISHED" 
TOTAL AREA

[ snip ]

********* Block Number: 5*************
********* Paragraph Number: 10*************
Active 
2415 ST PETER STREET
********* Paragraph Number: 11*************
$500,000 (LP) 
R2222222 
Port Moody
********* Paragraph Number: 12*************
(SP) 
Board: V, Attached
********* Paragraph Number: 13*************
Port Moody Centre 
********* Paragraph Number: 15*************
V3G 2T5 
********* Paragraph Number: 16*************

[ SNIP ]

Приведенный выше вывод был сгенерирован с использованием:

def annotate(_json):
    annotation = _json['responses'][0]['fullTextAnnotation']
    line = 0
    paranum = 0
    blcknum = 0
    pgenum = 0
    for page in annotation['pages']:
        print('********* Page Number: ' + str(pgenum) + '*************')
        pgenum += 1
        for block in page['blocks']:
            print('********* Block Number: ' + str(blcknum) + '*************')
            blcknum += 1
            for paragraph in block['paragraphs']:
                print('********* Paragraph Number: ' + str(paranum) + '*************')
                paranum += 1
                for word in paragraph['words']:
                    for symbol in word['symbols']:
                        print(symbol['text'], end='')
                        try:
                            bType = symbol['property']['detectedBreak']['type']
                            if bType == 'SPACE':
                                print(' ', end='')
                            if bType == 'EOL_SURE_SPACE':
                                print(' ')
                            if bType == 'LINE_BREAK':
                                print('')
                        except KeyError:
                            print('', end='')
                line += 1
...