Great, Thanks. That is very close, but I need the foreground bitmap rather than the white mask.Like this?
[B4X] SelfieSegmentation with ML Kit
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...www.b4x.com
This may also work:
[class] ML Kit Subject Segmentation
https://developers.google.com/ml-kit/vision/subject-segmentation Input: image Output: image with main subject See attached project. Don't miss the #AdditionalJars in the main module and the manifest editor snippets. Usage: Private Sub Button1_Click Dim cc As ContentChooser...www.b4x.com
Very nice, but that is a paid (expensive) service. However, APIs can be imported to b4a.https://magicstudio.com/it/background-remover/
(I don't remember if you will be able to download the image for free).
I would also try Grok (x.com)
I thought you just wanted to create images, using external tools, to use in your projects.Some paid sites do that by ai.
The #2 link posted by DonManfred does not solve your issue?Great, Thanks. That is very close, but I need the foreground bitmap rather than the white mask.
I said b4a code. I will be grateful for any.While it was likely, you did not specify that you wanted to do this programmatically, in your app, and since you wrote:
I thought you just wanted to create images, using external tools, to use in your projects.
You can get the foreground bitmap of the image by the maskGreat, Thanks. That is very close, but I need the foreground bitmap rather than the white mask.
Unfortunately, the referred code: https://www.b4x.com/android/forum/threads/b4x-selfiesegmentation-with-ml-kit.161499/#content is not workingYou can get the foreground bitmap of the image by the mask
I modified Erel's code to fit my needs, this code works fine for me, removing the background completely, it only works for B4A, I still have not gotten a perfect solution for B4i.Unfortunately, the referred code: https://www.b4x.com/android/forum/threads/b4x-selfiesegmentation-with-ml-kit.161499/#content is not working
'v1.01
Sub Class_Globals
Type SegmentationResult (Success As Boolean, ForegroundBitmap As B4XBitmap, ForegroundMask As B4XBitmap)
Private segmenter As JavaObject
Private xui As XUI
End Sub
Public Sub Initialize
Dim options As JavaObject
options.InitializeNewInstance("com.google.mlkit.vision.segmentation.subject.SubjectSegmenterOptions.Builder", Null)
options = options.RunMethodJO("enableForegroundBitmap", Null).RunMethodJO("enableForegroundConfidenceMask", Null).RunMethod("build", Null)
Dim SubjectSegmentation As JavaObject
SubjectSegmentation.InitializeStatic("com.google.mlkit.vision.segmentation.subject.SubjectSegmentation")
segmenter = SubjectSegmentation.RunMethod("getClient", Array(options))
End Sub
Private Sub CreateInputImage(bmp As B4XBitmap) As Object
Dim InputImage As JavaObject
InputImage.InitializeStatic("com.google.mlkit.vision.common.InputImage")
Return InputImage.RunMethod("fromBitmap", Array(bmp, 0))
End Sub
Public Sub Process (bmp As B4XBitmap, getForeGroundMask As Boolean, maskColor As Int) As ResumableSub
Dim image As JavaObject = CreateInputImage(bmp)
Dim width, height As Int
width = image.RunMethod("getWidth", Null)
height = image.RunMethod("getHeight", Null)
Dim colores(width & height) As Int
Dim task As JavaObject = segmenter.RunMethod("process", Array(image))
Do While task.RunMethod("isComplete", Null).As(Boolean) = False
Sleep(50)
Loop
Dim res As SegmentationResult
res.Initialize
If task.RunMethod("isSuccessful", Null) Then
res.Success = True
Dim SubjectSegmentationResult As JavaObject = task.RunMethod("getResult", Null)
res.ForegroundBitmap = SubjectSegmentationResult.RunMethod("getForegroundBitmap", Null)
If getForeGroundMask Then
Dim ForegroundMask As JavaObject
ForegroundMask = SubjectSegmentationResult.RunMethod("getForegroundConfidenceMask", Null)
Dim bitmapMask As BitmapCreator
bitmapMask.Initialize(width, height)
For i = 0 To (width * height) - 1
If (ForegroundMask.RunMethod("get", Null)) > 0.5 Then
colores(i) = maskColor
Else
colores(i) = xui.Color_White
End If
Next
Dim bmpx As JavaObject
Dim foregroundBitmap As B4XBitmap
bmpx = bmpx.InitializeStatic("android.graphics.Bitmap")
Dim config As JavaObject
config = config.InitializeStatic("android.graphics.Bitmap.Config")
bmpx = bmpx.RunMethodJO("createBitmap", Array(colores, width, height, config.GetField("ARGB_8888")))
foregroundBitmap = bmpx
res.ForegroundMask = foregroundBitmap
End If
End If
Return res
End Sub
Public Sub Initialize
Dim options As JavaObject
options.InitializeNewInstance("com.google.mlkit.vision.segmentation.subject.SubjectSegmenterOptions.Builder", Null)
options = options.RunMethodJO("enableForegroundBitmap", Null).RunMethodJO("enableForegroundConfidenceMask", Null).RunMethod("build", Null)
Dim SubjectSegmentation As JavaObject
SubjectSegmentation.InitializeStatic("com.google.mlkit.vision.segmentation.subject.SubjectSegmentation")
segmenter = SubjectSegmentation.RunMethod("getClient", Array(options))
End Sub
After replacing the code you recommended and using getForeGroundMask as True and maskColor as colors.White, I did not get it working. Can you supply an example please.I modified Erel's code to fit my needs, this code works fine for me, removing the background completely, it only works for B4A, I still have not gotten a perfect solution for B4i.
Selfie Segmenter:'v1.01 Sub Class_Globals Type SegmentationResult (Success As Boolean, ForegroundBitmap As B4XBitmap, ForegroundMask As B4XBitmap) Private segmenter As JavaObject Private xui As XUI End Sub Public Sub Initialize Dim options As JavaObject options.InitializeNewInstance("com.google.mlkit.vision.segmentation.subject.SubjectSegmenterOptions.Builder", Null) options = options.RunMethodJO("enableForegroundBitmap", Null).RunMethodJO("enableForegroundConfidenceMask", Null).RunMethod("build", Null) Dim SubjectSegmentation As JavaObject SubjectSegmentation.InitializeStatic("com.google.mlkit.vision.segmentation.subject.SubjectSegmentation") segmenter = SubjectSegmentation.RunMethod("getClient", Array(options)) End Sub Private Sub CreateInputImage(bmp As B4XBitmap) As Object Dim InputImage As JavaObject InputImage.InitializeStatic("com.google.mlkit.vision.common.InputImage") Return InputImage.RunMethod("fromBitmap", Array(bmp, 0)) End Sub Public Sub Process (bmp As B4XBitmap, getForeGroundMask As Boolean, maskColor As Int) As ResumableSub Dim image As JavaObject = CreateInputImage(bmp) Dim width, height As Int width = image.RunMethod("getWidth", Null) height = image.RunMethod("getHeight", Null) Dim colores(width & height) As Int Dim task As JavaObject = segmenter.RunMethod("process", Array(image)) Do While task.RunMethod("isComplete", Null).As(Boolean) = False Sleep(50) Loop Dim res As SegmentationResult res.Initialize If task.RunMethod("isSuccessful", Null) Then res.Success = True Dim SubjectSegmentationResult As JavaObject = task.RunMethod("getResult", Null) res.ForegroundBitmap = SubjectSegmentationResult.RunMethod("getForegroundBitmap", Null) If getForeGroundMask Then Dim ForegroundMask As JavaObject ForegroundMask = SubjectSegmentationResult.RunMethod("getForegroundConfidenceMask", Null) Dim bitmapMask As BitmapCreator bitmapMask.Initialize(width, height) For i = 0 To (width * height) - 1 If (ForegroundMask.RunMethod("get", Null)) > 0.5 Then colores(i) = maskColor Else colores(i) = xui.Color_White End If Next Dim bmpx As JavaObject Dim foregroundBitmap As B4XBitmap bmpx = bmpx.InitializeStatic("android.graphics.Bitmap") Dim config As JavaObject config = config.InitializeStatic("android.graphics.Bitmap.Config") bmpx = bmpx.RunMethodJO("createBitmap", Array(colores, width, height, config.GetField("ARGB_8888"))) foregroundBitmap = bmpx res.ForegroundMask = foregroundBitmap End If End If Return res End Sub
The changes were made in the Sub Process function, I added a few parameters to retrieve either the Mask or the foregound bitmap and also in the Initialize Sub to enable the foreground confidence mask.
B4X:Public Sub Initialize Dim options As JavaObject options.InitializeNewInstance("com.google.mlkit.vision.segmentation.subject.SubjectSegmenterOptions.Builder", Null) options = options.RunMethodJO("enableForegroundBitmap", Null).RunMethodJO("enableForegroundConfidenceMask", Null).RunMethod("build", Null) Dim SubjectSegmentation As JavaObject SubjectSegmentation.InitializeStatic("com.google.mlkit.vision.segmentation.subject.SubjectSegmentation") segmenter = SubjectSegmentation.RunMethod("getClient", Array(options)) End Sub
Hope this is what you are looking for, let me know if this works for you.
Walter
Try getForeGroundMask to False if you want to remove the background, set to True only if you want to retrieve the Mask.After replacing the code you recommended and using getForeGroundMask as True and maskColor as colors.White, I did not get it working. Can you supply an example please.
Thanks. This code does not work:Try getForeGroundMask to False if you want to remove the background, set to True only if you want to retrieve the Mask.
Dim cc As ContentChooser
cc.Initialize("cc")
cc.Show("image/*", "choose image")
Wait For cc_Result (Success As Boolean, Dir As String, FileName As String)
If Success Then
'I'm resizing the image here. It might be better to leave the image with the original resolution.
Dim bmp As B4XBitmap = xui.LoadBitmapResize(Dir, FileName, B4XImageView1.mBase.Width, B4XImageView1.mBase.Height, True)
B4XImageView1.Bitmap = bmp
B4XImageView2.Clear
Wait For (segmenter.Process(bmp, True, Colors.White)) Complete (Result As SegmentationResult)
If Result.Success Then
B4XImageView2.Bitmap = Result.ForegroundBitmap
End If
End If
Try it like this, setting getForegroundMask to FalseThanks. This code does not work:
Result.Success is always FalseB4X:Dim cc As ContentChooser cc.Initialize("cc") cc.Show("image/*", "choose image") Wait For cc_Result (Success As Boolean, Dir As String, FileName As String) If Success Then 'I'm resizing the image here. It might be better to leave the image with the original resolution. Dim bmp As B4XBitmap = xui.LoadBitmapResize(Dir, FileName, B4XImageView1.mBase.Width, B4XImageView1.mBase.Height, True) B4XImageView1.Bitmap = bmp B4XImageView2.Clear Wait For (segmenter.Process(bmp, True, Colors.White)) Complete (Result As SegmentationResult) If Result.Success Then B4XImageView2.Bitmap = Result.ForegroundBitmap End If End If
Dim cc As ContentChooser
cc.Initialize("cc")
cc.Show("image/*", "choose image")
Wait For cc_Result (Success As Boolean, Dir As String, FileName As String)
If Success Then
'I'm resizing the image here. It might be better to leave the image with the original resolution.
Dim bmp As B4XBitmap = xui.LoadBitmapResize(Dir, FileName, B4XImageView1.mBase.Width, B4XImageView1.mBase.Height, True)
B4XImageView1.Bitmap = bmp
B4XImageView2.Clear
Wait For (segmenter.Process(bmp, False, Colors.White)) Complete (Result As SegmentationResult)
If Result.Success Then
B4XImageView2.Bitmap = Result.ForegroundBitmap
End If
End If