在Android中使用Xamarin运行TensorFlow Lite示例

在Android中使用Xamarin运行TensorFlow Lite示例,android,xamarin,artificial-intelligence,tensorflow-lite,Android,Xamarin,Artificial Intelligence,Tensorflow Lite,很难在网上找到有关使用Xamarin实现TensorFlow Lite的资源。我试图从这个问题以及链接的堆栈溢出页面中重现同样的内容。我对Xamarin和TensorFlow很陌生,所以这里需要帮助。我所做的只是将在Visual Studio中创建的新解决方案的粘贴复制到MainActivity.cs。使用NuGet包Xamarin.TensorFlow.Lite using Android.App; using Android.Content.Res; using Android.Graphi

很难在网上找到有关使用Xamarin实现TensorFlow Lite的资源。我试图从这个问题以及链接的堆栈溢出页面中重现同样的内容。我对Xamarin和TensorFlow很陌生,所以这里需要帮助。我所做的只是将在Visual Studio中创建的新解决方案的粘贴复制到
MainActivity.cs
。使用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();
    }
}
使用Android.App;
使用Android.Content.Res;
使用Android.Graphics;
使用Android.OS;
使用Android.Runtime;
使用Android.Support.Design.Widget;
使用Android.Support.V7.App;
使用Android.Views;
使用Java.IO;
使用Java.Nio;
使用Java.Nio.Channels;
使用Plugin.Media.Abstractions;
使用制度;
使用System.Runtime.InteropServices;
使用Xamarin.TensorFlow.Lite;
名称空间App1
{
[活动(Label=“@string/app_name”,Theme=“@style/AppTheme.NoActionBar”,MainLauncher=true)]
公共类MainActivity:AppCompativeActivity
{
创建时受保护的覆盖无效(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(这个,savedInstanceState);
SetContentView(Resource.Layout.activity_main);
Android.Support.V7.Widget.Toolbar-Toolbar=findviewbyd(Resource.Id.Toolbar);
设置支持操作栏(工具栏);
FloatingActionButton fab=FindViewById(Resource.Id.fab);
生产线点击+=生产线点击;
}
公共覆盖布尔onCreateOptions菜单(IMenu菜单)
{
菜单充气器。充气(Resource.Menu.Menu_main,Menu);
返回true;
}
公共覆盖bool OnOptionsItemSelected(IMenuItem)
{
int id=item.ItemId;
if(id==Resource.id.action\u设置)
{
返回true;
}
返回基本选项。OnOptionsItemSelected(项目);
}
私有void FabOnClick(对象发送方,EventArgs EventArgs)
{
视图=(视图)发送方;
Snackbar.Make(查看“替换为您自己的操作”,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(请求代码、权限、GrantResult);
base.OnRequestPermissionsResult(请求代码、权限、GrantResult);
}
私有MappedByteBuffer加载模型文件()
{
var资产=Application.Context.assets;
AssetFileDescriptor fileDescriptor=assets.OpenFd(“seed_model_no_qt.tflite”);
FileInputStream inputStream=新的FileInputStream(fileDescriptor.fileDescriptor);
FileChannel FileChannel=inputStream.Channel;
long startOffset=fileDescriptor.startOffset;
long declaredLength=fileDescriptor.declaredLength;
返回fileChannel.Map(fileChannel.MapMode.ReadOnly,startOffset,declaredLength);
}
私有字符串分类(MediaFile MediaFile)
{
var资产=Application.Context.assets;
位图bp=BitmapFactory.DecodeStream(mediaFile.GetStream());
var resizedBitmap=Bitmap.CreateScaledBitmap(bp,12801280,false)。复制(Bitmap.Config.argb888,false);
var bufint=新整数[1280*1280];
GetPixels(bufint,0,1280,0,0,1280,1280);
整数像素=0;
var input_buffer=新字节[4*1280*1280*3];
对于(int i=0;i<1280;i++)
{
对于(int k=0;k<1280;k++)
{
int val=bufint[pixels++];
Array.Copy(BitConverter.GetBytes((val>>16)和0xFF)*(1f/255f)),0,输入缓冲区,(i*1280+k)*12,4);
Array.Copy(BitConverter.GetBytes((val>>8)和0xFF)*(1f/255f)),0,输入缓冲区,(i*1280+k)*12+4,4);
Array.Copy(BitConverter.GetBytes((val&0xFF)*(1f/255f)),0,输入缓冲区,(i*1280+k)*12+8,4);
}
}
var bytebuffer=Java.Nio.bytebuffer.Wrap(输入缓冲区);
var output=Java.Nio.ByteBuffer.AllocateDirect(4*160*160);
运行(bytebuffer,输出);
var buffer=新字节[4*160*160];
Copy(output.GetDirectBufferAddress(),buffer,0,4*160*160);
浮动总和=0.0f;
对于(int i=0;i<160*160;i++)
{
sum+=位转换器.ToSingle(缓冲区,i*4);
}
返回“Count:”+((int)(sum/255)).ToString();
}
}
}

我面临的特殊问题是此错误:
非静态字段、方法或属性的解释器需要对象引用。即使我使用Xamarin.TensorFlow.Lite,也要运行(object,object)


我不知道从哪里开始解决这个问题,因为我对Xamarin非常陌生。

错误消息很清楚,您没有实例化
解释器
对象,即
var my解释器=新解释器(someBuffer)Run
方法。谢谢@寿司宿醉@SebastianKong嗨,如果已经解决了,记得在回答中分享解决方案。经过一段时间的工作,它没有编译错误,但我实际上没有调用该函数。当用我自己的模型调用解释器时,会出现一些错误。然而,这可能与这个问题无关。所以需要一些时间来研究它,否则我不确定这个问题是否得到了回答。@SebastianKong您对TensorFlow for ML与Xamarin一起使用的经验、理解和建议是什么?Xamarin在数据AI和ML中的局限性是什么。