Использование Xamarin - запуск примеров TensorFlow Lite в Android - PullRequest
0 голосов
/ 17 февраля 2020

Трудно найти ресурсы в Интернете о реализации TensorFlow Lite с Xamarin. Я пытаюсь воспроизвести то же самое из вопроса на этой странице переполнения стека , а также на связанных страницах переполнения стека. Я очень новичок в Xamarin и TensorFlow, поэтому мне нужна помощь здесь. Я просто скопировал вставку в MainActivity.cs нового решения, созданного в Visual Studio. С пакетом NuGet Xamarin.TensorFlow.Lite.

using Android.App;
using Android.Content.Res;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Support.V7.App;
using Android.Views;
using Java.IO;
using Java.Nio;
using Java.Nio.Channels;
using Plugin.Media.Abstractions;
using System;
using System.Runtime.InteropServices;
using Xamarin.TensorFlow.Lite;

namespace App1
{
    [Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
    public class MainActivity : AppCompatActivity
    {

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        SetContentView(Resource.Layout.activity_main);

        Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
        SetSupportActionBar(toolbar);

        FloatingActionButton fab = FindViewById<FloatingActionButton>(Resource.Id.fab);
        fab.Click += FabOnClick;
    }

    public override bool OnCreateOptionsMenu(IMenu menu)
    {
        MenuInflater.Inflate(Resource.Menu.menu_main, menu);
        return true;
    }

    public override bool OnOptionsItemSelected(IMenuItem item)
    {
        int id = item.ItemId;
        if (id == Resource.Id.action_settings)
        {
            return true;
        }

        return base.OnOptionsItemSelected(item);
    }

    private void FabOnClick(object sender, EventArgs eventArgs)
    {
        View view = (View) sender;
        Snackbar.Make(view, "Replace with your own action", Snackbar.LengthLong)
            .SetAction("Action", (Android.Views.View.IOnClickListener)null).Show();
    }
    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
    {
        Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    private MappedByteBuffer LoadModelFile()
    {
        var assets = Application.Context.Assets;
        AssetFileDescriptor fileDescriptor = assets.OpenFd("seed_model_no_qt.tflite");
        FileInputStream inputStream = new FileInputStream(fileDescriptor.FileDescriptor);
        FileChannel fileChannel = inputStream.Channel;
        long startOffset = fileDescriptor.StartOffset;
        long declaredLength = fileDescriptor.DeclaredLength;
        return fileChannel.Map(FileChannel.MapMode.ReadOnly, startOffset, declaredLength);
    }

    private string Classify(MediaFile mediaFile)
    {
        var assets = Application.Context.Assets;

        Bitmap bp = BitmapFactory.DecodeStream(mediaFile.GetStream());
        var resizedBitmap = Bitmap.CreateScaledBitmap(bp, 1280, 1280, false).Copy(Bitmap.Config.Argb8888, false);

        var bufint = new int[1280 * 1280];
        resizedBitmap.GetPixels(bufint, 0, 1280, 0, 0, 1280, 1280);
        int pixels = 0;
        var input_buffer = new byte[4 * 1280 * 1280 * 3];
        for (int i = 0; i < 1280; i++)
        {
            for (int k = 0; k < 1280; k++)
            {
                int val = bufint[pixels++];
                Array.Copy(BitConverter.GetBytes(((val >> 16) & 0xFF) * (1f / 255f)), 0, input_buffer, (i * 1280 + k) * 12, 4);
                Array.Copy(BitConverter.GetBytes(((val >> 8) & 0xFF) * (1f / 255f)), 0, input_buffer, (i * 1280 + k) * 12 + 4, 4);
                Array.Copy(BitConverter.GetBytes((val & 0xFF) * (1f / 255f)), 0, input_buffer, (i * 1280 + k) * 12 + 8, 4);
            }
        }
        var bytebuffer = Java.Nio.ByteBuffer.Wrap(input_buffer);
        var output = Java.Nio.ByteBuffer.AllocateDirect(4 * 160 * 160);
        Interpreter.Run(bytebuffer, output);

        var buffer = new byte[4 * 160 * 160];

        Marshal.Copy(output.GetDirectBufferAddress(), buffer, 0, 4 * 160 * 160);

        float sum = 0.0f;
        for (int i = 0; i < 160 * 160; i++)
        {
            sum += BitConverter.ToSingle(buffer, i * 4);
        }

        return "Count : " + ((int)(sum / 255)).ToString();
    }
}

}

Особая проблема, с которой я сталкиваюсь, - это ошибка: An object reference is required for the non-static field, method, or property 'Interpreter.Run(Object, Object), хотя я using Xamarin.TensorFlow.Lite;

I Я не уверен, где начать решать эту проблему, потому что я очень плохо знаком с Xamarin.

...