Introduction
In this article, you will learn how to consume cognitive services for recognizing a celebrity in Xamarin.Android by using a mobile camera. I hope you will learn some cool stuff in Xamarin using cognitive services.
Xamarin.Android - Recognize Celebrities By Camera
Prerequisites
  • Computer Vision API Key
  • Microsoft.Net.Http
  • Newtonsoft.Json
Computer Vision API keys
Xamarin.Android - Recognize Celebrities By Camera
Computer vision services require special subscription keys. Every call to the Computer Vision API requires a subscription key. This key needs to be either passed through a query string parameter or specified in the request header.
To sign up for subscription keys, see Subscriptions. It's free to sign up. Pricing for these services is subject to change.
If you sign up using the Computer Vision free trial, your subscription keys are valid for the west-central region (https://westcentralus.api.cognitive.microsoft.com).
The steps given below are required to be followed in order to create a Celebrities Recognize app in Xamarin.Android, using Visual Studio.
Step 1 - Create an Android Project
Create your Android solution in Visual Studio or Xamarin Studio. Select Android and from the list, choose Android Blank App. Give it a name, like RecognizeCelebritiesbyCamera.
(ProjectName: RecognizeCelebritiesbyCamera)
Step 2 - Add References of Nuget Packages
First of all, in References, add the reference of Microsoft.Net.Http and Newtonsoft.Json using NuGet Package Manager, as shown below.
Xamarin.Android - Recognize Celebrities By Camera
Step 3 - User Interface
Open Solution Explorer-> Project Name-> Resources-> Layout-> Main.axml and add the following code. The layout will have an ImageView in order to display the preview of Celebrities image. I also added a TextView to display the contents of the Celebrities and two buttons.
(FileName: Main.axml)
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent">
  7. <ImageView
  8. android:id="@+id/image"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent"
  11. android:layout_above="@+id/group_button" />
  12. <LinearLayout
  13. android:layout_above="@+id/txtDescription"
  14. android:id="@+id/group_button"
  15. android:layout_width="match_parent"
  16. android:layout_height="wrap_content"
  17. android:orientation="horizontal"
  18. android:weightSum="2">
  19. <Button
  20. android:id="@+id/btnCapture"
  21. android:layout_width="0dp"
  22. android:layout_height="wrap_content"
  23. android:layout_weight="1"
  24. android:text="Capture" />
  25. <Button
  26. android:id="@+id/btnProcess"
  27. android:layout_width="0dp"
  28. android:layout_height="wrap_content"
  29. android:layout_weight="1"
  30. android:text="Process" />
  31. </LinearLayout>
  32. <TextView
  33. android:id="@+id/txtDescription"
  34. android:layout_width="match_parent"
  35. android:layout_height="wrap_content"
  36. android:text="Description: "
  37. android:textSize="20sp"
  38. android:layout_alignParentBottom="true" />
  39. </RelativeLayout>
Step 4 - Analysis Model Class
Add a new class in your project with name AnalysisModel.cs. Add the following properties to get the result set from JSON response with the appropriate namespace.
  1. using System.Collections.Generic;
  2. namespace RecoginizeCelebrities
  3. {
  4. public class AnalysisModel
  5. {
  6. public IList<Category> categories { get; set; }
  7. public object adult { get; set; }
  8. public IList<Tag> tags { get; set; }
  9. public Description description { get; set; }
  10. public string requestId { get; set; }
  11. public Metadata metadata { get; set; }
  12. public IList<Face> faces { get; set; }
  13. public Color color { get; set; }
  14. public ImageType imageType { get; set; }
  15. }
  16. public class FaceRectangle
  17. {
  18. public int left { get; set; }
  19. public int top { get; set; }
  20. public int width { get; set; }
  21. public int height { get; set; }
  22. }
  23. public class Celebrity
  24. {
  25. public string name { get; set; }
  26. public FaceRectangle faceRectangle { get; set; }
  27. public double confidence { get; set; }
  28. }
  29. public class Detail
  30. {
  31. public IList<Celebrity> celebrities { get; set; }
  32. public object landmarks { get; set; }
  33. }
  34. public class Category
  35. {
  36. public string name { get; set; }
  37. public double score { get; set; }
  38. public Detail detail { get; set; }
  39. }
  40. public class Tag
  41. {
  42. public string name { get; set; }
  43. public double confidence { get; set; }
  44. }
  45. public class Caption
  46. {
  47. public string text { get; set; }
  48. public double confidence { get; set; }
  49. }
  50. public class Description
  51. {
  52. public IList<string> tags { get; set; }
  53. public IList<Caption> captions { get; set; }
  54. }
  55. public class Metadata
  56. {
  57. public int width { get; set; }
  58. public int height { get; set; }
  59. public string format { get; set; }
  60. }
  61. public class Face
  62. {
  63. public int age { get; set; }
  64. public string gender { get; set; }
  65. public FaceRectangle faceRectangle { get; set; }
  66. }
  67. public class Color
  68. {
  69. public string dominantColorForeground { get; set; }
  70. public string dominantColorBackground { get; set; }
  71. public IList<string> dominantColors { get; set; }
  72. public string accentColor { get; set; }
  73. public bool isBWImg { get; set; }
  74. }
  75. public class ImageType
  76. {
  77. public int clipArtType { get; set; }
  78. public int lineDrawingType { get; set; }
  79. }
  80. }
Step 5 - Backend Code
Now, go to Solution Explorer-> Project Name-> MainActivity and add the following code with appropriate namespaces.
Note
Please replace your subscription key and your selected region address in the Main activity class.
(FileName: MainActivity)
  1. using Android.App;
  2. using Android.Widget;
  3. using Android.OS;
  4. using Android.Support.V7.App;
  5. using Android.Graphics;
  6. using System.Net.Http;
  7. using System.IO;
  8. using Android.Content;
  9. using Android.Runtime;
  10. using Android.Content.PM;
  11. using Android;
  12. using Android.Provider;
  13. using System.Threading.Tasks;
  14. using Newtonsoft.Json;
  15. using System;
  16. using System.Net.Http.Headers;
  17. namespace RecoginizeCelebrities
  18. {
  19. [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
  20. public class MainActivity : AppCompatActivity
  21. {
  22. const string subscriptionKey = "3407ad6140b240f58847194ebf0dc26d";
  23. const string uriBase = "https://westcentralus.api.cognitive.microsoft.com/vision/v2.0/analyze";
  24. ImageView imageView;
  25. Bitmap mBitMap;
  26. int CAMERA_CODE = 1000, CAMERA_REQUEST = 1001;
  27. ByteArrayContent content;
  28. TextView txtDes;
  29. Button btnProcess, btnCapture;
  30. public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
  31. {
  32. base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
  33. if (requestCode == CAMERA_CODE)
  34. {
  35. if (grantResults[0] == Permission.Granted)
  36. Toast.MakeText(this, "Permission Granted", ToastLength.Short).Show();
  37. else
  38. Toast.MakeText(this, "Permission Not Granted", ToastLength.Short).Show();
  39. }
  40. }
  41. protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
  42. {
  43. base.OnActivityResult(requestCode, resultCode, data);
  44. if (requestCode == 0 && resultCode == Android.App.Result.Ok &&
  45. data != null)
  46. {
  47. mBitMap = (Bitmap)data.Extras.Get("data");
  48. imageView.SetImageBitmap(mBitMap);
  49. byte[] bitmapData;
  50. using (var stream = new MemoryStream())
  51. {
  52. mBitMap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
  53. bitmapData = stream.ToArray();
  54. }
  55. content = new ByteArrayContent(bitmapData);
  56. }
  57. }
  58. protected override void OnCreate(Bundle savedInstanceState)
  59. {
  60. base.OnCreate(savedInstanceState);
  61. // Set our view from the "main" layout resource
  62. SetContentView(Resource.Layout.activity_main);
  63. //Request runtime permission
  64. if (CheckSelfPermission(Manifest.Permission.Camera) == Android.Content.PM.Permission.Denied)
  65. {
  66. RequestPermissions(new string[] { Manifest.Permission.Camera }, CAMERA_REQUEST);
  67. }
  68. txtDes = FindViewById<TextView>(Resource.Id.txtDescription);
  69. imageView = FindViewById<ImageView>(Resource.Id.image);
  70. btnProcess = FindViewById<Button>(Resource.Id.btnProcess);
  71. btnCapture = FindViewById<Button>(Resource.Id.btnCapture);
  72. btnCapture.Click += delegate
  73. {
  74. Intent intent = new Intent(MediaStore.ActionImageCapture);
  75. StartActivityForResult(intent, 0);
  76. };
  77. btnProcess.Click += async delegate
  78. {
  79. await MakeAnalysisRequest(content);
  80. };
  81. }
  82. public async Task MakeAnalysisRequest(ByteArrayContent content)
  83. {
  84. try
  85. {
  86. HttpClient client = new HttpClient();
  87. // Request headers.
  88. client.DefaultRequestHeaders.Add(
  89. "Ocp-Apim-Subscription-Key", subscriptionKey);
  90. string requestParameters =
  91. "visualFeatures=Categories&details=Celebrities";
  92. // Assemble the URI for the REST API method.
  93. string uri = uriBase + "?" + requestParameters;
  94. content.Headers.ContentType =
  95. new MediaTypeHeaderValue("application/octet-stream");
  96. // Asynchronously call the REST API method.
  97. var response = await client.PostAsync(uri, content);
  98. // Asynchronously get the JSON response.
  99. string contentString = await response.Content.ReadAsStringAsync();
  100. var analysesResult = JsonConvert.DeserializeObject<AnalysisModel>(contentString);
  101. txtDes.Text = "Name: " + analysesResult.categories[0].detail.celebrities[0].name.ToString();
  102. }
  103. catch (Exception e)
  104. {
  105. Toast.MakeText(this, "" + e.ToString(), ToastLength.Short).Show();
  106. }
  107. }
  108. }
  109. }
Results of Analyzing the Celebrities
Just capture the image and hit "Analyze". You will get the same results as shown below.
Xamarin.Android - Recognize Celebrities By Camera
Xamarin.Android - Recognize Celebrities By Camera