Let go for the step by step:
1. Creating our Custom Vision service
The Custom Vision service is part of the Cognitive Services suite of services ( https://aka.ms/cognitive ).
We must start by registering at https://customvision.ai .
We created a new cross-platform blank project, with Xamarin.Forms and PCL type.
- Xam.Plugin.Media v3.0.1 , allows us to cross-platform access to the camera and the photos on the cell phone. Be sure to read the instructions in the Readme.
- Newtonsoft.Json v10.0.3 , allows us to deserialize the JSON format.
- Microsoft.Net.Http v2.2.29 , gives us access to the HttpClient to be able to call web services in a simple way.
- Acr.UserDialogs v6.5.1 , allows us to display progress dialog boxes, toasts, etc. Do not forget to initialize it in the MainActivity.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Clasificador"
x:Class="Clasificador.MainPage"
Title="Clasificador">
<Page.Resources>
<ResourceDictionary>
<Style TargetType="Button">
<Setter Property="BackgroundColor" Value="Blue"/>
<Setter Property="TextColor" Value="White"/>
<Setter Property="BorderRadius" Value="20"/>
</Style>
</ResourceDictionary>
</Page.Resources>
<StackLayout Padding="20">
<Image x:Name="ImgSource" Source="Icon.png" MinimumHeightRequest="100" MinimumWidthRequest="100" HorizontalOptions="Center"/>
<Button Text="Elige una foto" Clicked="ElegirClick">
</Button>
<Button Text="Tomar una foto" Clicked="TomarClick"/>
<Button Text="Analizar" Clicked="ClasificarClick"/>
<Label x:Name="Resultado"/> <ProgressBar x:Name="Precision" />
</StackLayout>
</ContentPage>
private async void ElegirClick(object sender, EventArgs e)
{
await CrossMedia.Current.Initialize();
var foto = await CrossMedia.Current .PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions());
_foto = foto; ImgSource.Source = FileImageSource.FromFile(foto.Path);
}
private async void TomarClick(object sender, EventArgs e)
{
await CrossMedia.Current.Initialize();
var foto = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions()
{
Directory = "clasificator", Name = "source.jpg"
});
_foto = foto; ImgSource.Source = FileImageSource.FromFile(foto.Path);
}
private async void ClasificarClick(object sender, EventArgs e) {
const string endpoint = "https://southcentralus.api.cognitive.microsoft.com/customvision/v1.0/Prediction/4b2e382f-59b0-4941-bbd5-a77b6d3ce8c2/image";
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Prediction-Key", "c1561b9c08134ce69773e368ace40fe6");
var contentStream = new StreamContent(_foto.GetStream());
using (Acr.UserDialogs.UserDialogs.Instance.Loading("Uploading..."))
{
var response = await httpClient.PostAsync(endpoint, contentStream);
if (!response.IsSuccessStatusCode)
{
UserDialogs.Instance.Toast("Un error ha ocurrido."); return;
}
var json = await response.Content.ReadAsStringAsync(); }
}
public string Id { get; set; }
public string Project { get; set; }
public string Iteration { get; set; }
public DateTime Created { get; set; }
public Prediction[] Predictions { get; set; }
}
public class Prediction {
public string TagId { get; set; }
public string Tag { get; set; }
public float Probability { get; set; }
}
Using JSON.NET we perform the response and with that we can show the results in the on-screen controls.
private async void ClasificarClick(object sender, EventArgs e)
{
const string endpoint = "https://southcentralus.api.cognitive.microsoft.com/customvision/v1.0/Prediction/4b2e382f-59b0-4941-bbd5-a77b6d3ce8c2/image";
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Prediction-Key", "c1561b9c08134ce69773e368ace40fe6");
var contentStream = new StreamContent(_foto.GetStream());
using (Acr.UserDialogs.UserDialogs.Instance.Loading("Uploading..."))
{ var response = await httpClient.PostAsync(endpoint, contentStream);
if (!response.IsSuccessStatusCode) { UserDialogs.Instance.Toast("Un error ha ocurrido.");
return;
}
var json = await response.Content.ReadAsStringAsync();
var prediction = JsonConvert.DeserializeObject<PredictionResponse>(json);
var tag = prediction.Predictions.First();
Resultado.Text = $"{tag.Tag} - {tag.Probability:p0}"; Precision.Progress = tag.Probability; } }