Wish FaceDetectionListener callback for the camera

JordiCP

Expert
Licensed User
Longtime User
It would be very nice to be able to set a FaceDetectionListener Callback for the camera (when supported)

The Android Facedetector works ok, but IMO is very slow and needs previous conversion of the frames to a bitmap.

The B4A camera library is very complete and through reflection we have access to even more parameters, but can't see the way to set up a new callback (except the ones already supported: _ready, _preview, _picturetaken...)

As it is only supported from API14, I understand compatibility issues, but it could be done by adding a "isFaceDetectionSupported()" function which returns false if API<14 or the camera itself does not support it
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Here:
1. Add this code to CameraEx:
B4X:
Public Sub SetFaceDetectionListener
   Dim jo As JavaObject = nativeCam
   Dim e As Object = jo.CreateEvent("android.hardware.Camera.FaceDetectionListener", "FaceDetection", Null)
   jo.RunMethod("setFaceDetectionListener", Array(e))
End Sub

Private Sub FaceDetection_Event (MethodName As String, Args() As Object) As Object
   Dim faces() As Object = Args(0)
   For Each f As Object In faces
     Dim jo As JavaObject = f
     Dim faceRect As Rect = jo.GetField("rect")
     Log(faceRect)
   Next
   Return Null
End Sub

Public Sub StartFaceDetection
   Dim jo As JavaObject = nativeCam
   jo.RunMethod("startFaceDetection", Null)
End Sub

Public Sub StopFaceDetection
   Dim jo As JavaObject = nativeCam
   jo.RunMethod("stopFaceDetection", Null)
End Sub
2. You need to call SetFaceDetectionListener when your app starts and StartFaceDetection after the preview is started:
B4X:
Sub Camera1_Ready (Success As Boolean)
   If Success Then
     camEx.SetJpegQuality(90)
     camEx.ExposureCompensation = camEx.MaxExposureCompensation
     camEx.SetFaceDetectionListener
     camEx.CommitParameters
     camEx.StartPreview
     camEx.StartFaceDetection
   Else
     ToastMessageShow("Cannot open camera.", True)
   End If
End Sub

See the documentation of Face.rect: http://developer.android.com/reference/android/hardware/Camera.Face.html
 

gmh

New Member
Licensed User
Longtime User
Thanks, this has been really helpful.

Question 1: I’m looking to display the rectangle around the face and I’m not quite sure how to superimpose it on the preview. Using the above code, I am able to identify the co-ordinates. Any pointers on overlaying a rectangle greatly appreciated.

Question 2: I’ve tried to identify the co-ordinates for eyes and mouth. However there doesn’t seem to be a type for ‘Point’. I’ve try using the code below without success. Again any pointers (no pun intended) also greatly appreciated.

B4X:
Private Sub FaceDetection_Event (MethodName As String, Args() As Object) As Object
   Dim faces() As Object = Args(0)
   For Each f As Object In faces
     Dim jo As JavaObject
     jo = f
    
     Dim faceRect As Rect
     faceRect = jo.GetField("rect")
     Log("faceRect "&faceRect.Top&" "&faceRect.Left)  'works as expected
    
     Dim Score As Int
     Score = jo.GetField("score")
     Log("left "&Score) ' works as expected
    
     Dim p As JavaObject
     p.InitializeNewInstance("android.graphics.PointF", Null)
     p = jo.GetField("leftEye")
     Log("Point "&p.GetField("x") & " , "&p.GetField("y") ) 'Gets  java.lang.RuntimeException: Object should first be initialized (JavaObject).
  
   Next
   Return Null
End Sub

Many thanks

Geoff
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
The coordinates are explained here: http://developer.android.com/reference/android/hardware/Camera.Face.html

Start in landscape orientation with the rear camera.

Remove this line: p.InitializeNewInstance("android.graphics.PointF", Null)
You are creating a new point and you never use its value.

You should check the value of p.IsInitialized before you use it. As you can see in the documentation it may be null.
 

Elton Leung

Member
Licensed User
Longtime User
Thanks, this has been really helpful.

Question 1: I’m looking to display the rectangle around the face and I’m not quite sure how to superimpose it on the preview. Using the above code, I am able to identify the co-ordinates. Any pointers on overlaying a rectangle greatly appreciated.

Question 2: I’ve tried to identify the co-ordinates for eyes and mouth. However there doesn’t seem to be a type for ‘Point’. I’ve try using the code below without success. Again any pointers (no pun intended) also greatly appreciated.

B4X:
Private Sub FaceDetection_Event (MethodName As String, Args() As Object) As Object
   Dim faces() As Object = Args(0)
   For Each f As Object In faces
     Dim jo As JavaObject
     jo = f
   
     Dim faceRect As Rect
     faceRect = jo.GetField("rect")
     Log("faceRect "&faceRect.Top&" "&faceRect.Left)  'works as expected
   
     Dim Score As Int
     Score = jo.GetField("score")
     Log("left "&Score) ' works as expected
   
     Dim p As JavaObject
     p.InitializeNewInstance("android.graphics.PointF", Null)
     p = jo.GetField("leftEye")
     Log("Point "&p.GetField("x") & " , "&p.GetField("y") ) 'Gets  java.lang.RuntimeException: Object should first be initialized (JavaObject).
 
   Next
   Return Null
End Sub

Many thanks

Geoff

Hi Geoff

Have you get the rectangle and eyes coordinates to work? Mind to show me how?

Elton
 

sasidhar

Active Member
Licensed User
Longtime User
Here:
1. Add this code to CameraEx:
B4X:
Public Sub SetFaceDetectionListener
   Dim jo As JavaObject = nativeCam
   Dim e As Object = jo.CreateEvent("android.hardware.Camera.FaceDetectionListener", "FaceDetection", Null)
   jo.RunMethod("setFaceDetectionListener", Array(e))
End Sub

Private Sub FaceDetection_Event (MethodName As String, Args() As Object) As Object
   Dim faces() As Object = Args(0)
   For Each f As Object In faces
     Dim jo As JavaObject = f
     Dim faceRect As Rect = jo.GetField("rect")
     Log(faceRect)
   Next
   Return Null
End Sub

Public Sub StartFaceDetection
   Dim jo As JavaObject = nativeCam
   jo.RunMethod("startFaceDetection", Null)
End Sub

Public Sub StopFaceDetection
   Dim jo As JavaObject = nativeCam
   jo.RunMethod("stopFaceDetection", Null)
End Sub
2. You need to call SetFaceDetectionListener when your app starts and StartFaceDetection after the preview is started:
B4X:
Sub Camera1_Ready (Success As Boolean)
   If Success Then
     camEx.SetJpegQuality(90)
     camEx.ExposureCompensation = camEx.MaxExposureCompensation
     camEx.SetFaceDetectionListener
     camEx.CommitParameters
     camEx.StartPreview
     camEx.StartFaceDetection
   Else
     ToastMessageShow("Cannot open camera.", True)
   End If
End Sub

See the documentation of Face.rect: http://developer.android.com/reference/android/hardware/Camera.Face.html


Hi Erel,

I am getting error with JavaObject says createEvent does not exist.

also in cameraEx class camEx.ExposureCompensation = camEx.MaxExposureCompensation does not exist.
can you please guide me.

thanks
sasidhar
 

sasidhar

Active Member
Licensed User
Longtime User
hi JavaObject issue resolve after updating to latest version,

Error at
camEx.ExposureCompensation = camEx.MaxExposureCompensation error no member
camEx.SetFaceDetectionListener error "="

please share some sample project if anyone has.

thanks
sasidhar
 

sasidhar

Active Member
Licensed User
Longtime User
Please find the attached code and error facing. need more details on this library usage.
 

Attachments

  • 1.jpg
    1.jpg
    240.7 KB · Views: 348
  • Camera.zip
    11.7 KB · Views: 328

sasidhar

Active Member
Licensed User
Longtime User
I removed that still the same error coming. Is there any sample project to understand in detail.

Parsing code. 0.01
Compiling code. Error
Error compiling program.
Error description: 'as' expected.
Occurred on line: 286
jo.RunMethod("setFaceDetectionListener", Array(e))
Word: (
 

sasidhar

Active Member
Licensed User
Longtime User
Hi erel,

as mentioned changes done, compiled properly,

but error during facedetection_event



LogCat connected to: B4A-Bridge: LGE Nexus 5
--------- beginning of main
Connected to B4A-Bridge (Bluetooth)
sending message to waiting queue (CallSubDelayed - UpdateStatus)
Connected to B4A-Bridge (Bluetooth)
sending message to waiting queue (CallSubDelayed - UpdateStatus)
Installing file.
Installing file.
Installing file.
PackageAdded: package:anywheresoftware.b4a.samples.camera
** Activity (main) Create, isFirst = true **
(Main, 22) FullScreen or IncludeTitle properties in layout file do not match the activity attributes settings. (warning #1004)
** Activity (main) Resume **
90
cameraexclass_facedetection_event (B4A line: 291)
Dim faces() As Object = Args(0)
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
at anywheresoftware.b4a.samples.camera.cameraexclass._facedetection_event(cameraexclass.java:275)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:173)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:157)
at anywheresoftware.b4j.object.JavaObject$1.invoke(JavaObject.java:191)
at java.lang.reflect.Proxy.invoke(Proxy.java:393)
at $Proxy0.toString(Unknown Source)
at java.lang.String.valueOf(String.java:1258)
at anywheresoftware.b4a.BA.ObjectToNumber(BA.java:585)
at anywheresoftware.b4a.samples.camera.cameraexclass._setfacedetectionlistener(cameraexclass.java:1046)
at anywheresoftware.b4a.samples.camera.main._camera1_ready(main.java:599)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:173)
at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:858)
at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:815)
at anywheresoftware.b4a.samples.camera.cameraexclass._camera_ready(cameraexclass.java:167)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:173)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:157)
at anywheresoftware.b4a.objects.CameraW$2$1.run(CameraW.java:139)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
90
cameraexclass_facedetection_event (B4A line: 291)
Dim faces() As Object = Args(0)
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
at anywheresoftware.b4a.samples.camera.cameraexclass._facedetection_event(cameraexclass.java:275)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:173)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:157)
at anywheresoftware.b4j.object.JavaObject$1.invoke(JavaObject.java:191)
at java.lang.reflect.Proxy.invoke(Proxy.java:393)
at $Proxy0.toString(Unknown Source)
at java.lang.String.valueOf(String.java:1258)
at anywheresoftware.b4a.BA.ObjectToNumber(BA.java:585)
at anywheresoftware.b4a.samples.camera.cameraexclass._setfacedetectionlistener(cameraexclass.java:1046)
at anywheresoftware.b4a.samples.camera.main._camera1_ready(main.java:599)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:173)
at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:858)
at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:815)
at anywheresoftware.b4a.samples.camera.cameraexclass._camera_ready(cameraexclass.java:167)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:173)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:157)
at anywheresoftware.b4a.objects.CameraW$2$1.run(CameraW.java:139)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
** Activity (main) Pause, UserClosed = false **
Installing file.
PackageAdded: package:anywheresoftware.b4a.samples.camera
 

Leni Berry

Active Member
Licensed User
Longtime User
The coordinates are explained here: http://developer.android.com/reference/android/hardware/Camera.Face.html

Start in landscape orientation with the rear camera.

Remove this line: p.InitializeNewInstance("android.graphics.PointF", Null)
You are creating a new point and you never use its value.

You should check the value of p.IsInitialized before you use it. As you can see in the documentation it may be null.

dear erel
how to get lefteye, righteye and mouth coordinate with similiar code like this :
B4X:
Dim Score As Int
     Score = jo.GetField("score")
     Log("left "&Score) ' works as expected
it 's really dificult because field in point.
 

NeoTechni

Well-Known Member
Licensed User
Longtime User
B4X:
Dim mouth As JavaObject = jo.GetField("mouth")
Log(mouth.GetField("x"))
Log(mouth.GetField("y"))

Doesn't work. I get:

java.lang.RuntimeException: Object should first be initialized (JavaObject).
at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:50)
at anywheresoftware.b4j.object.JavaObject.getCurrentClass(JavaObject.java:258)
at anywheresoftware.b4j.object.JavaObject.GetField(JavaObject.java:180)
at com.omnicorp.scifiui.cameraexclass._facedetection_event(cameraexclass.java:372)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:186)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:166)
at anywheresoftware.b4j.object.JavaObject$1.invoke(JavaObject.java:237)
at java.lang.reflect.Proxy.invoke(Proxy.java:393)
at $Proxy0.onFaceDetection(Unknown Source)
at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1139)
at android.os.Handler.dispatchMessage(Handler.java:102)
at anywheresoftware.b4a.Msgbox.waitForMessage(Msgbox.java:227)
at anywheresoftware.b4a.Msgbox.msgbox(Msgbox.java:166)
at anywheresoftware.b4a.BA.ShowErrorMsgbox(BA.java:260)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:224)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:166)
at anywheresoftware.b4j.object.JavaObject$1.invoke(JavaObject.java:237)
at java.lang.reflect.Proxy.invoke(Proxy.java:393)
at $Proxy0.onFaceDetection(Unknown Source)
at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1139)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
 
Top