Ao personalizar a Visão Computacional no Azure, além de organizarmos nossos projetos como vimos no artigo anterior, precisamos criar as tags da Visão Personalizada da Azure.
Essas tags nos auxiliaram a definir o quê são as imagens que enviaremos aos projetos. Depois, na predição, daremos uma imagem e o Serviço Cognitivo da Azure de Visão Personalizada nos dirá o que a imagem é, de acordo com as tag cadastradas, alimentadas e treinadas.
Este artigo é uma continuação imediata do anterior, NÃO reinvente a roda! Como criar projetos para a Visão Personalizada da Azure, que dividimos em três partes, sendo esta a parte dois, além de fazer parte da série NÃO reinvente a roda!
Visão Personalizada no Azure
Assim como o Serviço de Visão Computacional, o Serviço de Visão Personalizada da Azure também é usado para analisar e detectar informações relevantes em imagens, com a diferença de ser completamente customizável para o seu domínio e ainda sem precisar de expertise em machine learning.
Este artigo será dividido em três partes devido a quantidade de operações que podem ser feitas na Visão Personalizada, sendo esta a segunda parte, que tratará das tags para os Projetos de tal Serviço Cognitivo criados no artigo anterior. O projeto, em si, foi iniciado no primeiro artigo técnico da série NÃO reinvente a roda! Serviços cognitivos da Azure: Face e demos continuidade em todos os da série NÃO reinvente a roda!. Portanto, confere lá os outros artigos e fique por dentro de tudo que estamos fazendo.
Este artigo terá todos os controles referentes as Tags da Visão Personalizada da Azure. Como criá-las, editá-las, excluí-las e listá-las.
Todo o código está disponível no github.
Então, vamos a mão na massa!
1. Tenha seu projeto
Criamos um projeto do tipo ASP.NET Core Web Application, com o template Web Application para ter o projeto criado voltado para o Razor Pages. Demos a ele o nome de AzureCognitiveServices. Confira no primeiro passo do primeiro artigo técnico da série e crie o seu projeto também.
O projeto CustomVision, do tipo Class Library (.NET Core) dentro da Solution Folder nomeada de Vision foi criado no artigo anterior.
É importante que seu projeto esteja assim:
2. Configure a Azure e obtenha as informações do portal de Visão Personalizada
Para prosseguir, você vai precisar da chave e do endpoint do recurso de treinamento da Visão Computacional Personalizada do Azure, bem como as informações de dentro do portal de Visão Computacional.
Como obter tais informações estão detalhadas no artigo sobre como criar projetos para a Visão Personalizada da Azure e é imprescindível a leitura do mesmo, bem como a aquisição dessas informações
3. Implemente as Tags da Visão Personalizada da Azure na classe Treinamento.cs
Essa classe já possui seus usings, variáveis e métodos. Ao final da classe, após o último método (
public
Project
CarregarProjeto
(
string
idDoProjeto)
), adicione o código a seguir:
public IEnumerable<Tag> ListarTags(Project projeto) => _servicoCognitivoDeVisaoPersonalizadaTreinamento.GetTags(projeto.Id); public void CriarTag(Project projeto, string nome, string descricao = \"\") => _servicoCognitivoDeVisaoPersonalizadaTreinamento.CreateTag(projeto.Id, nome, descricao); public void EditarTag(Project projeto, string idDaTag, Tag tag) => _servicoCognitivoDeVisaoPersonalizadaTreinamento.UpdateTag(projeto.Id, new Guid(idDaTag), tag); public void ExcluirTag(Project projeto, string idDaTag) => _servicoCognitivoDeVisaoPersonalizadaTreinamento.DeleteTag(projeto.Id, new Guid(idDaTag)); public Tag CarregarTag(Project projeto, string idDaTag) => ListarTags(projeto).FirstOrDefault(t => t.Id.ToString().Equals(idDaTag)) ?? new Tag();
Essas são as operações referentes a manipulação das tags. Note que são as mesmas operações que fazemos com Projetos, ou seja, as operações básicas de listar, carregar, criar, editar e excluir.
Todos os métodos precisam saber de qual Projeto são as tags solicitadas na operação, mas as operações em si são bem simples. O único método que possui algo diferente é o CarregarTag
()
, este utiliza um null-coalescing (o símbolo de ??) para retornar uma nova instância de Tag()
, caso o retorno original seja nulo.
A classe inteira pode ser visualizada no github.
4. Crie o arquivo SalvarTag.cshtml no projeto AzureCognitiveServices
Dentro do projeto AzureCognitiveServices utilize a pasta CustomVision, dentro da pasta Vision que está dentro de Pages para adicionar uma Razor Page e a chame de SalvarProjeto.cshtml.
Lembrando que essa pasta foi criada no artigo anterior.
Nela, criaremos o formulário responsável por ter as informações do cadastro de uma Tag, que é bem simples, composto de Nome e Descrição.
Vamos usá-la tanto para cadastrar uma nova Tag, quanto para editar uma Tag existente.
Vamos, primeiro, editar o código do servidor. Para isso, clique com o botão direito no arquivo aberto e vá em Go to PageModel ou aperte o F7.
Esse arquivo é responsável pelo código C# desta página. Comece colocando os usings.
using CustomVision; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training.Models;
Adicione agora as variáveis que utilizaremos na classe.
namespace AzureCognitiveServices { public class SalvarTagModel : PageModel { private readonly Treinamento _treinamento; public Project Projeto { get; private set; } public Tag Tag { get; private set; }
Temos três variáveis. A primeira Treinamento
_treinamento
é responsável por chamar os métodos da classe que criamos em 5. Implemente o Treinamento da Visão Personalizada na classe Treinamento.cs. Já a outra, Project Projeto
é o projeto ao qual criaremos a Tag.
Crie o método construtor.
public SalvarTagModel() => _treinamento = new Treinamento();
O método construtor apenas cria uma nova instância de Treinamento
()
para ser usada no restante da classe.
Agora crie o método get que será executado sempre que esta página for aberta e o método que ele chama.
public void OnGet(string idDoProjeto, string idDaTag) { CarregarProjeto(idDoProjeto); Tag = _treinamento.CarregarTag(Projeto, idDaTag); } private void CarregarProjeto(string idDoProjeto) => Projeto = _treinamento.CarregarProjeto(idDoProjeto);
O método get apenas carregará um Projeto específico que será passado por parâmetro, e dois carregará a Tag desse Projeto, caso ela existir. Como este método é executado sempre que a página é aberta, os parâmetros esperados por ele (string
idDoProjeto,
string
idDaTag
) serão passados na URL. O parâmetro referente ao id do Projeto sempre será passado.
Por último, crie o método post para capturar os envios do formulário HTML e não esqueça de fechar as chaves da classe.
public IActionResult OnPost(string idDoProjeto, string idDaTag) { var nome = Request.Form[\"nome\"]; var descrição = Request.Form[\"descrição\"]; CarregarProjeto(idDoProjeto); if (string.IsNullOrWhiteSpace(idDaTag)) _treinamento.CriarTag(Projeto, nome, descricao); else _treinamento.EditarTag(Projeto, idDaTag, new Tag { Name = nome, Description = descrição }); return RedirectToPage(\"/Vision/CustomVision/TagsDoProjeto\", new { idDoProjeto }); } } }
Este método começa um pouco diferente do que vimos até agora, pois o tipo de retorno é IActionResult
e, mesmo sendo um post, tem dois parâmetros (string
idDoProjeto,
string
idDaTag
).
Isto é porque, no final do método, iremos redirecionar o usuário para uma outra página (que criaremos mais a frente, ainda neste artigo) e, por isso, é necessário esse tipo de retorno.
O redirecionamento requer um parâmetro na URL, que é o id do Projeto ao qual estamos criando ou editando uma Tag.
Já os parâmetros, são referentes a informação do Projeto e da Tag, sendo que esta última pode, ou não, estar na URL. No decorrer do método, fazemos uma verificação nele, caso ele não exista, significa que teremos que criar uma nova Tag, caso exista, teremos que editar a Tag do Projeto que foi passado por parâmetro, ambos pegando informações do formulário HTML.
Isso encerra o código da parte do servidor. Vamos voltar a parte do HTML.
A classe HTML terá o código inicial. O altere para isso:
@page @model AzureCognitiveServices.SalvarTagModel @{ ViewData[\"Title\"] = \"Salvar Tag\"; } <h1>Salvar Tag @Model.Tag?.Name</h1>
Coloque o seguinte código HTML no restante do arquivo:
<p>@Model.Projeto?.Name</p> <form method=\"post\"> <div> <div> <div> <label for=\"nome\">* Tag:</label> <input type=\"text\" value=\"@Model.Tag?.Name\" name=\"nome\" id=\"nome\" required aria-describedby=\"ajudaParaTag\" /> <small id=\"ajudaParaTag\"> Tags representam o que você <strong>VAI</strong> adicionar ao projeto. Adicione uma. </small> </div> </div> </div> <div> <div> <div> <label for=\"descrição\">Descrição da tag:</label> <textarea name=\"descrição\" id=\"descrição\" rows=\"4\">@Model.Tag?.Description</textarea> </div> </div> </div> <div> <div> <div> <button type=\"button\" data-dismiss=\"modal\">Limpar campos</button> <button type=\"submit\">Salvar tag</button> </div> </div> </div> </form>
Este código tem apenas o HTML que informará o nome do Projeto que estamos criando ou editando a Tag, e também que gerará um formulário contendo os campos de Nome e Descrição, necessários para a criação de uma Tag, sendo que o campo Nome é obrigatório. E, por fim, botões para limpar os campos ou concluir a operação.
Além disso, como há a possibilidade de ser uma edição, os campos têm seus valores preenchidos pelos valores do Tag, caso ela exista.
Os arquivos inteiros podem ser visualizados no github, tanto o arquivo de HTML, quando a classe do servidor.
5. Crie o arquivo TagsDoProjeto.cshtml no projeto AzureCognitiveServices
Dentro do projeto AzureCognitiveServices use a pasta CustomVision para criar uma Razor Page e a chame de TagsDoProjeto.cshtml.
Ela será responsável por listar todas as Tags existentes de um Projeto em específico, bem como redirecionar para todos os outros recursos referentes as Tags, como adições, edições e exclusões.
Vamos, primeiro, editar o código do servidor. Para isso, clique com o botão direito no arquivo aberto e vá em Go to PageModel ou aperte o F7.
Esse arquivo é responsável pelo código C# desta página. Comece colocando os usings.
using CustomVision; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training.Models; using System.Collections.Generic; using System.Linq;
Adicione agora as variáveis que utilizaremos na classe.
namespace AzureCognitiveServices { public class TagsDoProjetoModel : PageModel { private readonly Treinamento _treinamento; public Project Projeto { get; private set; } public IList<Tag> Tags { get; private set; }
Essa classe também tem uma variável Treinamento
_treinamento
para acessar os métodos dessa classe que criamos, também tem uma Project
Projeto
para sabermos de qual Projeto são as Tags que veremos e, por fim uma IList
<Tag> Tags
que são as Tags referentes ao Projeto.
Crie o método construtor.
public TagsDoProjetoModel() => _treinamento = new Treinamento();
O método construtor apenas cria uma nova instância de Treinamento
()
para ser usada no restante da classe.
Agora crie o método get que será executado sempre que esta página for aberta, além dos métodos que têm suas chamadas encadeadas.
public void OnGet(string idDoProjeto) => CarregarInformacoes(idDoProjeto); private void CarregarInformacoes(string idDoProjeto) { CarregarProjeto(idDoProjeto); ListarTags(Projeto); } private void CarregarProjeto(string idDoProjeto) => Projeto = _treinamento.CarregarProjeto(idDoProjeto); private void ListarTags(Project projeto) => Tags = _treinamento.ListarTags(Projeto).ToList();
O método get apenas recebe o id do Projeto por parâmetro, na URL e chama o método CarregarInformacoes
()
, este, como o nome sugere, carrega as informações referentes ao Projeto e lista todas as Tags do mesmo, em métodos diferentes.
Por último, crie o método post e não esqueça de fechar todas as chaves da classe.
public void OnPost(string idDoProjeto) { CarregarProjeto(idDoProjeto); _treinamento.ExcluirTag(Projeto, Request.Form[\"idDaTag\"]); ListarTags(Projeto); } } }
O método post dessa classe é bem curto, apenas com uma ação, pois todas as outras serão redirecionadas para outras páginas. Primeiro ele carrega informações sobre o Projeto que estamos gerenciando as Tags, depois exclui a Tag selecionada. Por fim, executa o método ListarTags
()
para listá-las novamente. Não se preocupe com a exclusão, a pergunta de confirmação da ação é feita no HTML.
Isso encerra o código da parte do servidor. Vamos voltar a parte do HTML, altere o código inicial para isto:
@page @model AzureCognitiveServices.TagsDoProjetoModel @{ ViewData[\"Title\"] = \"Tags Do Projeto\"; } <h1>Tags Do Projeto @Model.Projeto?.Name</h1>
Coloque o seguinte código HTML no restante do arquivo:
<p>@Model.Projeto?.Description</p> <a asp-page=\"/Vision/CustomVision/SalvarTag\" asp-route-idDoProjeto=\"@Model.Projeto?.Id\">Nova Tag</a> <br /> @if (Model.Tags.Any()) { <fieldset> <legend>Tags já existentes</legend> <div> @foreach (var tag in Model.Tags) { <div> <div> <div> <h5>@tag.Name</h5> <h6>@tag.Description</h6> <p>Esta tag contém @tag.ImageCount fotos</p> <div> <a asp-page=\"/Vision/CustomVision/SalvarTag\" asp-route-idDoProjeto=\"@Model.Projeto?.Id\" asp-route-idDaTag=\"@tag.Id\">Editar</a> <a href=\"#\" data-toggle=\"modal\" data-target=\"#[email protected]\">Excluir</a> </div> </div> </div> </div> <div id=\"[email protected]\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"[email protected]\" aria-hidden=\"true\"> <div role=\"document\"> <div> <div> <h5 id=\"[email protected]\">Tag: @tag.Name (@tag.ImageCount fotos)</h5> <button type=\"button\" data-dismiss=\"modal\" aria-label=\"Close\"> <span aria-hidden=\"true\">×</span> </button> </div> <div> <p>Tem certeza que deseja excluir a tag?</p> </div> <div> <form method=\"post\"> <input type=\"hidden\" value=\"@tag.Id\" name=\"idDaTag\" id=\"idDaTag\" /> <button type=\"button\" data-dismiss=\"modal\">Cancelar</button> <button type=\"submit\">Excluir tag</button> </form> </div> </div> </div> </div> } </div> </fieldset> }
O código HTML dessa página começa mostrando informações sobre o Projeto e sua descrição, além de um botão para adicionar novas Tags ao Projeto.
Ele segue verificando se já há alguma Tag cadastrada no Projeto cadastrado e, se houver, exibe o código HTML restante.
Há, depois, um foreach
que varre toda nossa lista de Tags IList
<Tag> Tags
e cria uma parte do HTML para cada Tag nessa lista.
Nesta parte há um link que redireciona para a página de edição de Tag. Note que o redirecionamento é o mesmo utilizado antes, mas há duas declarações a mais asp-route-idDoProjeto
=
\"@Model.Projeto?.Id\"
e asp-route-idDaTag
=
\"@tag.Id\"
essas declarações dizem que, para a página que estou redirecionando, há duas variáveis que devem ir junto da rota (na URL) e se chamam idDoProjeto
e idDaTag
, respectivamente, seus valores serão o Id do Projeto e o Id da Tag ao qual essa parte do HTML está sendo gerado.
Essas declarações são bem simples e úteis. A parte asp-route-
é fixa, o restante é mutável para nossas necessidades, no nosso caso, uma variável chamada idDoProjeto
e outra chamada idDaTag
, que serão recebidas pela página destino. O URL ficará assim com essa declaração: /Vision/CustomVision/SalvarTag?idDoProjeto=[conteúdo]&idDaTag=[conteúdo]
, por exemplo.
Note, também, que a ação de excluir não redireciona para página alguma, tampouco executa o método post, ela apenas abre uma modal, que está sendo criada logo abaixo. Essa modal é exibida para confirmação de exclusão e é criada para cada Tag existente. Caso haja uma confirmação, aí sim o método post é executado e a Tag é excluída.
Os arquivos inteiros podem ser visualizados no github, tanto o arquivo de HTML, quando a classe do servidor.
Conclusão
Este artigo, devido às várias opções do Serviço Cognitivo de Visão Personalizada, foi dividido em três partes, sendo esta a segunda parte, especificamente sobre as tags da Visão Personalizada da Azure. Justamente por isso, não precisamos adicionar as páginas criadas ao menu, pois a página principal já está lá.
Com isso, a estrutura atual do seu projeto deve estar se parecendo assim:
Além de rápida, a criação de Tags nos permite configurar da forma que quisermos nosso ambiente de Visão Personalizada, nos dando total poder de como treinaremos nossos modelos. Além disso, há a possibilidade de tudo ser feito através do portal de Visão Personalizada, o que nos poupa ainda mais tempo, o que nos reduz o custo.
No próximo artigo, finalizares com o treinamento e predição.
Todo o projeto está disponível no github com uma licença que possibilita colaboração. Sinta-se a vontade.