Extrair texto e informações de imagens em enriquecimento de IA

Por meio do enriquecimento de IA, a IA do Azure Search oferece várias opções para criar e extrair texto pesquisável de imagens, incluindo:

Por meio do OCR, você pode extrair texto de fotos ou imagens que contêm texto alfanumérico, como a palavra "PARE" em um sinal de parada. Por meio de 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 "amarela". Você também pode extrair metadados sobre a imagem, como seu tamanho.

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

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

  • Arquivos de origem que incluem imagens
  • Um indexador de pesquisa, configurado para ações de imagem
  • Um conjunto de habilidades com habilidades personalizadas ou internas que invocam o OCR ou a 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 a associação.

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

Configurar arquivos de origem

O processamento de imagem é orientado por indexador, o que significa que as entradas brutas devem estar em uma fonte de dados compatível.

  • A análise de imagem dá suporte a JPEG, PNG, GIF e BMP
  • O OCR dá suporte a JPEG, PNG, BMP e TIF

As imagens são arquivos binários autônomos ou incorporadas em documentos (PDF, RTF e arquivos de aplicativo 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 serão extraídas e, em seguida, um aviso será gerado.

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

Configurar indexadores para processamento de imagem

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 downstream. A normalização de imagem inclui as seguintes operações:

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

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. As habilidades que iteram em 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).

    Esse 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 partes menores de texto, você pode adicionar uma habilidade de Divisão de Texto que subdivide um documento em paginação para fins de processamento. Mas, para cenários de pesquisa, um blob por documento será necessário 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 documento.

    • generateNormalizedImagePerPage (aplica-se somente a PDF) para gerar uma matriz de imagens normalizadas em que cada página no PDF é renderizada em uma imagem de saída. Para arquivos que não são PDF, o comportamento desse parâmetro é o mesmo que 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), já que várias imagens teriam que ser geradas.

  5. Opcionalmente, ajuste a largura ou a 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 se baseia nos tamanhos máximos compatíveis com a habilidade de OCR e a habilidade de análise de imagem. Habilidades de OCR são compatíveis com a largura e altura máximas de 4.200 para idiomas não inglês e 10.000 para o inglês. Caso aumente os limites máximos, poderá haver uma falha no processamento de imagens maiores, de acordo com a 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 destino um tipo de arquivo específico. A configuração do indexador de blobs inclui configurações de inclusão e exclusão de arquivos. Você pode filtrar arquivos que não deseja.

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

Obter 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 de imagem Descrição
data Cadeia codificada em Base64 da imagem normalizada no 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.
originalHeight A altura original da imagem antes da normalização.
rotationFromOriginal Rotação no sentido anti-horário em graus 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 caractere dentro do campo de conteúdo do qual a imagem foi extraída. Este campo só é aplicável a arquivos 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. Isso significa que as imagens aparecem depois de todo o texto nessa página, independentemente da localização original da imagem na página.
pageNumber Caso a imagem tenha sido extraída de um arquivo PDF ou renderizada nele, este campo vai conter o número da página da qual a imagem foi extraída ou na qual a imagem foi renderizada, começando pela página 1. Se a imagem não for de um PDF, esse campo será 0.

Exemplo de valor 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 conjuntos de habilidades para processamento de imagem

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

  1. Criar ou atualizar um conjunto de habilidades para adicionar habilidades.

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

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

  4. Se as imagens originais forem inseridas em arquivos PDF ou de aplicativo, como PPTX ou DOCX, você precisará adicionar uma habilidade de Mesclagem de Texto, se quiser a saída de imagem e a saída de texto juntas. Trabalhar com imagens inseridas é um assunto discutido mais adiante neste artigo.

Depois que a estrutura básica do conjunto de habilidades for criada e os serviços de IA do Azure estiverem configurados, será possível se concentrar em cada habilidade de imagem individual, definindo entradas e contexto de origem e mapeando saídas para campos em um índice ou repositório de conhecimento.

Observação

Confira Tutorial do REST: usar REST e IA para gerar conteúdo pesquisável de blobs do Azure para ver um exemplo de um modelo de conjunto de habilidades que combina processamento de imagem com processamento de idioma natural downstream. Ele mostra como alimentar a saída de imagens de habilidades em reconhecimento de entidade e extração de frases-chave.

Sobre entradas para processamento de imagem

Conforme observado, as imagens são extraídas durante a quebra de documento 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 entre duas maneiras:

  • /document/normalized_images/* é para documentos processados inteiros.

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

Se você estiver usando o OCR e a análise de imagem da mesma maneira, as entradas terão 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, a saída da habilidade de Análise de Imagem e 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 as saídas de habilidades.

    No exemplo de coleção de campos a seguir, "content" é conteúdo de blob. "Metadata_storage_name" contém o nome do arquivo (certifique-se de que seja "retrievable"). "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 de OCR e devem ser uma coleção de cadeias de caracteres para capturar toda saída gerada pelo 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 os 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 recuperação de documento de origem, processamento de imagem e indexação.

Verificar os resultados

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

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

O 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") estarão 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 devem ser esperados quando os nós não estão populados no documento enriquecido. Lembre-se de que a indexação de blobs permite incluir ou excluir tipos de arquivo se você 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 "content" e "merged_content". Observe que esses campos incluem conteúdo para qualquer arquivo de blob, mesmo aqueles em que não houve processamento de imagem realizado.

Sobre saídas de habilidades

As saídas de habilidades incluem "text" (OCR), "layoutText" (OCR), "merged_content", "captions" (análise de imagem), "tags" (análise de imagem):

  • "text" armazena a saída gerada pelo OCR. Esse 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 do OCR para três documentos. O primeiro é um documento que contém um arquivo sem imagens. O segundo é um documento (arquivo de imagem) que contém uma palavra, "Microsoft". O terceiro é um documento que contém várias imagens, algumas sem nenhum 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 pelo OCR sobre o local do texto na página, descritas em termos de caixas delimitadoras e coordenadas da imagem normalizada. Esse 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 campo grande do tipo Edm.String que contém texto bruto do documento de origem, com "texto" incorporado no lugar de uma imagem. Se os arquivos forem somente texto, o OCR e a análise de imagem não terão nada a ver, e "merged_content" será o mesmo que "content" (uma propriedade de blob que contém o conteúdo do blob).

  • "imageCaption" captura uma descrição de uma imagem como marcas de indivíduos e uma descrição de texto mais longa.

  • "imageTags" armazena marcas relativas a 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 quebra de documentos detectou três imagens incorporadas: bando de gaivotas, mapa, águia. Outros textos no exemplo (incluindo títulos, cabeçalhos e corpo de texto) foram extraídos como texto e excluídos do processamento de imagens.

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 interessantes. Para este exemplo, foram produzidas marcas e descrições, mas há mais saídas para escolher.

  • A saída "imageCaption" é uma matriz de descrições, uma por imagem, indicada por "marcas" que consistem em palavras simples e frases mais longas que descrevem a imagem. Observe as marcas contendo “um bando de gaivotas nadando na água” ou “uma imagem aproximada de um pássaro”.

  • A saída "imageTags" é uma matriz de marcas ú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, as passa para OCR ou análise de imagem para processamento. A extração de imagem ocorre durante a fase de quebra do documento e, uma vez que as imagens são separadas, elas 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 do processamento de imagem de volta no documento. Embora a Mesclagem de Texto não seja um requisito difícil, ela é frequentemente invocada para que a saída de imagem (texto OCR, layoutText OCR, marcas de imagem, legendas de imagem) possa ser reintroduzida no documento. Dependendo da habilidade, a saída de imagem substitui uma imagem binária inserida 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 de OCR sempre é exibida no final de cada página.

O fluxo de trabalho a seguir descreve o processo de extração, análise e mesclagem de imagem e como estender o pipeline para enviar a saída processada por imagem por push 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 em documentos enriquecidos como um nó "document/normalized_images".

  3. Os enriquecimentos de imagem são executados 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 (text e layoutText para o OCR, marcas 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. As partes de texto são consolidadas em uma única cadeia de caracteres grande, em que o texto é inserido primeiro na cadeia de caracteres e, em seguida, as saídas de texto OCR ou marcas e legendas de imagem.

    Agora a saída da mesclagem de texto é o texto definitivo a ser analisado quanto a quaisquer habilidades downstream que executam o processamento de texto. Por exemplo, se o seu conjunto de habilidades incluir o OCR e o 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 que todas as habilidades foram executadas, o documento enriquecido é concluído. Na última etapa, os indexadores se referem a mapeamentos de campo de saída para enviar conteúdo enriquecido para campos individuais no índice de pesquisa.

O exemplo de conjunto de habilidades a seguir cria um campo "merged_text" que contém o texto original do 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 de 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 na definição do indexador. Todo o conteúdo dos arquivos, incluindo o texto das imagens, serão pesquisáveis.

Cenário: Visualizar caixas delimitadoras

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

Como a etapa OCR é executada nas imagens normalizadas, as coordenadas do layout estão no espaço da imagem normalizada, mas se você precisar exibir a imagem original, converta os 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 personalizadas de imagem

As imagens também podem ser transmitidas e retornadas das habilidades personalizadas. Um conjunto de habilidades codifica em Base64 a imagem que está sendo transmitida para a habilidade personalizada. Para usar a imagem dentro da habilidade personalizada, defina "/document/normalized_images/*/data" como a entrada para a habilidade personalizada. No código da habilidade personalizado, decodifique a cadeia de caracteres em Base64 antes de convertê-la em uma imagem. Para retornar uma imagem para o conjunto de habilidades, codifique a imagem em Base64 antes de retorná-la para o conjunto de habilidades.

A imagem é retornada como um objeto com as propriedades a seguir.

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

O repositório de exemplos do Python do Azure Search traz um exemplo completo implementado no Python de uma habilidade personalizada que enriquece imagens.

Como enviar imagens às habilidades personalizadas

Nos cenários em que você precisa usar uma habilidade personalizada para trabalhar com imagens, será possível enviar imagens a uma habilidade personalizada de modo que ela retorne textos ou imagens. O conjunto de habilidades a seguir foi extraído do exemplo.

O conjunto de habilidades abaixo usa a imagem normalizada (obtida durante a quebra de documento) e gera fatias dela.

Conjunto de habilidades de exemplo

{
  "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

Uma habilidade personalizada será criada fora do conjunto de habilidades. Nesse caso, é o código Python que primeiro faz um loop pelo 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

Do mesmo modo, para retornar uma imagem, retorne uma cadeia de caracteres de codificação de Base 64 dentro de um objeto JSON com uma propriedade $type 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 
}

Confira também