Extraia texto e informações de imagens no enriquecimento de IA

Através do enriquecimento de IA, o Azure AI Search dá-lhe várias opções para criar e extrair texto pesquisável de imagens, incluindo:

  • OCR para reconhecimento ótico de caracteres de texto e dígitos
  • Análise de imagem que descreve imagens através de recursos visuais
  • Habilidades personalizadas para invocar qualquer processamento de imagem externo que você deseja fornecer

Através do OCR, você pode extrair texto de fotos ou imagens contendo texto alfanumérico, como a palavra "STOP" em um sinal de parada. Através da análise de imagem, você pode gerar uma representação de texto de uma imagem, como "dente de leão" para uma foto de um dente de leão, ou a cor "amarelo". Você também pode extrair metadados sobre a imagem, como seu tamanho.

Este artigo aborda os fundamentos do trabalho com imagens e também descreve vários cenários comuns, como trabalhar com imagens incorporadas, habilidades personalizadas e sobreposição de visualizações em imagens originais.

Para trabalhar com conteúdo de imagem em um conjunto de habilidades, você precisará:

  • Arquivos de origem que incluem imagens
  • Um indexador de pesquisa, configurado para ações de imagem
  • Um conjunto de habilidades com habilidades internas ou personalizadas que invocam OCR ou análise de imagem
  • Um índice de pesquisa com campos para receber a saída de texto analisada, além de mapeamentos de campo de saída no indexador que estabelecem associação.

Opcionalmente, você pode definir projeções para aceitar a saída analisada por imagem em um armazenamento de conhecimento para cenários de mineração de dados.

Configurar arquivos de origem

O processamento de imagem é controlado por indexador, o que significa que as entradas brutas devem estar em uma fonte de dados suportada.

  • A análise de imagem suporta JPEG, PNG, GIF e BMP
  • OCR suporta JPEG, PNG, BMP e TIF

As imagens são arquivos binários autônomos ou incorporados em documentos (PDF, RTF e arquivos de aplicativos da Microsoft). Um máximo de 1000 imagens podem ser extraídas de um determinado documento. Se houver mais de 1000 imagens em um documento, as primeiras 1000 são extraídas e, em seguida, um aviso é gerado.

O Armazenamento de Blobs do Azure é o armazenamento usado com mais frequência para processamento de imagens na Pesquisa de IA do Azure. Há três tarefas principais relacionadas à recuperação de imagens de um contêiner de blob:

Configurar indexadores para processamento de imagens

Depois que os arquivos de origem forem configurados, habilite a normalização da imagem definindo o parâmetro na configuração do imageAction indexador. A normalização de imagens ajuda a tornar as imagens mais uniformes para processamento a jusante. A normalização de imagem inclui as seguintes operações:

  • As imagens grandes são redimensionadas para uma altura e largura máximas para torná-las uniformes.
  • Para imagens com metadados na orientação, a rotação da imagem é ajustada para carregamento vertical.

Os ajustes de metadados são capturados em um tipo complexo criado para cada imagem. Não é possível desativar o requisito de normalização de imagem. Habilidades que iteram sobre imagens, como OCR e análise de imagem, esperam imagens normalizadas.

  1. Crie ou atualize um indexador para definir as propriedades de configuração:

    {
      "parameters":
      {
        "configuration": 
        {
           "dataToExtract": "contentAndMetadata",
           "parsingMode": "default",
           "imageAction": "generateNormalizedImages"
        }
      }
    }
    
  2. Defina dataToExtract como contentAndMetadata (obrigatório).

  3. Verifique se o parsingMode está definido como padrão (obrigatório).

    Este parâmetro determina a granularidade dos documentos de pesquisa criados no índice. O modo padrão configura uma correspondência um-para-um para que um blob resulte em um documento de pesquisa. Se os documentos forem grandes ou se as habilidades exigirem pedaços menores de texto, você poderá adicionar a habilidade Divisão de texto que subdivide um documento em paginação para fins de processamento. Mas para cenários de pesquisa, é necessário um blob por documento se o enriquecimento incluir processamento de imagem.

  4. Defina imageAction para habilitar o nó normalized_images em uma árvore de enriquecimento (obrigatório):

    • generateNormalizedImages para gerar uma matriz de imagens normalizadas como parte da quebra de documentos.

    • generateNormalizedImagePerPage (aplica-se apenas a PDF) para gerar uma matriz de imagens normalizadas onde cada página do PDF é renderizada em uma imagem de saída. Para arquivos não-PDF, o comportamento desse parâmetro é semelhante como se você tivesse definido "generateNormalizedImages". No entanto, observe que a configuração "generateNormalizedImagePerPage" pode tornar a operação de indexação menos eficiente por design (especialmente para documentos grandes), uma vez que várias imagens teriam que ser geradas.

  5. Opcionalmente, ajuste a largura ou altura das imagens normalizadas geradas:

    • normalizedImageMaxWidth (em pixels). O padrão é 2000. O valor máximo é 10000.

    • normalizedImageMaxHeight (em pixels). O padrão é 2000. O valor máximo é 10000.

    O padrão de 2000 pixels para a largura e altura máximas das imagens normalizadas é baseado nos tamanhos máximos suportados pela habilidade OCR e pela habilidade de análise de imagem. A habilidade OCR suporta uma largura e altura máximas de 4200 para idiomas diferentes do inglês e 10000 para o inglês. Se você aumentar os limites máximos, o processamento pode falhar em imagens maiores, dependendo da definição do conjunto de habilidades e do idioma dos documentos.

  • Opcionalmente, defina critérios de tipo de arquivo se a carga de trabalho tiver como alvo um tipo de arquivo específico. A configuração do indexador de Blob inclui configurações de inclusão e exclusão de arquivos. Pode filtrar ficheiros que não pretende.

    {
      "parameters" : { 
          "configuration" : { 
              "indexedFileNameExtensions" : ".pdf, .docx",
              "excludedFileNameExtensions" : ".png, .jpeg" 
          } 
      }
    }
    

Sobre imagens normalizadas

Quando imageAction é definido como um valor diferente de "nenhum", o novo campo normalized_images contém uma matriz de imagens. Cada imagem é um tipo complexo que tem os seguintes membros:

Membro da imagem Description
data BASE64 seqüência codificada da imagem normalizada em formato JPEG.
width Largura da imagem normalizada em pixels.
altura Altura da imagem normalizada em pixels.
originalWidth A largura original da imagem antes da normalização.
originalAltura A altura original da imagem antes da normalização.
rotaçãoFromOriginal Rotação no sentido anti-horário em graus que ocorreram para criar a imagem normalizada. Um valor entre 0 graus e 360 graus. Esta etapa lê os metadados da imagem gerada por uma câmera ou scanner. Geralmente um múltiplo de 90 graus.
contentOffset O deslocamento de caracteres dentro do campo de conteúdo de onde a imagem foi extraída. Este campo só é aplicável a ficheiros com imagens incorporadas. O contentOffset para imagens extraídas de documentos PDF está sempre no final do texto na página da qual foi extraído no documento. Isto significa que as imagens aparecem depois de todo o texto nessa página, independentemente da localização original da imagem na página.
Número da página Se a imagem foi extraída ou renderizada de um PDF, este campo contém o número da página no PDF do qual foi extraída ou renderizada, a partir de 1. Se a imagem não for de um PDF, este campo será 0.

Valor da amostra de normalized_images:

[
  {
    "data": "BASE64 ENCODED STRING OF A JPEG IMAGE",
    "width": 500,
    "height": 300,
    "originalWidth": 5000,  
    "originalHeight": 3000,
    "rotationFromOriginal": 90,
    "contentOffset": 500,
    "pageNumber": 2
  }
]

Definir skillsets para processamento de imagens

Esta seção complementa os artigos de referência de habilidades, fornecendo contexto para trabalhar com entradas, saídas e padrões de habilidades, conforme eles se relacionam com o processamento de imagens.

  1. Crie ou atualize um conjunto de habilidades para adicionar habilidades.

  2. Adicione modelos para OCR e Análise de Imagem do portal ou copie as definições da documentação de referência de habilidades. Insira-os na matriz de habilidades da sua definição de conjunto de habilidades.

  3. Se necessário, inclua a chave multisserviço na propriedade de serviços de IA do Azure do conjunto de habilidades. O Azure AI Search faz chamadas para um recurso faturável de serviços de IA do Azure para OCR e análise de imagem para transações que excedem o limite gratuito (20 por indexador por dia). Os serviços de IA do Azure devem estar na mesma região que o seu serviço de pesquisa.

  4. Se as imagens originais estiverem incorporadas em PDF ou em arquivos de aplicativos como PPTX ou DOCX, você precisará adicionar uma habilidade de mesclagem de texto se quiser saída de imagem e saída de texto juntas. O trabalho com imagens incorporadas é discutido mais adiante neste artigo.

Depois que a estrutura básica do seu conjunto de habilidades for criada e os serviços de IA do Azure forem configurados, você poderá se concentrar em cada habilidade de imagem individual, definindo entradas e contexto de origem e mapeando saídas para campos em um índice ou armazenamento de conhecimento.

Nota

Consulte Tutorial REST: Usar REST e IA para gerar conteúdo pesquisável a partir de blobs do Azure para obter um conjunto de habilidades de exemplo que combina processamento de imagem com processamento de linguagem natural downstream. Ele mostra como alimentar a saída de imagens de habilidades no reconhecimento de entidades e extração de frases-chave.

Sobre entradas para processamento de imagens

Como observado, as imagens são extraídas durante a quebra de documentos e, em seguida, normalizadas como uma etapa preliminar. As imagens normalizadas são as entradas para qualquer habilidade de processamento de imagem e são sempre representadas em uma árvore de documentos enriquecida de uma das duas maneiras:

  • /document/normalized_images/* destina-se a documentos que são processados inteiros.

  • /document/normalized_images/*/pages é para documentos que são processados em partes (páginas).

Se você estiver usando OCR e análise de imagem no mesmo, as entradas têm praticamente a mesma construção:

    {
      "@odata.type": "#Microsoft.Skills.Vision.OcrSkill",
      "context": "/document/normalized_images/*",
      "detectOrientation": true,
      "inputs": [
        {
          "name": "image",
          "source": "/document/normalized_images/*"
        }
      ],
      "outputs": [ ]
    },
    {
      "@odata.type": "#Microsoft.Skills.Vision.ImageAnalysisSkill",
      "context": "/document/normalized_images/*",
      "visualFeatures": [ "tags", "description" ],
      "inputs": [
        {
          "name": "image",
          "source": "/document/normalized_images/*"
        }
      ],
      "outputs": [ ]
    }

Mapear saídas para campos de pesquisa

Em um conjunto de habilidades, Análise de Imagem e saída de habilidades OCR é sempre texto. O texto de saída é representado como nós em uma árvore de documentos enriquecida interna e cada nó deve ser mapeado para campos em um índice de pesquisa ou para projeções em um repositório de conhecimento para disponibilizar o conteúdo em seu aplicativo.

  1. No conjunto de habilidades, revise a outputs seção de cada habilidade para determinar quais nós existem no documento enriquecido:

    {
      "@odata.type": "#Microsoft.Skills.Vision.OcrSkill",
      "context": "/document/normalized_images/*",
      "detectOrientation": true,
      "inputs": [ ],
      "outputs": [
        {
          "name": "text",
          "targetName": "text"
        },
        {
          "name": "layoutText",
          "targetName": "layoutText"
        }
      ]
    }
    
  2. Crie ou atualize um índice de pesquisa para adicionar campos para aceitar os resultados de habilidades.

    No exemplo de coleção de campos a seguir, "conteúdo" é conteúdo de blob. "Metadata_storage_name" contém o nome do ficheiro (certifique-se de que é "recuperável"). "Metadata_storage_path" é o caminho exclusivo do blob e é a chave de documento padrão. "Merged_content" é a saída da mesclagem de texto (útil quando as imagens são incorporadas).

    "Text" e "layoutText" são saídas de habilidades OCR e devem ser uma coleção de cadeias de caracteres para capturar toda a saída gerada por OCR para todo o documento.

      "fields": [
        {
          "name": "content",
          "type": "Edm.String",
          "filterable": false,
          "retrievable": true,
          "searchable": true,
          "sortable": false
        },
        {
          "name": "metadata_storage_name",
          "type": "Edm.String",
          "filterable": true,
          "retrievable": true,
          "searchable": true,
          "sortable": false
        },
        {
          "name": "metadata_storage_path",
          "type": "Edm.String",
          "filterable": false,
          "key": true,
          "retrievable": true,
          "searchable": false,
          "sortable": false
        },
        {
          "name": "merged_content",
          "type": "Edm.String",
          "filterable": false,
          "retrievable": true,
          "searchable": true,
          "sortable": false
        },
        {
          "name": "text",
          "type": "Collection(Edm.String)",
          "filterable": false,
          "retrievable": true,
          "searchable": true
        },
        {
          "name": "layoutText",
          "type": "Collection(Edm.String)",
          "filterable": false,
          "retrievable": true,
          "searchable": true
        }
      ],
    
  3. Atualize o indexador para mapear a saída do conjunto de habilidades (nós em uma árvore de enriquecimento) para campos de índice.

    Os documentos enriquecidos são internos. Para externalizar os nós em uma árvore de documentos enriquecida, configure um mapeamento de campo de saída que especifique qual campo de índice recebe conteúdo de nó. Os dados enriquecidos são acessados pelo seu aplicativo por meio de um campo de índice. O exemplo a seguir mostra um nó "texto" (saída OCR) em um documento enriquecido que é mapeado para um campo "texto" em um índice de pesquisa.

      "outputFieldMappings": [
        {
          "sourceFieldName": "/document/normalized_images/*/text",
          "targetFieldName": "text"
        },
        {
          "sourceFieldName": "/document/normalized_images/*/layoutText",
          "targetFieldName": "layoutText"
        }
      ]
    
  4. Execute o indexador para invocar a recuperação do documento de origem, o processamento de imagens e a indexação.

Verificar resultados

Execute uma consulta no índice para verificar os resultados do processamento de imagens. Use o Search Explorer como um cliente de pesquisa ou qualquer ferramenta que envie solicitações HTTP. A consulta a seguir seleciona campos que contêm a saída do processamento de imagens.

POST /indexes/[index name]/docs/search?api-version=[api-version]
{
    "search": "*",
    "select": "metadata_storage_name, text, layoutText, imageCaption, imageTags"
}

OCR reconhece texto em arquivos de imagem. Isso significa que os campos OCR ("text" e "layoutText") estão vazios se os documentos de origem forem texto puro ou imagens puras. Da mesma forma, os campos de análise de imagem ("imageCaption" e "imageTags") ficam vazios se as entradas do documento de origem forem estritamente texto. A execução do indexador emite avisos se as entradas de imagem estiverem vazias. Esses avisos são esperados quando os nós não são preenchidos no documento enriquecido. Lembre-se de que a indexação de blob permite incluir ou excluir tipos de arquivo se quiser trabalhar com tipos de conteúdo isoladamente. Você pode usar essas configurações para reduzir o ruído durante as execuções do indexador.

Uma consulta alternativa para verificar os resultados pode incluir os campos "conteúdo" e "merged_content". Observe que esses campos incluem conteúdo para qualquer arquivo blob, mesmo aqueles onde não houve processamento de imagem executado.

Sobre os resultados de habilidades

Os resultados de habilidades incluem "texto" (OCR), "layoutText" (OCR), "merged_content", "legendas" (análise de imagem), "tags" (análise de imagem):

  • "text" armazena a saída gerada por OCR. Este nó deve ser mapeado para o campo do tipo Collection(Edm.String). Há um campo "texto" por documento de pesquisa que consiste em cadeias de caracteres delimitadas por vírgulas para documentos que contêm várias imagens. A ilustração a seguir mostra a saída OCR para três documentos. O primeiro é um documento que contém um arquivo sem imagens. O segundo é um documento (arquivo de imagem) contendo uma palavra, "Microsoft". O terceiro é um documento que contém várias imagens, algumas sem qualquer texto ("",).

    "value": [
        {
            "@search.score": 1,
            "metadata_storage_name": "facts-about-microsoft.html",
            "text": []
        },
        {
            "@search.score": 1,
            "metadata_storage_name": "guthrie.jpg",
            "text": [ "Microsoft" ]
        },
        {
            "@search.score": 1,
            "metadata_storage_name": "Azure AI services and Content Intelligence.pptx",
            "text": [
                "",
                "Microsoft",
                "",
                "",
                "",
                "Azure AI Search and Augmentation Combining Microsoft Azure AI services and Azure Search"
            ]
        }
    ]
    
  • "layoutText" armazena informações geradas por OCR sobre a localização do texto na página, descritas em termos de caixas delimitadoras e coordenadas da imagem normalizada. Este nó deve ser mapeado para o campo do tipo Collection(Edm.String). Há um campo "layoutText" por documento de pesquisa que consiste em cadeias de caracteres delimitadas por vírgula.

  • "merged_content" armazena a saída de uma habilidade de mesclagem de texto e deve ser um grande campo do tipo Edm.String que contém texto bruto do documento de origem, com "texto" incorporado no lugar de uma imagem. Se os arquivos são somente texto, então OCR e análise de imagem não têm nada a ver, e "merged_content" é o mesmo que "content" (uma propriedade blob que contém o conteúdo do blob).

  • "imageCaption" captura uma descrição de uma imagem como tags individuais e uma descrição de texto mais longa.

  • "imageTags" armazena tags sobre uma imagem como uma coleção de palavras-chave, uma coleção para todas as imagens no documento de origem.

A captura de tela a seguir é uma ilustração de um PDF que inclui texto e imagens incorporadas. A fissuração de documentos detetou três imagens embutidas: bando de gaivotas, mapa, águia. Outro texto no exemplo (incluindo títulos, cabeçalhos e corpo de texto) foi extraído como texto e excluído do processamento de imagem.

Screenshot of three images in a PDF

A saída da análise de imagem é ilustrada no JSON abaixo (resultado da pesquisa). A definição de habilidade permite especificar quais recursos visuais são de interesse. Para este exemplo, tags e descrições foram produzidas, mas há mais saídas para escolher.

  • A saída "imageCaption" é uma matriz de descrições, uma por imagem, denotadas por "tags" que consistem em palavras únicas e frases mais longas que descrevem a imagem. Observe as etiquetas que consistem em "um bando de gaivotas está nadando na água", ou "um close up de um pássaro".

  • A saída "imageTags" é uma matriz de tags únicas, listadas na ordem de criação. Observe que as tags se repetem. Não há agregação ou agrupamento.

 "imageCaption": [
      "{\"tags\":[\"bird\",\"outdoor\",\"water\",\"flock\",\"many\",\"lot\",\"bunch\",\"group\",\"several\",\"gathered\",\"pond\",\"lake\",\"different\",\"family\",\"flying\",\"standing\",\"little\",\"air\",\"beach\",\"swimming\",\"large\",\"dog\",\"landing\",\"jumping\",\"playing\"],\"captions\":[{\"text\":\"a flock of seagulls are swimming in the water\",\"confidence\":0.70419257326275686}]}",
      "{\"tags\":[\"map\"],\"captions\":[{\"text\":\"map\",\"confidence\":0.99942880868911743}]}",
      "{\"tags\":[\"animal\",\"bird\",\"raptor\",\"eagle\",\"sitting\",\"table\"],\"captions\":[{\"text\":\"a close up of a bird\",\"confidence\":0.89643581933539462}]}",
    . . .

 "imageTags": [
    "bird",
    "outdoor",
    "water",
    "flock",
    "animal",
    "bunch",
    "group",
    "several",
    "drink",
    "gathered",
    "pond",
    "different",
    "family",
    "same",
    "map",
    "text",
    "animal",
    "bird",
    "bird of prey",
    "eagle"
    . . .

Cenário: imagens incorporadas em PDFs

Quando as imagens que você deseja processar são incorporadas em outros arquivos, como PDF ou DOCX, o pipeline de enriquecimento extrai apenas as imagens e, em seguida, passa-as para OCR ou análise de imagem para processamento. A extração de imagem ocorre durante a fase de quebra de documentos e, uma vez separadas, as imagens permanecem separadas, a menos que você mescle explicitamente a saída processada de volta ao texto de origem.

A mesclagem de texto é usada para colocar a saída de processamento de imagem de volta no documento. Embora a mesclagem de texto não seja um requisito rígido, ela é frequentemente invocada para que a saída de imagem (texto OCR, layoutText OCR, tags de imagem, legendas de imagem) possa ser reintroduzida no documento. Dependendo da habilidade, a saída de imagem substitui uma imagem binária incorporada por um equivalente de texto in-loco. A saída da Análise de Imagem pode ser mesclada no local da imagem. A saída OCR sempre aparece no final de cada página.

O fluxo de trabalho a seguir descreve o processo de extração, análise, fusão de imagens e como estender o pipeline para enviar a saída processada por imagem para outras habilidades baseadas em texto, como Reconhecimento de Entidade ou Tradução de Texto.

  1. Depois de se conectar à fonte de dados, o indexador carrega e quebra documentos de origem, extraindo imagens e texto e enfileirando cada tipo de conteúdo para processamento. Um documento enriquecido que consiste apenas em um nó raiz ("document") é criado.

  2. As imagens na fila são normalizadas e passadas para documentos enriquecidos como um "document/normalized_images" nó.

  3. O enriquecimento de imagem é executado, usando "/document/normalized_images" como entrada.

  4. As saídas de imagem são passadas para a árvore de documentos enriquecida, com cada saída como um nó separado. As saídas variam de acordo com a habilidade (texto e layoutText para OCR, tags e legendas para Análise de Imagem).

  5. Opcional, mas recomendado se você quiser que os documentos de pesquisa incluam texto e texto de origem da imagem juntos, a mesclagem de texto é executada, combinando a representação de texto dessas imagens com o texto bruto extraído do arquivo. Os blocos de texto são consolidados em uma única cadeia grande, onde o texto é inserido primeiro na cadeia de caracteres e, em seguida, na saída de texto OCR ou tags de imagem e legendas.

    A saída do Text Merge é agora o texto definitivo a ser analisado para quaisquer habilidades downstream que executam processamento de texto. Por exemplo, se seu conjunto de habilidades incluir OCR e Reconhecimento de Entidade, a entrada para o Reconhecimento de Entidade deverá ser "document/merged_text" (o targetName da saída da habilidade de Mesclagem de Texto).

  6. Depois de todas as habilidades terem sido executadas, o documento enriquecido está completo. Na última etapa, os indexadores referem-se a mapeamentos de campo de saída para enviar conteúdo enriquecido para campos individuais no índice de pesquisa.

O conjunto de habilidades de exemplo a seguir cria um "merged_text" campo contendo o texto original do seu documento com texto OCRed incorporado no lugar de imagens incorporadas. Ele também inclui uma habilidade de Reconhecimento de Entidade que usa "merged_text" como entrada.

Sintaxe do corpo da solicitação

{
  "description": "Extract text from images and merge with content text to produce merged_text",
  "skills":
  [
    {
        "description": "Extract text (plain and structured) from image.",
        "@odata.type": "#Microsoft.Skills.Vision.OcrSkill",
        "context": "/document/normalized_images/*",
        "defaultLanguageCode": "en",
        "detectOrientation": true,
        "inputs": [
          {
            "name": "image",
            "source": "/document/normalized_images/*"
          }
        ],
        "outputs": [
          {
            "name": "text"
          }
        ]
    },
    {
      "@odata.type": "#Microsoft.Skills.Text.MergeSkill",
      "description": "Create merged_text, which includes all the textual representation of each image inserted at the right location in the content field.",
      "context": "/document",
      "insertPreTag": " ",
      "insertPostTag": " ",
      "inputs": [
        {
          "name":"text", "source": "/document/content"
        },
        {
          "name": "itemsToInsert", "source": "/document/normalized_images/*/text"
        },
        {
          "name":"offsets", "source": "/document/normalized_images/*/contentOffset" 
        }
      ],
      "outputs": [
        {
          "name": "mergedText", "targetName" : "merged_text"
        }
      ]
    },
    {
      "@odata.type": "#Microsoft.Skills.Text.V3.EntityRecognitionSkill",
      "context": "/document",
      "categories": [ "Person"],
      "defaultLanguageCode": "en", 
      "minimumPrecision": 0.5, 
      "inputs": [
        {
            "name": "text", "source": "/document/merged_text"
        }
      ],
      "outputs": [
        {
            "name": "persons", "targetName": "people"
        }
      ]
    }
  ]
}

Agora que você tem um campo merged_text, pode mapeá-lo como um campo pesquisável em sua definição de indexador. Todo o conteúdo dos seus ficheiros, incluindo o texto das imagens, será pesquisável.

Cenário: Visualizar caixas delimitadoras

Outro cenário comum é visualizar informações de layout de resultados de pesquisa. Por exemplo, talvez você queira destacar onde um pedaço de texto foi encontrado em uma imagem como parte dos resultados da pesquisa.

Como a etapa OCR é executada nas imagens normalizadas, as coordenadas de layout estão no espaço de imagem normalizado, mas se você precisar exibir a imagem original, converta pontos de coordenadas no layout para o sistema de coordenadas da imagem original.

O algoritmo a seguir ilustra o padrão:

/// <summary>
///  Converts a point in the normalized coordinate space to the original coordinate space.
///  This method assumes the rotation angles are multiples of 90 degrees.
/// </summary>
public static Point GetOriginalCoordinates(Point normalized,
                            int originalWidth,
                            int originalHeight,
                            int width,
                            int height,
                            double rotationFromOriginal)
{
    Point original = new Point();
    double angle = rotationFromOriginal % 360;

    if (angle == 0 )
    {
        original.X = normalized.X;
        original.Y = normalized.Y;
    } else if (angle == 90)
    {
        original.X = normalized.Y;
        original.Y = (width - normalized.X);
    } else if (angle == 180)
    {
        original.X = (width -  normalized.X);
        original.Y = (height - normalized.Y);
    } else if (angle == 270)
    {
        original.X = height - normalized.Y;
        original.Y = normalized.X;
    }

    double scalingFactor = (angle % 180 == 0) ? originalHeight / height : originalHeight / width;
    original.X = (int) (original.X * scalingFactor);
    original.Y = (int)(original.Y * scalingFactor);

    return original;
}

Cenário: habilidades de imagem personalizada

As imagens também podem ser passadas e devolvidas a partir de habilidades personalizadas. Um conjunto de habilidades base64 codifica a imagem que está sendo passada para a habilidade personalizada. Para usar a imagem dentro da habilidade personalizada, defina "/document/normalized_images/*/data" como a entrada para a habilidade personalizada. Dentro do seu código de habilidade personalizado, base64-decodifice a string antes de convertê-la em uma imagem. Para retornar uma imagem ao conjunto de habilidades, base64-codifice a imagem antes de devolvê-la ao conjunto de habilidades.

A imagem é retornada como um objeto com as seguintes propriedades.

 { 
  "$type": "file", 
  "data": "base64String" 
 }

O repositório de exemplos Python da Pesquisa do Azure tem um exemplo completo implementado em Python de uma habilidade personalizada que enriquece imagens.

Passando imagens para habilidades personalizadas

Para cenários em que você precisa de uma habilidade personalizada para trabalhar em imagens, você pode passar imagens para a habilidade personalizada e fazer com que ela retorne texto ou imagens. O conjunto de habilidades a seguir é de uma amostra.

O conjunto de habilidades a seguir pega a imagem normalizada (obtida durante a quebra do documento) e produz fatias da imagem.

Exemplo de conjunto de competências

{
  "description": "Extract text from images and merge with content text to produce merged_text",
  "skills":
  [
    {
          "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
          "name": "ImageSkill",
          "description": "Segment Images",
          "context": "/document/normalized_images/*",
          "uri": "https://your.custom.skill.url",
          "httpMethod": "POST",
          "timeout": "PT30S",
          "batchSize": 100,
          "degreeOfParallelism": 1,
          "inputs": [
            {
              "name": "image",
              "source": "/document/normalized_images/*"
            }
          ],
          "outputs": [
            {
              "name": "slices",
              "targetName": "slices"
            }
          ],
          "httpHeaders": {}
        }
  ]
}

Exemplo de habilidade personalizada

A habilidade personalizada em si é externa ao conjunto de habilidades. Nesse caso, é o código Python que primeiro percorre o lote de registros de solicitação no formato de habilidade personalizado e, em seguida, converte a cadeia de caracteres codificada em base64 em uma imagem.

# deserialize the request, for each item in the batch
for value in values:
  data = value['data']
  base64String = data["image"]["data"]
  base64Bytes = base64String.encode('utf-8')
  inputBytes = base64.b64decode(base64Bytes)
  # Use numpy to convert the string to an image
  jpg_as_np = np.frombuffer(inputBytes, dtype=np.uint8)
  # you now have an image to work with

Da mesma forma, para retornar uma imagem, retorne uma cadeia de caracteres codificada em base64 dentro de um objeto JSON com uma $type propriedade de file.

def base64EncodeImage(image):
    is_success, im_buf_arr = cv2.imencode(".jpg", image)
    byte_im = im_buf_arr.tobytes()
    base64Bytes = base64.b64encode(byte_im)
    base64String = base64Bytes.decode('utf-8')
    return base64String

 base64String = base64EncodeImage(jpg_as_np)
 result = { 
  "$type": "file", 
  "data": base64String 
}

Consulte também