تشخیص اشیا در تصویر با زامارین اندروید و تنسورفلولایت


طبقه بندی تصاویر با TensorFlow Lite و سرویس Azure Custom Vision  در اندروید

برای تشخیص اشیاء در یک تصویر از طبقه بندی (Classification ) که یک تکنیک در یادگیری ماشینی (ML ) می باشد استفاده می کنیم.

تشخیص شی در یک تصویر امروزه با استفاده از الگوریتم های یادگیری ماشینی خیلی مرسوم شده است. هیجان انگیز هست که یک اپلیکیشن با هوشمندی بتواند یک شی در یک تصویر را بمانند انسان تشخیص دهد.

برای طبقه بندی تصاویر نیاز هست که ما یک متخصص در حوزه یادگیری ماشینی باشیم و الگوریتم های یادگیری ماشینی را یاد بگیریم ولی با استفاده از Azure Custom Vision که سرویس های یادگیری ماشینی را ارائه میدهد بدون دانش الگوریتم های یادگیری ماشینی می توانیم از آن بهره ببریم. من توصیه میکنم هر چند که نیاز به دانستن الگوریتم های یادگیری ماشینی با استفاده از این سرویس نیست ولی حتما در حد آشنایی مطالعه کنید.لازم به ذکر هست که سرویس های Azure در ایران مسدود هستند. بدانید که زاگریو در ایران این امکان را فراهم نموده است و باید از آنها تشکر نمود. (مرگ بر تحریم و مسببین )

در این مقاله بصورت گام به گام با استفاده از Azure Custom Service و TensorFlow Lite  یک اپلیکیشن اندروید با Xamarin.Android  برای تشخیص اشیاء در تصویر پیاده سازی می کنیم.

TensorFlow Lite یک پلتفرم متن باز در حوزه یادگیری ماشینی است.

کتابخانه های طبقه بندی تصویر

1- Azure Custom Vision Service

با استفاده از Azure Custom Vision Service بدون تجربه قبلی در هوش مصنوعی (AI) و یادگیری ماشین (ML ) براحتی مدل های یادگیری ماشین را ایجاد و train  (در یادگیری ماشین train  کردن مدل به این معنی است که به مدل آموزش دهیم)  کنید.

با پورتال Custom Vision Web Portal بدون نوشتن یک خط کد AI/ML می تونیم براحتی با چند گام زیر این کار را انجام دهیم.

1- اپلود یک تصویر برای train کردن

2- تگ کردن اشیاء  در تصویر

3- تکرار ( هر چقدر تکرار بیشتر بشه و داده های بیشتری برای train به مدل بدهیم آموزش بهتری خواهیم داشت )

4-همین و بس. باقی ماجرا با Custom Vision Service هست.

 مایکروسافت قدرتمند. مایکروسافت خیلی خیلی خوب شده و در آینده قدرت بیشتر اون رو خواهیم دید.

2- TensorFlow Lite

TensorFlow Lite یک پلتفرم متن باز برای یادگیری ماشین ( ML ) هست که از TensorFlow برای IoT و دستگاه های موبایل استفاده میکند.

هر دو پلتفرم TensorFlow  و TensorFlow Lite کاملا متن باز بوده و روی GitHub قابل دسترس هستند.

پیاده سازی Image Classification  با Azure و Xamarin.Android

نمونه کامل این اپ روی GitHub موجود هست

https://github.com/dhindrik/MushroomDetector/

1- train کردن مدل (آموزش دادن مدل )

در گام اول با استفاده از Custom Vision Service Web Portal شروع به آموزش مدل می کنیم.

·         در Custom Vision Service Web Portal روی New Project کلیک کنید.


·         در پنجره Create New Project فیلد ها را همانند زیر قرار دهید:

Name: XamarinImageClassification

Description: Identify Objects in Images

Resource: [Create a new resource]

Project Type: Classification

Classification Types: Multilabel (Multiple tags per image)

Domains: General (compact)

Export Capabilities: Basic platforms

1- در پنجره Create new project روی دکمه Create project کلیک کنید.

2- در پنجره  XamarinImageClassification روی Add images کلیک کنید.

3- تصاویر مورد نظر خود را که شامل اشیاء هستند را انتخاب کنید.

4- در پنجره Image upload تگ اضافه کنید.



5- در در پنجره Image upload روی Upload کلیک کنید.

6- در پنجره   XamarinImageClassification

در گوشه سمت راست بالا روی دکمه Train Model کلیک کنید.در پنجره Choose Training Type نوع train را Quick Training انتخاب و در آخر روی دکمه Train کلیک کنید.



2- استخراج مدل train شده از Azure Custom Vision Service

حالا که مدل ما train شد پس می تونیم برای استفاده در اپ موبایل خودمون از آن استفاده کنیم.

با دانلود مدل و استفاده از آن بصورت لوکال نیاز نیست که از اینترنت استفاده کنیم که دراین صورت کاربر تصویر مورد نظر خود را جایی اپلود نمی کند و از این رو حریم خصوصی کاربر حفظ می شود.   

برای استخراج مدل دو مرحله زیر را انجام میدهیم:

1- در پنجره XamarinImageClassification در بالای صفحه، زبانه ( Tab) Performance را نتخاب کنید.

2- در زبانه ( Tab) Performance  روی دکمه Export کلیک کنید.

3- در پنجره Choose your platform  گزینه TensorFlow ، را انتخاب کنید.



4-از لیست کشویی (Dropdown ) گزینه TensorFlow Lite را انتخاب کنید. در نهایت در پنجره Choose your platform گزینه دانلود را انتخاب کنید.

 

3- اضافه کردن TensorFlowLite به پروژه Xamarin.Android

1-در پروژه Xamarin.Android پکیج TensorFlow Lite را از NuGet نصب کنید.

تیم زامارین ماکروسافت این پکیج NuGet  را بصورت متن باز برای اپ Xamarin.Android توسعه داده و که امکان نوشتن کد به C# وجود دارد. کد های C# به کتابخانه اصلی TensorFlowLite بایند می شوند. مرسی از تیم زامارین ماکروسافت.

2- -اکنون مدل را که از Custom Vision Web Portal  دانلود کردیم را باید Unzip کنیم.

در پوشه زیپ دو تا فایل به نام های lables.txt  و model.tflite وجود دارد:

·         فایل labels.txt حاوی تگ تصاویری است که در طی train کردن مدل ایجاد کردیم می باشد.

·         فایل models.tflite مدل یادگیری ماشین ما هست. در واقع از آن برای پیش بینی نام اشیاء در تصاویر استفاده می کنیم.

1- در Visual Studio  در پروژه Xamarin.Android روی پوشه Assets کلیک راست کنید.

2- در منو کلیک راست گزینه Add > Existing item…

3- در پنجره Add Existing item ، هر دوفایل models.tflite  و lables.txt را انتخاب کنید.

4- در پوشه Assets روی فایل labels.txt کلیک راست کنید و از منو گزینه Properties را انتخاب کنید.

5- از منو Properties  گزینه Build Action  و در نهایت Android Asset را انتخاب کنید.

6- در پوشه Assets روی فایل models.tflite کلیک راست کنید و از منو گزینه Properties را انتخاب کنید.

7- از منو Properties  گزینه Build Action  و در نهایت Android Asset را انتخاب کنید.



 

4- پیاده سازی و کدنویسی Image Classification  برای Xamarin.Android

خوب حالا که مدل را به پروژه اضافه کردیم نوبت به کد نویسی رسید. جای خوب داستان اینجاست.

در پروژه Xamarin.Android دو تا کلاس ImageClassificationModel.cs و TensorfloeClassifier.cs را اضافه کنید:

ImageClassificationModel.cs

public class ImageClassificationModel
{
    public ImageClassificationModel(string tagName, float probability)
    {
        TagName = tagName;
        Probability = probability;
    }
  
    public float Probability { get; }
    public string TagName { get; }
}

 TensorflowClassifier.cs



using System.Collections.Generic;
using System.IO;
using System.Linq;
using Android.App;
using Android.Graphics;
using Java.IO;
using Java.Nio;
using Java.Nio.Channels;
 
public class TensorflowClassifier
{
    //FloatSize is a constant with the value of 4 because a float value is 4 bytes
    const int FloatSize = 4;
    //PixelSize is a constant with the value of 3 because a pixel has three color channels: Red Green and Blue
    const int PixelSize = 3;
 
    public List<ImageClassificationModel> Classify(byte[] image)
    {
        var mappedByteBuffer = GetModelAsMappedByteBuffer();
        var interpreter = new Xamarin.TensorFlow.Lite.Interpreter(mappedByteBuffer);
 
        //To resize the image, we first need to get its required width and height
        var tensor = interpreter.GetInputTensor(0);
        var shape = tensor.Shape();
 
        var width = shape[1];
        var height = shape[2];
 
        var byteBuffer = GetPhotoAsByteBuffer(image, width, height);
 
        //use StreamReader to import the labels from labels.txt
        var streamReader = new StreamReader(Application.Context.Assets.Open("labels.txt"));
 
        //Transform labels.txt into List<string>
        var labels = streamReader.ReadToEnd().Split('\n').Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)).ToList();
 
        //Convert our two-dimensional array into a Java.Lang.Object, the required input for Xamarin.TensorFlow.List.Interpreter
        var outputLocations = new float[1][] { new float[labels.Count] };
        var outputs = Java.Lang.Object.FromArray(outputLocations);
 
        interpreter.Run(byteBuffer, outputs);
        var classificationResult = outputs.ToArray<float[]>();
 
        //Map the classificationResult to the labels and sort the result to find which label has the highest probability
        var classificationModelList = new List<ImageClassificationModel>();
 
        for (var i = 0; i < labels.Count; i++)
        {
            var label = labels[i]; classificationModelList.Add(new ImageClassificationModel(label, classificationResult[0][i]));
        }
 
        return classificationModelList;
    }
 
    //Convert model.tflite to Java.Nio.MappedByteBuffer , the require type for Xamarin.TensorFlow.Lite.Interpreter
    private MappedByteBuffer GetModelAsMappedByteBuffer()
    {
        var assetDescriptor = Application.Context.Assets.OpenFd("model.tflite");
        var inputStream = new FileInputStream(assetDescriptor.FileDescriptor);
 
        var mappedByteBuffer = inputStream.Channel.Map(FileChannel.MapMode.ReadOnly, assetDescriptor.StartOffset, assetDescriptor.DeclaredLength);
 
        return mappedByteBuffer;
    }
 
    //Resize the image for the TensorFlow interpreter
    private ByteBuffer GetPhotoAsByteBuffer(byte[] image, int width, int height)
    {
        var bitmap = BitmapFactory.DecodeByteArray(image, 0, image.Length);
        var resizedBitmap = Bitmap.CreateScaledBitmap(bitmap, width, height, true);
 
        var modelInputSize = FloatSize * height * width * PixelSize;
        var byteBuffer = ByteBuffer.AllocateDirect(modelInputSize);
        byteBuffer.Order(ByteOrder.NativeOrder());
 
        var pixels = new int[width * height];
        resizedBitmap.GetPixels(pixels, 0, resizedBitmap.Width, 0, 0, resizedBitmap.Width, resizedBitmap.Height);
 
        var pixel = 0;
 
        //Loop through each pixels to create a Java.Nio.ByteBuffer
        for (var i = 0; i < width; i++)
        {
            for (var j = 0; j < height; j++)
            {
                var pixelVal = pixels[pixel++];
 
                byteBuffer.PutFloat(pixelVal >> 16 & 0xFF);
                byteBuffer.PutFloat(pixelVal >> 8 & 0xFF);
                byteBuffer.PutFloat(pixelVal & 0xFF);
            }
        }
 
        bitmap.Recycle();
 
        return byteBuffer;
    }
}

 

حالا می تونید براحتی با ارسال تصویر به کلاس TensorflowClassifier.Classify ، شی موجود در تصویر را پیش بینی کنید.

منبع : https://devblogs.microsoft.com/xamarin/image-classification-xamarin-android/ 

 

 

 

 

 


نظرات شما برای ما فوق العاده مهم هستند. لطفا نظر خود را بنویسید.


با نظردهی ما را حمایت کنید:

Captcha