B4J Question 1st PyBridge try: alfa-test

peacemaker

Expert
Licensed User
Longtime User
Hi, All and @Erel ,

Just tried for the first time your PyBridge draft. B4J 10.0
Compiling at line:
Dim correctClassesNames As Map = jo.InitializeStatic("anywheresoftware.b4a.randomaccessfile.RandomAccessFile").GetField("correctedClasses")
gives the error:
Waiting for debugger to connect...
Program started.
Error occurred on line: 18 (PyComm)
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at anywheresoftware.b4a.keywords.Common.CallSubDebug2(Common.java:486)
at b4j.example.b4xpagesmanager._createpageifneeded(b4xpagesmanager.java:875)
at b4j.example.b4xpagesmanager._showpage(b4xpagesmanager.java:354)
at b4j.example.b4xpagesmanager._addpage(b4xpagesmanager.java:175)
at b4j.example.b4xpagesmanager._addpageandcreate(b4xpagesmanager.java:189)
at b4j.example.b4xpagesmanager._initialize(b4xpagesmanager.java:125)
at b4j.example.main._appstart(main.java:85)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:629)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:237)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:111)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:100)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:98)
at b4j.example.main.start(main.java:38)
at javafx.graphics@19.0.2.1/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847)
at javafx.graphics@19.0.2.1/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
at javafx.graphics@19.0.2.1/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics@19.0.2.1/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
at javafx.graphics@19.0.2.1/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics@19.0.2.1/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics@19.0.2.1/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:134)
at anywheresoftware.b4a.debug.Debug.CallSubNew2(Debug.java:81)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
... 28 more
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:115)
... 30 more
Caused by: java.lang.RuntimeException: Field: correctedClasses not found in: anywheresoftware.b4a.randomaccessfile.RandomAccessFile
at anywheresoftware.b4j.object.JavaObject$FieldCache.getField(JavaObject.java:307)
at anywheresoftware.b4j.object.JavaObject.GetField(JavaObject.java:182)
at b4j.example.pycomm._initialize(pycomm.java:108)
at b4j.example.pybridge._start(pybridge.java:181)
at b4j.example.b4xmainpage$ResumableSub_B4XPage_Created.resume(b4xmainpage.java:130)
at b4j.example.b4xmainpage._b4xpage_created(b4xmainpage.java:84)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
... 32 more
Just alfa-test...
Any updates in jRandomAccessFile lib?
 

Attachments

  • TempDownload.png
    TempDownload.png
    17.8 KB · Views: 155
Last edited:

Magma

Expert
Licensed User
Longtime User
yes.. was the AV/IS...
1738257497358.png


Nice !

It will be better - if had support for my AMD RADEON 7970... it has many bit Proccessor...

---

I am having thoughts...
why we are not having yet our libs for B4X (and we need bridges) - i know python has many examples for AI...
but how difficult is to have the logic..
(this is for other thread - sure)

---

Is it really "better" to run locally AI services or using CLOUD... (???) - ofcourse having cost... but from the other cost of your pc-parts, temperature, cpu freezing ?
(this is for other thread - sure)
 
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
For this PyBridge it's needed one-time open-dialog setting for "Choose the path to python.exe".
And maybe better - some PyBridgeView or PyBridgeTemplate, where all settings together:

  • button for downloading Python, and instructions for installation
  • open-dialog setting for "Choose the path to python.exe"
It will be used in any project related to py.

 
Last edited:
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Nice.

Plus its using CUDA

WARNING: package com.sun.javafx.embed.swing.oldimpl not in javafx.swing
Waiting for debugger to connect...
Program started.
(b4j) Server is listening on port: 63674
Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events.
(out) starting PyBridge v0.1
watchdog set to 60 seconds
Connecting to port: 63674
(b4j) connected
 

Attachments

  • ocrTest.png
    ocrTest.png
    424.8 KB · Views: 109
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
For this PyBridge it's needed one-time open-dialog setting for "Choose the path to python.exe".
And maybe better - some PyBridgeView or PyBridgeTemplate, where all settings together:

  • button for downloading Python, and instructions for installation
  • open-dialog setting for "Choose the path to python.exe"
It will be used in any project related to py.

I just use (because its at the top of Main and easy to find)
#VirtualMachineArgs: -DPythonPath=d:/python.3.12/python.exe

and changed this line to use it
Py.Start(Py.CreateOptions(GetSystemProperty("PythonPath","")))
 
Upvote 0

tchart

Well-Known Member
Licensed User
Longtime User
Probably expected but I noticed easyocr will work fine with small images (640x480) but fails on larger images (6400x4800). It throws a memory error. So expect to use lots of memory or resize your images.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
I have it working ok on 3000 x 2200 images
 
Upvote 0

tchart

Well-Known Member
Licensed User
Longtime User
I have it working ok on 3000 x 2200 images
How much memory does your Python process use? For me it’s uses around 800mb for small images. The large image it requested 12gb but the virtual machine only had 4gb. I realise that’s small but I’m merely pointing out that it can consume a lot of memory. I’m not saying it doesn’t work.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Python was using about 680MB, the GPU was using 5.1GB of its memory.

(Python 3.12.8)
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Don't focus too much on EasyOCR. It is just a simple test that I made.

why we are not having yet our libs for B4X (and we need bridges) - i know python has many examples for AI...
This is a valid question and the answer is no. Java is way behind Python in this field and B4J can only run Java code directly. Just running something on the GPU with Java is a complete mess, and here with Torch you can do it very easily.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Quite easy to get B4J to use keras now
B4X:
public Sub Keras
    Dim Code As String=$"
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
import tensorflow
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Input


def kerastest():
    print_result = ''
    try:
        # Input dataset (3 inputs)
        inputs = np.array([[1, 0, 0]], dtype=float)

        # Output dataset (1 output)
        expected_output = np.array([[1]], dtype=float)

        # Ensure the input and output data are of the correct shape
        if inputs.ndim != 2 or expected_output.ndim != 2:
            return "Input and output data must be 2-dimensional"

        print_result += f"Input data shape: {inputs.shape}, dtype: {inputs.dtype}"
        print_result += f"\nOutput data shape: {expected_output.shape}, dtype: {expected_output.dtype}"
        
        # Create the model
        model = Sequential()

        # Add the input layer using Input and the first hidden layer
        model.add(Input(shape=(3,)))
        model.add(Dense(units=3, activation='sigmoid'))

        # Add the output layer
        model.add(Dense(units=1, activation='sigmoid'))

        # Compile the model
        model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

        # Train the model
        model.fit(inputs, expected_output, epochs=750, verbose=0)

        # Make predictions
        predicted_output = model.predict(inputs)
        print_result += f"\nFinal output after training: {format(predicted_output[0][0],'.0f')}"
        return print_result

    except Exception as e:
        import traceback
        error_message = traceback.format_exc()  # Capture the traceback as a string
        return f"An error occurred:\n{error_message}"
"$
    Wait for (Py.Utils.RunCode("kerastest",Null, Code).Fetch) Complete(Result As PyWrapper)
    Log(Result.Value.As(String))

End Sub
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Run code from a .py file
B4X:
Sub runFromFile(dir As String,fname As String,method As String,params() As Object) As ResumableSub
    Dim Code As String
    Code = File.ReadString(dir,fname)
    If params=Null Then
        Wait for (Py.Utils.RunCode(method, Null, Code).Fetch) Complete(Result As PyWrapper)
    Else
        Wait for (Py.Utils.RunCode(method, params, Code).Fetch) Complete(Result As PyWrapper)
    End If    
    Return (Result.Value.As(String))
End Sub

Calling the code
B4X:
...
    wait for (GPUTest.runFromFile(File.DirAssets,"test.py","major_test",doubleArray(Array("")))) Complete (Result As Object)
    Log(Result)
    wait for (GPUTest.runFromFile(File.DirAssets,"test.py","major_test",doubleArray(Array("","test")))) Complete (Result As Object)
    Log(Result)
    wait for (GPUTest.runFromFile(File.DirAssets,"test.py","major_test",doubleArray(Array("","test","2nd Parameter")))) Complete (Result As Object)
    Log(Result)
End Sub

private Sub doubleArray(a() As Object) As Object
    Return Array(a)
End Sub

python code in file
B4X:
def test0():
    return f"This is from a function in a python script"
def test1(a):
    return f"This is from function with a param ({a})"
def test2(a,b):
    return f"This is from function with 2 param ({a}, {b})"
def major_test(a):
    switch = {
        1: lambda: test0(),
        2: lambda: test1(a[1]),
        3: lambda: test2(a[1],a[2])
    }
    res = switch.get(len(a),lambda: f"Not Found")()
    return res
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
Run code from a .py file
B4X:
Sub runFromFile(dir As String,fname As String,method As String,params() As Object) As ResumableSub
    Dim Code As String
    Code = File.ReadString(dir,fname)
    If params=Null Then
        Wait for (Py.Utils.RunCode(method, Null, Code).Fetch) Complete(Result As PyWrapper)
    Else
        Wait for (Py.Utils.RunCode(method, params, Code).Fetch) Complete(Result As PyWrapper)
    End If    
    Return (Result.Value.As(String))
End Sub

Calling the code
B4X:
...
    wait for (GPUTest.runFromFile(File.DirAssets,"test.py","major_test",doubleArray(Array("")))) Complete (Result As Object)
    Log(Result)
    wait for (GPUTest.runFromFile(File.DirAssets,"test.py","major_test",doubleArray(Array("","test")))) Complete (Result As Object)
    Log(Result)
    wait for (GPUTest.runFromFile(File.DirAssets,"test.py","major_test",doubleArray(Array("","test","2nd Parameter")))) Complete (Result As Object)
    Log(Result)
End Sub

private Sub doubleArray(a() As Object) As Object
    Return Array(a)
End Sub

python code in file
B4X:
def test0():
    return f"This is from a function in a python script"
def test1(a):
    return f"This is from function with a param ({a})"
def test2(a,b):
    return f"This is from function with 2 param ({a}, {b})"
def major_test(a):
    switch = {
        1: lambda: test0(),
        2: lambda: test1(a[1]),
        3: lambda: test2(a[1],a[2])
    }
    res = switch.get(len(a),lambda: f"Not Found")()
    return res
Well as I understand you understood the way working the whole py bridge thing... is it easy to create a thread with comments and a b4xpage with all these ?

I understand some parts but I am loosing you with the call..

Thanks in advance..
 
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
in mind? (for a real life example)

Recognition of 500 objects in the database of the same size, but with small irregular ids on the surface:
1738499971097.png

1738500020215.png
Without any way of adding digital ID (like QR- or barcode).
Periodically being added new ones, and removing the existing ones :)


1738500927328.jpeg
 
Last edited:
Upvote 0

Magma

Expert
Licensed User
Longtime User
What do you have in mind? (for a real life example)
Ok can be... recognition counting persons...

I don't know exactly where keras can be used... and if it is easy

Something simple...that no need much time...
Ofcourse you must want to do that... not make you...
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
What is this?

And also what app is this and what is doing?
Industrial vagonets, and my B4J server app that tries to recognize them with help of some Python subsystem via Http API.

But the main trouble is that adding new objects, it seems, is impossible together with recognition process nonstop.
And anyway - without Py subsystem it's also impossible: i was trying to make it by pure B4J and OpenCV only, failed.
 
Last edited:
Upvote 0
Top