B4J Code Snippet Detect faces with OpenCV (JavaObject)



Hello everyone, I made a basic example of how to use OpenCV with javaobject and detect people's faces.

The example detects faces and adds a green square around them.


This same example can be changed to detect entire bodies, cats, license plates, etc.

just download the desired .xml.

I am using in this example the
haarcascade_frontalface_default.xml


Download
 
Thanks for the code. I am getting
Compiling generated Java code. Error
Cannot find: C:\Program Files\Anywhere Software\B4J\libraries\opencv-490.jar
Where to get the opencv-490.jar ? I didn't find it on the forum.
 

Douglas Farias

Expert
Licensed User
Longtime User
Thanks for the code. I am getting

Where to get the opencv-490.jar ? I didn't find it on the forum.
Hi, i have uploaded it on the same link (google drive)

or u can download it here too
 
Hi, i have uploaded it on the same link (google drive)

or u can download it here too
Thank you for the link. I have included opencv but I am getting this error while compiling :
Waiting for debugger to connect...
Program started.
OpenCV library loaded successfully.
Error occurred on line: 47 (B4XMainPage)
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.keywords.Common.CallSubDebug2(Common.java:486)
at b4j.example.b4xpagesmanager._createpageifneeded(b4xpagesmanager.java:872)
at b4j.example.b4xpagesmanager._showpage(b4xpagesmanager.java:351)
at b4j.example.b4xpagesmanager._addpage(b4xpagesmanager.java:172)
at b4j.example.b4xpagesmanager._addpageandcreate(b4xpagesmanager.java:186)
at b4j.example.b4xpagesmanager._initialize(b4xpagesmanager.java:122)
at b4j.example.main._appstart(main.java:80)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
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 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
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 com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:748)
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)
... 35 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:115)
... 36 more
Caused by: java.lang.UnsupportedClassVersionError: org/opencv/core/Mat has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at anywheresoftware.b4j.object.JavaObject.getCorrectClassName(JavaObject.java:274)
at anywheresoftware.b4j.object.JavaObject.InitializeNewInstance(JavaObject.java:84)
at b4j.example.b4xmainpage._detectfaces(b4xmainpage.java:143)
at b4j.example.b4xmainpage._initializeopencv(b4xmainpage.java:88)
at b4j.example.b4xmainpage._b4xpage_created(b4xmainpage.java:59)
... 41 more
 

Douglas Farias

Expert
Licensed User
Longtime User
Hello! Nice work @Douglas Farias !
Is it possible to save a face as an id?
Hi.
u can change the DetectFaces sub.
in this example i save the face into a map with a id for each face and save a image cropped with the face.

B4X:
Sub DetectFaces
    ' Save the image from Canvas to disk
    Dim Out As OutputStream = File.OpenOutput(File.DirApp, "1.jpg", False)
    canvas.Snapshot.WriteToStream(Out)
    Out.Close

    ' Load the image
    Dim imgs As JavaObject
    imgs.InitializeNewInstance("org.opencv.core.Mat", Null)
    Dim imgcodecs As JavaObject
    imgcodecs.InitializeStatic("org.opencv.imgcodecs.Imgcodecs")
    imgs = imgcodecs.RunMethod("imread", Array(File.Combine(File.DirApp, "1.jpg")))

    ' Check if the image was loaded correctly
    If imgs.RunMethod("empty", Null) Then
        Log("Image not loaded.")
        Return
    End If

    ' Load face classifier
    Dim faceCascade As JavaObject
    Dim xmlPath As String = File.Combine(File.DirApp, "haarcascade_frontalface_default.xml")
    faceCascade.InitializeNewInstance("org.opencv.objdetect.CascadeClassifier", Null)
    faceCascade.RunMethod("load", Array(xmlPath))

    ' Detect faces
    Dim faceDetections As JavaObject
    faceDetections.InitializeNewInstance("org.opencv.core.MatOfRect", Null)
    faceCascade.RunMethod("detectMultiScale", Array(imgs, faceDetections))

    ' Process detections and draw rectangles
    Private facesDetected As Map : facesDetected.Initialize
    Dim facesArray() As Object = faceDetections.RunMethod("toArray", Null)
    Dim count As Int = 0
    For Each face As JavaObject In facesArray
        count = count + 1
        Log("Face detected at: x=" & face.GetField("x") & " y=" & face.GetField("y") & " width=" & face.GetField("width") & " height=" & face.GetField("height"))
        canvas.DrawRect(face.GetField("x"), face.GetField("y"), face.GetField("width"), face.GetField("height"), fx.Colors.Green, False, 2)
      
        Private faceId As String = $"people${canvas.Tag}Face${count}"$
        facesDetected.Put(faceId, CreateMap("x": face.GetField("x"), "y": face.GetField("y"), "width": face.GetField("width"), "height": face.GetField("height")))
        Log(faceId)

        ' Crop and save face
        Dim x As Int = face.GetField("x")
        Dim y As Int = face.GetField("y")
        Dim width As Int = face.GetField("width")
        Dim height As Int = face.GetField("height")
        Dim faceMat As JavaObject = imgs.RunMethod("submat", Array(y, y + height, x, x + width))
        Dim faceImgCodecs As JavaObject
        faceImgCodecs.InitializeStatic("org.opencv.imgcodecs.Imgcodecs")
        Dim faceFileName As String = File.Combine(File.DirApp, faceId & ".jpg")
        faceImgCodecs.RunMethod("imwrite", Array(faceFileName, faceMat))
    Next
    Log("Total faces detected: " & facesArray.Length)
    'Log(facesDetected)
End Sub
 

aaronk

Well-Known Member
Licensed User
Longtime User
It would be good to detect the face in the image, and then compare the faces (like face matching / Face Comparison) and if it's more than 80% match then make it do something in B4J.
 

Douglas Farias

Expert
Licensed User
Longtime User
It would be good to detect the face in the image, and then compare the faces (like face matching / Face Comparison) and if it's more than 80% match then make it do something in B4J.
This is possible, but it would require more work with JavaCV and Dlib.

I'll try to set aside some time and look into this over the next few weeks.
 
Top