Microsoft Azure Cognitive Services — Fotoğrafları Xamarin ile Tanıyalım

Furkan Bozdag
4 min readApr 21, 2017

--

Selamlar.

Bilindiği gibi Microsoft’un Azure servisi ücretli bir servis ama bunun yanında geliştirdiğiniz ürünler için tadımlık bir ücretsiz kullanım sunuyor. Bu da bize geliştireceğimiz üründe kullanacağımız servis neyse test etme imkanı veriyor :)

Ayrıca Azure içerisinde basit SQL Server’dan yapay zekaya kadar tüm bileşenlere ulaşmanız mümkün. Bugün değinmek istediğim konu ise Azure’da bulunan Cognitive Servisleri.

Peki nedir bu Cognitive Servisleri?

Cognitive Services(Bilişsel Hizmetler) güçlü yapay zeka algoritmalarıyla oluşturulmuş görüntü, duygu, ses, video, bilgi ve daha fazla durumu analiz etmeye yarayan bir servistir. Bu servis ile bir fotoğrafta duygu analizi yapabilir, bir ses dosyasındaki kelimeleri öğrenebilir yada fotoğrafta ne olduğunu yapay zekaya sorabilirsiniz. Datanın çok önemli olduğu bu zamanda imkanınız varsa ürününüzde böyle bir servis kullanmak sizin açınızdan çok faydalı olacaktır.

Buraya kadar olan hikaye kısımdan sonra hiç bilmeyenler için bu servisi Xamarin’de kullanarak basit bir uygulama geliştirip fotoğrafımızı analiz ettirelim :)

Öncelikle Azure üzerinde kullanacağımız servisi oluşturuyoruz.

Daha sonra bir Xamarin.Forms PCL projesi açıyoruz. Daha sonra servisleri kullanabilmek için NuGet’ten sırayla Microsoft.Bcl.Build ve Microsoft.Bcl paketlerini tüm katmanlarımıza ekliyoruz.

Ardından servisle haberleşebilmemiz için HttpClient, dönecek olan datayı almak için ise Newtonsoft.JSON paketlerini de tüm katmanlarımıza ekliyoruz.

Fotoğraf analiz edeceğimiz için NuGet’ten Xam.Plugin.Media paketini de kurmamız gerekiyor. İsteyen bu plugin olmadan fotoğrafın olduğu herhangi bir url vererek de analiz yapabilir.

Buradan sonra Xamarin tarafını okunabilirlik açısından MVVM (Konuyu bilmiyorsanız buradan öğrenebilirsiniz) ile yazdım. Öncelikle gelecek datamız için model oluşturuyoruz.

public class ComputerVisionModel
{
public class Rootobject
{
public Description description { get; set; }
public string requestId { get; set; }
public Metadata metadata { get; set; }
}

public class Description
{
public string[] tags { get; set; }
public Caption[] captions { get; set; }
}

public class Caption
{
public string text { get; set; }
public float confidence { get; set; }
}

public class Metadata
{
public int width { get; set; }
public int height { get; set; }
public string format { get; set; }
}
}

Daha sonra servise request edebilmemiz için ServiceManager sınıfını yazıyoruz (Bu kısma fazla takılmayın). Azure'da servisi oluşturduktan sonra ApiKey 'i yazmayı unutmayın.

public class ServiceManager
{
// Constructor
public ServiceManager()
{
}

public async Task<string> Request(Stream stream)
{
try
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress =
new Uri("https://westus.api.cognitive.microsoft.com/vision/v1.0/describe?maxCandidates=1");
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{ApiKeyWillBeHere}");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/octet-stream"));

HttpContent content = new StreamContent(stream);
content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/octet-stream");

var response = await client.PostAsync(
"https://westus.api.cognitive.microsoft.com/vision/v1.0/describe?maxCandidates=1", content);
return await response.Content.ReadAsStringAsync();
}
}
catch (Exception ex)
{
return "Task failed.\nDetails: " + ex.Message;
}
}
}

Yaptığım basit bir arayüz tasarımından sonra sıra geldi fotoğrafımızı seçerek veya çekerek analiz etmeye edip, sayfamıza bind etmeye :)

private async void onTakePhoto()
{
try
{
var media = CrossMedia.Current;
if (!media.IsTakePhotoSupported)
await Application.Current.MainPage.DisplayAlert("Error", "Camera not available!", "OK");

var img = await media.TakePhotoAsync(new StoreCameraMediaOptions());
if (img != null)
{
var manager = new ServiceManager();
var result = await manager.Request(img.GetStream());

_model = JsonConvert.DeserializeObject<ComputerVisionModel.Rootobject>(result);
IsVisible = true;
BindData();
}
}
catch (Exception ex)
{
await Application.Current.MainPage.DisplayAlert("Error", "Message: " + ex.Message, "OK");
}
}
private async void onSelectPhoto()
{
try
{
var media = CrossMedia.Current;
if (!media.IsPickPhotoSupported)
await Application.Current.MainPage.DisplayAlert("Error", "File directory is not found!", "OK");

var img = await media.PickPhotoAsync();
if (img != null)
{
var manager = new ServiceManager();
var result = await manager.Request(img.GetStream());
_model = JsonConvert.DeserializeObject<ComputerVisionModel.Rootobject>(result);

SelectedPhoto = img.Path + " is selected.";
IsVisible = true;
BindData();
}
}
catch (Exception ex)
{
await Application.Current.MainPage.DisplayAlert("Error", "Message: " + ex.Message, "OK");
}
}
private void BindData()
{
if (_model != null)
{
MetaData = "Meta\n";
CaptionText = "Description\n";
Tags = "Tags\n";

MetaData = string.Format($"H: {_model.metadata.height}\n" +
$"W: {_model.metadata.width}\n" +
$"Format: {_model.metadata.format}");

for (int i = 0; i < _model.description.captions.Length; i++)
{
CaptionText += _model.description.captions[i].text;
if (i != _model.description.captions.Length)
CaptionText += ", ";
}

for (int i = 0; i < _model.description.tags.Length; i++)
{
Tags += _model.description.tags[i];
if (i != _model.description.tags.Length)
Tags += ", ";
}
}
}

Bind metodu esnasında dönen datamızı onTakePhoto ve onSelectPhoto metodları içerisinde modelimize dönüştürdükten sonra MetaData, CaptionText, Tags stringlerine set ediyoruz (Çünkü bunları sayfamıza bind edeceğiz).

Vee sonuç :)

Projenin kaynak kodlarına buradan ulaşabilirsiniz.
Konu ile alakalı daha detaylı bilgiyi buradan inceleyebilirsiniz.

Ayrıca yüz tanıma, duygu analizi için Ozan kardeşimin github adresine de göz atabilirsiniz.

Görüşmek üzere, hoşçakalın ;)

--

--

Furkan Bozdag
Furkan Bozdag

Written by Furkan Bozdag

I don’t know what’s happening here? | sr. software engineer

No responses yet