xamarin / GooglePlayServicesComponents

Other
315 stars 146 forks source link

ImageProcessor.Builder.Build() method is missing from TensorFlow.Lite.Support library #754

Closed v-hogood closed 3 months ago

matmork commented 1 year ago

Try this

var imageProcessorBuilder = new ImageProcessor.Builder();

var imageProcessor = GetObject<ImageProcessor>
(imageProcessorBuilder.JniPeerMembers.InstanceMethods.InvokeVirtualObjectMethod("build.()Lorg/tensorflow/lite/support/common/SequentialProcessor;", imageProcessorBuilder, null).Handle, JniHandleOwnership.TransferLocalRef);
wollac11 commented 1 year ago

This is still a problem even with the very latest versions and it seems to affect not just the ImageProccessor.Builder but other Builders too (like TensorProcessor.Builder)

wollac11 commented 4 months ago

This is still broken in the latest version so I figured I'd bump the ticket and also add a workaround for anyone else who finds this.

@v-hogood has published a set of bindings that do contain these missing members. For people that just want to use the interpreter API or the standalone version of the Task Vision Library, that is probably the best option right now.

However, I wanted to use the Google Play Services version of the Task Vision library within my project (but I also need to use the Interpreter APIs to properly support some older models too). So to workaround the missing methods in Microsoft's bindings, I went with a solution similar to the suggestion above from @matmork but adjusted the method path to reflect the current library and wrapped them in extensions like so:

public static TensorProcessor Build(this TensorProcessor.Builder builder)
{
    return Java.Lang.Object.GetObject<TensorProcessor>(builder.JniPeerMembers.InstanceMethods.InvokeVirtualObjectMethod("build.()Lorg/tensorflow/lite/support/common/TensorProcessor;", builder, null).Handle, JniHandleOwnership.TransferLocalRef);
}

public static ImageProcessor Build(this ImageProcessor.Builder builder)
{
    return Java.Lang.Object.GetObject<ImageProcessor>(builder.JniPeerMembers.InstanceMethods.InvokeVirtualObjectMethod("build.()Lorg/tensorflow/lite/support/image/ImageProcessor;", builder, null).Handle, JniHandleOwnership.TransferLocalRef);
}

It works pretty well as a workaround. You'll need to enable unsafe code in your project and either declare these methods as unsafe or (as I opted to do) just declare the static extension class that contains them as unsafe instead.

That said, it would be good to get the bindings packages fixed at some point so this sort of thing is not needed.