B4A Library [B4X] SelfieSegmentation with ML Kit

1717424669041.png

Image source: https://en.wikipedia.org/wiki/Selfie#/media/File:TWC_Hokitika_Gorge_•_Stewart_Nimmo_•_MRD_1.jpg

A B4A + B4i selfie segmentation feature based on Google ML Kit: https://developers.google.com/ml-kit/vision/selfie-segmentation
The result is a mask image. In the example it is overlayed over the original image using a semitransparent B4XImageView.

Usage itself is quite straightforward. See the example.
Please go over the dependencies sections in the text recognition tutorial: https://www.b4x.com/android/forum/threads/b4x-textrecognition-based-on-mlkit.161210/#content

Don't miss:
- B4i dependencies + #PlistExtra (for MediaChooser) in Main module.
- B4i bundle files under Files\Special.
- B4A dependencies in Main module.
- B4A manifest editor. Snippets for MLKit and snippet for FileProvider (MediaChooser).
 

Attachments

Last edited:
I get the linking error:

B4A Versión: 13.40
Parseando código. (0.21s)
Java Versión: 11
Building folders structure. (0.05s)
Corriendo accion personalizada. (0.09s)
Compilando código. (0.38s)
Compilado códigos de diseños. (0.07s)
Organizando librerías. (7.69s)
(AndroidX SDK)
Compilando los recursos (2.08s)
Enlazando los recursos Error
res\values-v20\theme.xml:6: error: style attribute 'android:attr/windowOptOutEdgeToEdgeEnforcement' not found.
error: failed linking references.

I think I followed all the steps mentioned.

Please help!
 
When running Example latest version of B4A

Code:
** Activity (main) Resume **
(Bitmap) android.graphics.Bitmap@458c049
b4xmainpage_removemask (java line: 415)
java.lang.ArrayIndexOutOfBoundsException: length=835744; index=835747
    at b4a.example.bitmapcreator._getargb(bitmapcreator.java:4659)
    at selfie.segmentation.b4xmainpage._removemask(b4xmainpage.java:415)
    at selfie.segmentation.b4xmainpage$ResumableSub_HandeChooserResult.resume(b4xmainpage.java:357)
    at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:275)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:215)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.keywords.Common$15.run(Common.java:1857)
    at android.os.Handler.handleCallback(Handler.java:959)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loopOnce(Looper.java:249)
    at android.os.Looper.loop(Looper.java:337)
    at android.app.ActivityThread.main(ActivityThread.java:9469)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:636)
 
Looks like the mask size isn't the same as the bitmap size. Change the code in HandeChooserResult to:
Code:
If res.Success Then
        Log("bmp: " & bmp.Width & " x " & bmp.Height)
        Log("mask: " & res.ForegroundBitmap.Width & " x " & res.ForegroundBitmap.Height)
        Dim AfterMask As B4XBitmap = RemoveMask(bmp, res.ForegroundBitmap)
        ivOriginal.Bitmap = AfterMask
        ivMaskSmall.Bitmap = res.ForegroundBitmap
    End If

What is the output?
 
When running Example latest version of B4A

Code:
** Activity (main) Resume **
(Bitmap) android.graphics.Bitmap@458c049
b4xmainpage_removemask (java line: 415)
java.lang.ArrayIndexOutOfBoundsException: length=835744; index=835747
    at b4a.example.bitmapcreator._getargb(bitmapcreator.java:4659)
    at selfie.segmentation.b4xmainpage._removemask(b4xmainpage.java:415)
    at selfie.segmentation.b4xmainpage$ResumableSub_HandeChooserResult.resume(b4xmainpage.java:357)
    at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:275)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:215)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.keywords.Common$15.run(Common.java:1857)
    at android.os.Handler.handleCallback(Handler.java:959)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loopOnce(Looper.java:249)
    at android.os.Looper.loop(Looper.java:337)
    at android.app.ActivityThread.main(ActivityThread.java:9469)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:636)
I removed /bmp.Scale in the following routine and the segmentation seems to work without crash. However I have no idea if the code is correct :

Private Sub CreateBC(bmp As B4XBitmap) As BitmapCreator
Dim bc As BitmapCreator
'bc.Initialize(bmp.Width / bmp.Scale, bmp.Height / bmp.Scale)
bc.Initialize(bmp.Width, bmp.Height)
bc.CopyPixelsFromBitmap(bmp)
Return bc
End Sub
 
Back
Top