Olá, neste post irei falar um pouco sobre a API de Detecção Facial dos Serviços Cognitivos da Microsoft. E claro, não poderia deixar de demonstrar como implementar em aplicações Xamarin.Forms.
O serviço de Detecção facial, consiste em detectar rostos em uma foto e informações como idade, sexo, emoções e etc.
Para se aprofundar mais no assunto e conhecer outros serviços cognitivos da Microsoft acesse o link: https://azure.microsoft.com/pt-br/services/cognitive-services/face/
Para este exemplo irei assumir que você já criou uma aplicação Xamarin.Forms e utilizou o Nuget Package Xam.Plugin.Media para capturar uma foto da câmera. Se você possui dúvidas sobre isso, recomendo ler o post: Utilizando a Câmera – Xamarin.Forms, lá eu explico passo a passo como utilizar o plugin para tirar fotos em aplicações Xamarin.Forms.
Obtendo Chaves
É necessário obter uma URL e Chaves para utilizar a API de Detecção Facial, então o primeiro passo é acessar o link: https://azure.microsoft.com/pt-br/try/cognitive-services/?api=face-api e clicar em “Obter Chave de API”.
Em seguida será necessário realizar login com uma conta Microsoft.
Para este exemplo estou utilizando minha conta e os serviços disponibilizados gratuitamente por 30 dias. (Após esse período essas chaves serão desativadas).
Agora que você já possui sua URL e as chaves para utilizar a API, recomendo que guarde essas informações.
ADICIONANDO NUGET PACKAGES
Clique com o botão direito em cima de sua Solution e selecione “Manage NuGet Packages for Solution…”.
Digite “Microsoft.ProjectOxford.Face” e selecione o plugin como demonstrado na imagem a seguir.
Selecione apenas o projeto compartilhado e clique no botão “Install”.
Depois repita esses passos para instalar os seguintes pacotes:
- Microsoft.ProjectOxford.Common.DotNetStandard
- Newtonsoft.Json
C#
Crie uma variável do tipo IFaceServiceClient e um ObservableCollection de Face. Observe que ambos estão sendo inicializados no construtor. Substitua “URL” pela sua url e “Key” por uma de suas chaves obtidas no passo anterior “Obtendo Chaves”.
Crie um método chamado “TakePicture” como demonstrado no post Utilizando a Câmera – Xamarin.Forms, ele será responsável por tirar a foto. Em seguida adicione uma chamada para o método Facedetect passando como parâmetro o endereço da foto tirada.
Crie o método Facedetect e instancie um IEnumerable de FaceAttributeType com os atributos que serão retornados pela API.
Realize a chamada para o DetectAsync passando como parâmetro um Stream e os atributos setados anteriormente.
Código Completo
using System; | |
using System.Collections.Generic; | |
using System.Collections.ObjectModel; | |
using System.IO; | |
using System.Threading.Tasks; | |
using Microsoft.ProjectOxford.Face; | |
using Microsoft.ProjectOxford.Face.Contract; | |
using Plugin.Media; | |
using Plugin.Media.Abstractions; | |
using Xamarin.Forms; | |
namespace DemoFaceDetect | |
{ | |
public partial class MainPage : ContentPage | |
{ | |
private readonly IFaceServiceClient _faceServiceClient; | |
ObservableCollection<Face> list = new ObservableCollection<Face>(); | |
public MainPage() | |
{ | |
InitializeComponent(); | |
_faceServiceClient = new FaceServiceClient("KEY","URL"); | |
list = new ObservableCollection<Face>(); | |
FacesListView.ItemsSource = list; | |
} | |
private async void TakePicture(object sender, EventArgs e) | |
{ | |
await CrossMedia.Current.Initialize(); | |
if (!CrossMedia.Current.IsTakePhotoSupported || !CrossMedia.Current.IsCameraAvailable) | |
{ | |
await DisplayAlert("Ops", "Nenhuma câmera detectada.", "OK"); | |
return; | |
} | |
var file = await CrossMedia.Current.TakePhotoAsync( | |
new StoreCameraMediaOptions | |
{ | |
SaveToAlbum = false, | |
Directory = "Demo" | |
}); | |
if (file == null) | |
return; | |
await Facedetect(file.AlbumPath); | |
MinhaImagem.Source = ImageSource.FromStream(() => | |
{ | |
var stream = file.GetStream(); | |
file.Dispose(); | |
return stream; | |
}); | |
} | |
public async Task Facedetect(string image) | |
{ | |
IEnumerable<FaceAttributeType> faceAttributes = | |
new FaceAttributeType[] | |
{ | |
FaceAttributeType.Gender, | |
FaceAttributeType.Age, | |
FaceAttributeType.Smile, | |
FaceAttributeType.Emotion, | |
FaceAttributeType.Glasses, | |
}; | |
list.Clear(); | |
// Call the Face API. | |
try | |
{ | |
using (Stream imageFileStream = File.OpenRead(image)) | |
{ | |
var faces = await _faceServiceClient.DetectAsync(imageFileStream, | |
returnFaceId: true, | |
returnFaceLandmarks: false, | |
returnFaceAttributes: faceAttributes); | |
//Add Faces in List | |
foreach (var face in faces) | |
{ | |
list.Add(face); | |
} | |
} | |
} | |
// Catch and display Face API errors. | |
catch (FaceAPIException f) | |
{ | |
await DisplayAlert("Error", f.ErrorMessage, "ok"); | |
} | |
// Catch and display all other errors. | |
catch (Exception e) | |
{ | |
await DisplayAlert("Error", e.Message, "ok"); | |
} | |
} | |
} | |
} |
XAML
Crie uma Image para adicionar a foto tirada, um Button para chamar o método TakePicture quando clicado e uma lista para demonstrar todos os rostos encontrados na foto e seus atributos.
<?xml version="1.0" encoding="utf-8" ?> | |
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" | |
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | |
x:Class="DemoFaceDetect.MainPage"> | |
<ScrollView> | |
<StackLayout> | |
<StackLayout Orientation="Horizontal" | |
HorizontalOptions="Center" | |
VerticalOptions="Center"> | |
<Image x:Name="MinhaImagem" Aspect="AspectFill" HeightRequest="200" | |
WidthRequest="400" HorizontalOptions="CenterAndExpand" /> | |
</StackLayout> | |
<Button Clicked="TakePicture" Text="Foto"></Button> | |
<Label Text="Faces: " FontAttributes="Bold" FontSize="20" | |
HorizontalOptions="CenterAndExpand"/> | |
<ListView x:Name="FacesListView" | |
IsPullToRefreshEnabled="true" | |
CachingStrategy="RecycleElement"> | |
<ListView.ItemTemplate> | |
<DataTemplate> | |
<ViewCell> | |
<StackLayout> | |
<StackLayout Orientation="Horizontal" > | |
<Label Text="Sexo:" FontAttributes="Bold"></Label> | |
<Label Text="{Binding FaceAttributes.Gender}"></Label> | |
<Label Text="Idade:" FontAttributes="Bold"></Label> | |
<Label Text="{Binding FaceAttributes.Age}"></Label> | |
<Label Text="Óculos:" FontAttributes="Bold"></Label> | |
<Label Text="{Binding FaceAttributes.Glasses}"></Label> | |
</StackLayout> | |
<StackLayout Orientation="Horizontal" > | |
<Label Text="Raiva:" FontAttributes="Bold"></Label> | |
<Label Text="{Binding FaceAttributes.Emotion.Anger}"></Label> | |
<Label Text="Felicidade:" FontAttributes="Bold"></Label> | |
<Label Text="{Binding FaceAttributes.Emotion.Happiness}"></Label> | |
<Label Text="Desprezo:" FontAttributes="Bold"></Label> | |
<Label Text="{Binding FaceAttributes.Emotion.Contempt}"></Label> | |
<Label Text="Surpreso:" FontAttributes="Bold"></Label> | |
<Label Text="{Binding FaceAttributes.Emotion.Surprise}"></Label> | |
</StackLayout> | |
</StackLayout> | |
</ViewCell> | |
</DataTemplate> | |
</ListView.ItemTemplate> | |
</ListView> | |
</StackLayout> | |
</ScrollView> | |
</ContentPage> |
Resultado
Esse e todos os exemplos deste blog encontram-se disponíveis no GitHub.
Leia mais sobre esse assunto na documentação oficial da Microsoft.
Um comentário em “Microsoft Cognitive Services – Face Detect com Xamarin.Forms”