Na era das fotos digitais e reconhecimento facial para diversas coisas como realizar login, neste post vamos desmitificar um pouco este funcionalidade e veremos como criar o serviço de Face API do Azure e integra-lo no app Cognitive Services A demanda do mercado por softwares que sejam dotados de uma certa inteligencia tem crescido bastante nos ultimos anos. Com isso, a Microsoft tem ampliado seu investimento para prover ferramentas capazes de entregar esta demanda de maneira simples para os desenvolvedores. Com isto, a Microsoft criou os Serviços Cognitivos (Cognitive Services) . Os Serviços cognitivos, de acordo com a Microsoft são: Os Serviços Cognitivos colocam a IA ao alcance de todos os desenvolvedores, sem exigir experiência com machine learning. É necessária apenas uma chamada à API para inserir a funcionalidade de ver, ouvir, falar, pesquisar, entender e acelerar a tomada de decisão em seus aplicativos O Serviços Cognitivos da Microsoft possuem diversas categorias e funcionalidades diferentes, como: Detector de AnomaliasAnálise de texto Reconhecimento de vozTradução de falaFaceVisão personalizadaVerificação ortográfica Você pode conferir mais sobre os serviços cognitivos no site da plataforma. Criando o serviço de reconhecimento facial Para criar um serviço de reconhecimento facial, você vai precisar de uma conta no Microsoft Azure. Caso você precise inserir um cartão de crédito, o serviço que usaremos neste post é gratuito. Ao acessar o portal do Azure, procure por Cognitive Services: Na próxima tela, clique em + Add Na página seguinte, o Azure irá nos mostrar uma lista de todos os serviços cognitivos disponíveis para serem utilizados. Busque por Face: O Azure irá nos mostrar a pagina do serviço Face, vamos clicar então em Create. Na tela seguinte será solicitado que informemos alguns dados sobre o serviço que estamos criando: Nome, Subscription, Location, Pricing tier e Resource Group. Vamos configurar da seguinte maneira (sinta-se livre para configurar de modo diferente): Nome do serviço: ReconhecimentoFacial (pode ser que o nome que você deseja, já esteja em uso. Neste caso, de um nome diferente)Subscription: Ë sua conta do Azure, selecione a de sua preferenciaLocation: Vamos selecionar Brazil SouthPricing tier: Vamos selecionar F0 (que é camada de preço gratuita do serviço)Resource Group: Vamos selecionar o grupo do agrupador de recursos do Azure que vamos armazenar este serviço (pense nisto como uma pasta onde você irá manter os serviços juntos) vamos clicar m Create New e então informar no nome do resource group que será FaceRecognitionResourceGroup Para finalizar, vamos clicar em Create Após finalizar o processo e o Azure terminar de criar o serviço, o portal irá te mostrar a tela de sucesso. Clique então em Go to resource Integração com Xamarin.Forms A integração com este serviço pode ser feita via SDK do Cognitive Services ou via chamada de API Rest. O SDK está disponível para C# e Phyton. Neste post, nós iremos consumir o serviço via API. Na documentação do Face API você irá encontrar diversos tutorias em varias linguagens, você pode consultar a documentação aqui Vamos criar um novo projeto Xamarin.Forms e na MainPage.xaml vamos adicionar um Image, um botão com a label Tirar Foto e um botão com a label Identificar emoção: <?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="Facial.MainPage" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:d="http://xamarin.com/schemas/2014/forms/design" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <StackLayout Margin="10"> <Image Source="{Binding Foto}" Margin="10" /> <Button Command="{Binding TirarFotoCommand}" Text="Tirar foto" Margin="10"/> <Button Command="{Binding IdentificarEmoçãoCommand}" Text="Identificar emoção" Margin="10"/> </StackLayout> </ContentPage> Veja que no código acima, já definimos alguns bindings, um para o source da foto e outros dois para os commands dos botões. Vamos criar a MainPageViewModel.cs e setar o contexto de binding na MainPage.xaml.cs public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); BindingContext = new MainPageViewModel(); } } Para auxiliar o trabalho com a view model estou utilizando o pacote MVVMHelpers do James Montemagno Para que seja possível utilizar a camera para tirar a foto e enviar para o serviço que criamos no Azure, vamos utilizar o Media.Plugin do Jame Montemagno, ele está disponível aqui e a utilização dele é bem simples, o README do GitHub é bem explicativo. Após configurar o plugin de camera, vamos criar uma nova classe chamada FaceRecognitionService e vamos adicionar a tratativa da imagem e a chamada para API do Azure: public class FaceRecognitionService { const string subscriptionKey = "SUA KEY"; const string uriBase = "https://brazilsouth.api.cognitive.microsoft.com/face/v1.0/detect"; public async Task<List<FaceResponse>> MakeAnalysisRequest(string imageFilePath) { var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey); string requestParameters = "returnFaceId=true&returnFaceLandmarks=false" + "&returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses," + "emotion,hair,makeup,occlusion,accessories,blur,exposure,noise"; string uri = uriBase + "?" + requestParameters; byte[] byteData = GetImageAsByteArray(imageFilePath); List<FaceResponse> result; using (ByteArrayContent content = new ByteArrayContent(byteData)) { content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); var response = await httpClient.PostAsync(uri, content); string contentString = await response.Content.ReadAsStringAsync(); result = JsonConvert.DeserializeObject<List<FaceResponse>>(contentString); } return result; } private byte[] GetImageAsByteArray(string imageFilePath) { using (FileStream fileStream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read)) { BinaryReader binaryReader = new BinaryReader(fileStream); return binaryReader.ReadBytes((int)fileStream.Length); } } } Na classe acima estamos criando duas constantes, uma para armazenar a chave do serviço de reconhecimento facil, Face, criado no portal do Azure e um chamada uriBase que será o endereço da API do azure que iramos chamar. Note que o endereço da API é padrão e está apontando para o local onde criamos o serviço. Após isto, estamos criando o HTTP Client padrão do .NET e adicionando no header a chave que armazenamos na nossa constante criada acima. Montamos a url que iremos enviar a foto passando alguns parâmetros, que são o que nós estamos pedindo como resposta para o Azure. Fazemos isto na variável requestParameters, note que estamos pedindo smile, facielHair, glasses, noise, emotion e outros. Estes são os dados que após fazer a análise, o Azure irá nos devolver. O passo seguinte é utilizar o método de converter a imagem para um byte array e fazer o post para url contada com o urlBase + requestParameters (que são os dados que estamos pedindo como resposta do Azure). Para finalizarmos esta parte e voltamos e partimos para a view model, ainda precisamos fazer mais algumas coisas. A primeira é acessar novamente o portal do Azure e copiar a Key1: Copie o valor de Key1 e preencha na subscriptionKey da classe FaceRecognitionService. O objeto que será retornado pela API irá conter todas as informações que passamos no requestParameters na classe FaceRecognitionService. Nós não iremos utilizar todos estes dados, então para o exemplo do post, vamos criar duas nova classes: Uma chamada Face, que será o nosso modelo que armazenará o retorno e a classe FaceReponse que utilizaremos para deserializar o JSON de retorno do Azure: public class Face { [JsonProperty("emotion")] public Dictionary<string, double> Emotions; public string CurrentEmotion() { var emotions = Emotions.OrderByDescending(x => x.Value); return emotions.FirstOrDefault().Key; } } public class FaceResponse { public Face FaceAttributes { get; set; } } Ufa! A maior parte do trabalho já está feito! Agora vamos configurar a MainPageViewModel para realizar as chamadas: [code language="csharp"] public class MainPageViewModel : BaseViewModel { public ICommand TirarFotoCommand { get; set; } public ICommand IdentificarEmoçãoCommand { get; set; } ImageSource foto; public ImageSource Foto { get => foto; set => SetProperty(ref foto, value); } private string Arquivo { get; set; } string emoção; public string Emoção { get => emoção; set => SetProperty(ref emoção, value); } public MainPageViewModel() { TirarFotoCommand = new Command(async () => { await CrossMedia.Current.Initialize(); if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported) { Console.Write(@"Camera indisponível"); return; } var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions { Directory = "Exemplo", Name = "teste.jpg" }); if (file == null) return; Arquivo = file.Path; Foto = ImageSource.FromStream(() => { var stream = file.GetStream(); file.Dispose(); return stream; }); }); IdentificarEmoçãoCommand = new Command(async () => { var resultado = await new FaceRecognitionService().MakeAnalysisRequest(Arquivo); Emoção = resultado.FirstOrDefault().FaceAttributes.CurrentEmotion(); await App.Current.MainPage.DisplayAlert("Emoção da foto", Emoção, "OK"); }); } } [/code] Na view model acima além dos commands e da propriedade para guardar a imagem, nós também criamos um propriedade do tipo string chamada de Arquivo que será responsável por armazenar o endereço da imagem para lermos no command de enviar a imagem posteriormente a execução do command de tirar foto. Também criamos a propriedade string chamada Emoção, ela será a variável que irá armazenar a emoção retornada pelo Azure e exibida em um alert. Isso é tudo! Agora é só executar e ver o resultado! Conclusão Os serviços cognitivos são bem simples de serem consumidos e integrados com aplicações por ter a possibilidade de utilizar a API Rest. A documentação é bem completa e parte essencial para o uso. Com Xamarin, da um poder muito legal ao app com pouco esforço. — Você pode conferir o código deste post no meu GitHub, neste endereço #Ubuntu Compartilhe isso:Clique para compartilhar no Twitter(abre em nova janela)Clique para compartilhar no Facebook(abre em nova janela)Curtir isso:Curtir Carregando...