Exercício – Escrever um aplicativo de funções no Azure Functions para analisar fotos

Concluído

Nessa unidade, você usará o Azure Functions para escrever um aplicativo disparado toda vez que uma imagem é carregada no contêiner photos da conta de armazenamento. O aplicativo de funções usará o modelo da Visão Personalizada que você criou na unidade anterior para determinar se a foto contém um urso polar.

Criar um aplicativo de funções no Azure

Você pode escrever um aplicativo de funções no Azure Functions no portal do Azure ou externamente, usando ferramentas como o Visual Studio. Neste exercício, você escreverá um aplicativo de funções no portal. Você usará JavaScript para escrever o aplicativo de funções e o executará usando o runtime Node.js do Azure Functions. O aplicativo de funções é disparado cada vez que uma imagem é carregada no contêiner de photos que você criou no Armazenamento de Blobs. Em seguida, o aplicativo de funções passa cada blob que é carregado para a Visão Personalizada para que ele seja analisado quanto à presença de ursos polares.

  1. No navegador, volte ao portal do Azure. Nos Serviços do Azure, selecione Criar um recurso. No menu de recursos, selecione Computação e, em seguida, Aplicativo de Funções.

    Screenshot that shows numbered elements in the Azure portal that you select to create a new function app resource.

    Criar um aplicativo de funções no Azure

  2. Em Create Aplicativo de Funções, na guia Básico, insira ou selecione os seguintes valores:

    • Assinatura: selecionar a assinatura que você deve usar.
    • Grupo de recursos: selecione polar-bear-rg.
    • Nome do aplicativo de funções: insira um nome que seja exclusivo no Azure para seu novo aplicativo.
    • Publicar:. Deixe Código selecionado.
    • Pilha de runtime: selecione Node.js.
    • Região: selecione Centro-Sul dos EUA.
    • Sistema operacional: selecionar seu sistema.
    • Tipo de Plano: escolha Consumo (Sem Servidor).
    • Selecione Avançar: Hospedagem.

    Screenshot that shows the basic settings to select or enter for a new function app.

    Definir as configurações básicas para um novo aplicativo de funções

  3. Na guia Hospedagem, selecione a conta de armazenamento que você criou e para a qual as fotos de vida selvagem serão carregadas. Em seguida, selecione Examinar + criar.

    Screenshot that shows the hosting tab settings for a new function app.

    Definir as configurações de hospedagem para um novo aplicativo de funções

  4. Aguarde a conclusão da validação e, em seguida, selecione Criar.

  5. Aguarde até que o aplicativo de funções seja implantado e, em seguida, abra o aplicativo no portal do Azure. No menu de recursos, em Funções, selecione Funções e Criar.

    Screenshot that highlights the elements to select to add a function in the Azure portal.

    Adicionar uma função

  6. Em Adicionar função:

    1. Para Ambiente de desenvolvimento, selecione Desenvolver no portal.
    2. Em Modelo, selecione Gatilho do Armazenamento de Blobs do Azure.

    Screenshot that highlights the elements to select for a new function.

    Definir as configurações e escolher um modelo para uma função

    Observação

    Se você for solicitado a instalar a extensão Microsoft.Azure.WebJobs.Extensions.Storage, selecione Instalar.

    Aguarde a conclusão da instalação e, em seguida, selecione Continuar.

    (Se a extensão não precisar ser instalada, talvez seja necessário aguardar alguns minutos antes de prosseguir para a próxima etapa.)

  7. Em Detalhes do modelo:

    1. Em Nova Função, insira BlobTrigger.

    2. Em Caminho, insira photos/{nome} para que o aplicativo de funções seja disparado quando blobs forem carregados no contêiner photos.

    3. No campo Conexão da conta de armazenamento, selecione Novo.

      Observação

      Copie o valor mostrado em Conexão da conta de armazenamento e, em seguida, salve o. Você usará o valor em uma etapa posterior.

    4. Clique em Nova conexão da Conta de Armazenamento, escolha a conta de armazenamento criada anteriormente e selecione OK.

    Screenshot that shows settings to use to set up the template to create a blob-triggered function.

    Configurar o modelo para criar uma função disparada por blob

  8. Selecione Adicionar. A exibição do portal é alterada para mostrar o novo aplicativo.

  9. Na página de visão geral da nova função de gatilho, em Desenvolvedor, selecione Codificar + Testar. O arquivo index.js do gatilho é aberto no portal.

    Screenshot that highlights the portal elements to select to open the index dot J S file for the blob-triggered function.

    Abrir o arquivo index.js para a função de gatilho

  10. Copie o código a seguir e substitua o código do aplicativo de funções no portal do Azure por este código:

    module.exports = function (context, myBlob) {
        var predictionUrl = process.env.PREDICTION_URL;
        var predictionKey = process.env.PREDICTION_KEY;
        var storageConnectionString = process.env.<CONNECTION_STRING_NAME>;
    
        var storage = require('azure-storage');
        var blobService = storage.createBlobService(storageConnectionString);
        var blobName = context.bindingData.name;
        var blobUri = context.bindingData.uri;
    
        // Read the blob's metadata
        blobService.getBlobMetadata('photos', blobName, (err, result, response) => {
            if (!err) {
                var latitude = result.metadata.latitude;
                var longitude = result.metadata.longitude;
                var id = result.metadata.id;
    
                // Generate a shared access signature for the Custom Vision service
                var now = new Date();
                var expiry = new Date(now).setMinutes(now.getMinutes() + 3);
    
                var policy = {
                    AccessPolicy: {
                        Permissions: storage.BlobUtilities.SharedAccessPermissions.READ,
                        Start: now,
                        Expiry: expiry
                    },
                };
    
                var sas = blobService.generateSharedAccessSignature('photos', blobName, policy);
    
                // Pass the blob URL to the Custom Vision service
                var request = require('request');
    
                var options = {
                    url: predictionUrl,
                    method: 'POST',
                    headers: {
                        'Prediction-Key': predictionKey
                    },
                    body: {
                        'Url': blobUri + '?' + sas
                    },
                    json: true
                };
    
                request(options, (err, result, body) => {
                    if (!err) {
                        var probability =  body.predictions.find(p => p.tagName.toLowerCase() === 'polar-bear').probability;
                        var isPolarBear = probability > 0.8; // 80% threshold
                         if (isPolarBear) {
                            context.log('POLAR BEAR detected by ' + id + ' at ' + latitude + ', ' + longitude);
                        }
                        else {
                            context.log('Other wildlife detected by ' + id + ' at ' + latitude + ', ' + longitude);
                        }
    
                        context.done();
                    }
                    else {
                        context.log(err);
                        context.done();
                    }
                });
            }
            else {
                context.log(err);
                context.done();
            }
        });
    };
    

    O aplicativo de funções modificado usa o módulo request do npm para chamar o serviço de Visão Personalizada, transmitindo a URL da imagem a ser analisada. Ele analisa os resultados JSON e recupera o valor que indica a probabilidade de que a imagem contenha um urso polar. Em seguida, ele grava os resultados no log de saída. O limite para determinar se uma imagem contém um urso polar é 80%:

    var isPolarBear = probability > 0.8; // 80% threshold
    

    Outro aspecto importante desse código é o uso de uma assinatura de acesso compartilhado.

    O contêiner photos criado é privado. Para acessar os blobs armazenados nele, você precisará ter acesso à conta de armazenamento ou ter a chave de acesso da conta de armazenamento. As assinaturas de acesso compartilhado permitem que outros usuários e serviços acessem blobs individuais, mas apenas por um período especificado e, opcionalmente, com acesso somente leitura.

    O código que você colou no portal usa o SDK do Armazenamento do Azure para Node.js (azure-storage) para gerar uma assinatura de acesso compartilhado somente leitura para o blob associado à URL passada para a Visão Personalizada. O código acrescenta a assinatura de acesso compartilhado à URL do blob como uma cadeia de caracteres de consulta. A assinatura de acesso compartilhado é válida por três minutos e permite somente acesso de leitura. O código pode enviar blobs privados à Visão Personalizada para análise sem colocar os blobs em um contêiner público, no qual qualquer pessoa poderia baixá-los.

  11. Substitua <CONNECTION_STRING_NAME> na linha 4 pela cadeia de conexão da conta de armazenamento que você salvou anteriormente (por exemplo, polarbearstorage_STORAGE). Essa cadeia de conexão foi adicionada às configurações de aplicativo quando você adicionou a função BlobTrigger ao aplicativo de funções. O nome dela deriva do nome da conta de armazenamento. Se necessário, você pode pesquisar a cadeia de conexão da conta de armazenamento nas Configurações de aplicativo do aplicativo de funções.

    Depois de adicionar a cadeia de conexão da conta de armazenamento, selecione Salvar para terminar de fazer alterações ao arquivo index.js. Quando o arquivo tiver sido salvo, o log de saída da função será aberto na parte inferior da página.

  12. No portal do Azure, abra um console.

    • Na página de visão geral do aplicativo de funções, no menu de recursos, em Ferramentas de Desenvolvimento, selecione Console.

    Screenshot that shows how to open a console for a function app.

    Abrir um console do aplicativo de funções

  13. No console, execute os comandos a seguir para instalar o pacote request do npm e o SDK do Armazenamento do Azure para Node.js, de modo que o aplicativo de funções possa usá-los.

    npm install request
    npm install azure-storage
    

    Observação

    Ignore as mensagens de aviso que aparecerem. Para simplificar, estamos usando uma versão mais antiga de uma biblioteca JavaScript.

  14. Aguarde até que os comandos de instalação sejam concluídos. Em seguida, você adicionará duas configurações de aplicativo ao aplicativo de funções.

    1. No menu de recursos, em Configurações, selecione Configuração.
    2. Em Configurações de aplicativo, selecione Nova configuração de aplicativo.
    3. Em Adicionar/Editar configuração de aplicativo, adicione uma configuração chamada PREDICTION_URL. Defina o valor para a URL de previsão da Visão Personalizada que você salvou na unidade anterior. Deixe a Configuração do slot de implantação vazia. Selecione OK.
    4. Repita a etapa anterior para adicionar uma configuração chamada PREDICTION_KEY. Defina o valor para a chave de previsão da Visão Personalizada que você salvou na unidade anterior. Deixe a Configuração do slot de implantação vazia. Selecione OK.

    Screenshot that shows selections to make in the Azure portal for application settings for a function app.

    Definir as configurações de aplicativo do aplicativo de funções

    Para concluir, selecione Salvar. Se for solicitado, selecione Continuar para concluir a ação de salvar.

    Observação

    Em vez de embutir a chave de autenticação e a URL da Visão Personalizada no código da função, você está armazenando os valores nas configurações de aplicativo do aplicativo de funções. Os valores ficam mais seguros quando são salvos nas configurações de aplicativo.

  15. Para retornar ao aplicativo de funções BlobTrigger, no menu de recursos, em Funções, selecione Funções e, em seguida, selecione BlobTrigger:

    Screenshot that shows selections to make in the Azure portal to view the blob trigger function app.

    Abra o aplicativo de funções BlobTrigger

  16. No menu de recursos, em Desenvolvedor, selecione Codificar + Testar. Abaixo do código mostrado, selecione a seta para cima de Logs. O painel saída de log é aberto.

    Screenshot that shows how to open the output log for a function.

    Abrir o log de saída da função

    Mantenha o painel Logs aberto porque nós o usaremos em uma etapa posterior.

  17. Para abrir o contêiner do Armazenamento de Blobs photos, no menu de recursos, em Armazenamento de dados, selecione Contêineres. Na lista de contêineres, selecione o contêiner photos.

    Screenshot that highlights the items you select in the Azure portal to open the photos container.

    Abra o contêiner photos para a conta de Armazenamento de Blobs

  18. Em seguida, carregue uma imagem no contêiner photos para testar o aplicativo de funções.

    1. No painel photos do contêiner, selecione Carregar.
    2. Em Carregar blob, em Arquivos, selecione o ícone de pasta.
    3. No Windows Explorer, vá para a pasta photos no diretório do projeto.
    4. Selecione o arquivo image_12.jpg e selecione Abrir.
    5. Em Carregar blob, selecione Carregar. Quando o upload for concluído, selecione X para fechar o painel.

    Screenshot that shows how to upload a photo to a container.

    Carregar uma foto no contêiner

    Esta é a aparência de image_12.jpg:

    Image 12 dot j p g, which shows a polar bear.

    Imagem 12 no Armazenamento de Blobs

  19. No navegador, volte para o log do aplicativo de funções. Confirme se o aplicativo de funções foi executado e se Visão Personalizada indica que image_12.jpg contém um urso polar.

    Screenshot that shows the output log details for uploading and analyzing image 12 dot j p g.

    Exibir os detalhes do log de saída para carregar e analisar a imagem 12

O motivo do texto indefinido em indefinido, indefinido na saída do log é que a função tentou ler a latitude, a longitude e a ID da câmera nos metadados do blob e incluí-las na saída. Esses valores de metadados não existem porque você carregou o blob manualmente. Essa condição será alterada quando as câmeras virtuais carregarem as fotos no Armazenamento de Blobs.

Executar a matriz de câmeras

Em seguida, execute a matriz simulada de câmeras criada anteriormente. Em seguida, você verificará a saída do log no aplicativo de funções para verificar se as imagens estão sendo carregadas no Armazenamento de Blobs e analisadas quanto à presença de ursos polares.

  1. Em um prompt de comando ou uma janela do terminal, volte ao diretório do projeto. Execute o seguinte código para executar run.js:

    node run.js
    
  2. Volte à função BlobTrigger no portal do Azure e inspecione o log de saída por um ou dois minutos. Confirme se a função está sendo disparada e se está chamando a Visão Personalizada para determinar se cada foto carregada no contêiner photos contém um urso polar.

    Screenshot that shows logs in a terminal, with the log entry Polar Bear detected for one of the cameras and the camera's latitude and longitude.

    Há ursos polares!

  3. Volte ao prompt de comando ou à janela do terminal em que run.js está em execução e selecione Ctrl+C.

Parabéns! Você deve usar um sistema que transmite fotos da vida selvagem para o Armazenamento de Blobs do Azure e usar um modelo de Visão Personalizada de IA do Azure para determinar quais fotos contêm ursos polares. A próxima etapa será tornar a saída mais visual e isso começa com a criação de um banco de dados SQL usando o Banco de Dados SQL do Azure.