B4A Class CamEx class with Face Tracking and more error handling

Discussion in 'Additional libraries, classes and official updates' started by NeoTechni, Jul 20, 2017.

  1. NeoTechni

    NeoTechni Well-Known Member Licensed User

    So the basics of this variant of the CamEx class is I added some error handling, so that subs called before the camera is ready won't crash the program. And you can be sure you're actually getting data by checking CamEx.CameraIsReady.

    CommitParameters is called automatically in a few places, and the Panel is made visible automatically to prevent some annoying bug hunts I ran into.

    I merged some really helpful stuff like PreviewImageToJpeg, PreviewImageToBMP, and BytesToBmp (converts preview bytes directly to a BMP without writing to a file)

    But the biggest feature is the Face Detection. We've had the functions before, but Android uses a (deliberately?) obfuscated coordinate system that:
    -is not what the documentation claims (-1000 to 1000)
    -varies wildly between different devices (Xperia devices start at 0 instead of -1000)
    -varies wildly between different orientations (you can't even apply simple math to rotate it yourself)

    So I came up with a method that automatically calibrates the coordinate system, and saves it to to the Android folder (so every program using this code can use the same settings file) only when the data is changed, when you shut the camera down.

    Basically, all the user has to do is move their face into each of the 4 corners, for each of the device's orientations. This step isn't required as it'll naturally calibrate over time, but this speeds up the process.

    I don't have access to the eye/mouth coordinates yet, as Google's documentation on that is also wrong.

    The usage is roughly the same as the existing CamEx class.

    Code:
    Sub camera_Ready (Success As Boolean)
       
    Log("CAMERA IS " & IIF(Success, "READY""NOT READY"))
       
    If Success Then
         
    Log("ACLpanel: " & ACLpanel.Visible & " @ " & ACLpanel.Top & "," & ACLpanel.Left & " - " & ACLpanel.Width & "x" & ACLpanel.Height)
         
    If camEx.IsInitialized Then
           
    Try
             camEx.StartPreview
             camEx.StartFaceDetection 
    'This will start face detection, if it's supported
             'If Graphics.ColorEffect.Length>0 Then camEx.SetColorEffect2(Graphics.ColorEffect)
           Catch
             camera_Ready(
    False)
           
    End Try
         
    End If
       
    End If
    End Sub

    Sub camera_FaceDetected(Face As Face)
       
    Log("FACE: X=" & Face.Location.Left & ", Y=" & Face.Location.Top & ", W=" & Face.Location.Width & ", H=" & Face.Location.Height)
    End Sub

    'picwidth/height is the size of the image itself (src, before)
    'thumbwidth/height is the desired/maximum dimensions (dest, after)
    'forcefit expands smaller images to fit picwidth/height while retaining the aspect ratio (ie: letterboxing/pillarboxing)
    'forcefull expands smaller images to fill the entire picwidth/height leaving no border, destroying the aspect ratio
    Sub Thumbsize(PicWidth As Int, PicHeight As Int, thumbwidth As Int, thumbheight As Int, ForceFit As Boolean, ForceFull As Boolean)As Point
       
    Dim Temp As Point
       Temp.X=PicWidth
       Temp.Y=PicHeight
      
    If ForceFit Then
      
    If Temp.Y < thumbheight Then
      Temp.X = Temp.X * thumbheight / Temp.Y
      Temp.Y = thumbheight
      
    End If
      
    End If
      
    If Temp.X > thumbwidth Then
      Temp.Y = Temp.Y / (Temp.X / thumbwidth)
      Temp.X = thumbwidth
      
    End If
      
    If Temp.Y > thumbheight Then
      Temp.X = Temp.X / (Temp.Y / thumbheight)
      Temp.Y = Temp.Y / (Temp.Y / thumbheight)
      
    End If
      
    If ForceFull Then
      
    If Temp.X < thumbwidth Then
      Temp.Y = Temp.Y * (thumbwidth / Temp.X)
      Temp.X = thumbwidth
      
    End If
      
    If Temp.Y < thumbheight Then
      Temp.X = Temp.X * (thumbheight / Temp.Y)
      Temp.Y = Temp.Y * (thumbheight / Temp.Y)
      
    End If
      
    End If
       
    Return Temp
    End Sub


    Sub IIF(Value As Boolean , IFtrue, IfFalse)
       
    If Value Then Return IFtrue
       
    Return IfFalse
    End Sub
    EDIT: Points removed
     

    Attached Files:

    Last edited: Jul 25, 2017
  2. yiankos1

    yiankos1 Active Member Licensed User

    Good morning my friend,
    Uknown type: point.
    What library should i use?
     
  3. DonManfred

    DonManfred Expert Licensed User

  4. yiankos1

    yiankos1 Active Member Licensed User

  5. DonManfred

    DonManfred Expert Licensed User

    then you should know which library is needed. See the name of the html of the documentationpage.... The html name is the library where the point is part of.
     
  6. NeoTechni

    NeoTechni Well-Known Member Licensed User

    Sorry

    Type point(x as int, y as int)
     
    DonManfred likes this.
  7. DonManfred

    DonManfred Expert Licensed User

    You should update #1 and enter this information. The custom Type should be declared in the Main module.
     
  8. NeoTechni

    NeoTechni Well-Known Member Licensed User

    Will do once I get home
     
  9. DonManfred

    DonManfred Expert Licensed User

    It was not your fault. Even not mine ;)
    The solution is to add the following line to your MAIN module.
    Code:
    Type point(x as int, y as int)
     
    yiankos1 likes this.
  10. NeoTechni

    NeoTechni Well-Known Member Licensed User

    The variables have been commented out since I don't have the data yet anyway
     
  11. Rusty

    Rusty Well-Known Member Licensed User

    Where is the API.IIF defined?
    Thanks,
    Rusty
     
  12. DonManfred

    DonManfred Expert Licensed User

    Code:
    Sub IIF(c As boolean, TrueRes As String, FalseRes As String)
      
    If c Then Return TrueRes Else Return FalseRes
    End Sub
     
  13. Rusty

    Rusty Well-Known Member Licensed User

    Thanks Don,
    In the above code CamEx with face detection, the code snippet includes API.IIF and API.Thumbsize.
    I was trying to find NeoTechni's code so I could test the face detection.
    Since others have been using this code, I figured I'd missed a library/module somewhere.
    Do you know where he was "linking" these?
    Rusty
     
  14. DonManfred

    DonManfred Expert Licensed User

    not really. i guess "Api" is a code module from the TO and IFF a method inside this Module.

    I found the IFF sub in the forum. Erel posted it somewhere.
     
    JordiCP likes this.
  15. NeoTechni

    NeoTechni Well-Known Member Licensed User

    Odd, I'm not finding it referenced in the class. Nothing shows up when I search for it in B4A, or when I copy/paste the whole file into Notepad and use it to search. What line is it on?
     
  16. DonManfred

    DonManfred Expert Licensed User

     
  17. NeoTechni

    NeoTechni Well-Known Member Licensed User

    Oh. The usage code not the class.... Dang. Thank you again.
     
  18. Rusty

    Rusty Well-Known Member Licensed User

    Neo,
    Also upload_2017-7-24_20-39-0.png
    the Thumbsize is in the PreviewImagetoBMP
    Regards,
    Rusty
     
  19. NeoTechni

    NeoTechni Well-Known Member Licensed User

    ARG!

    Added to the top post. Thank you again.
     
    lemonisdead, Rusty and DonManfred like this.
  20. Beimer Osorio

    Beimer Osorio New Member Licensed User



    Where do I have to type
    Code:
    Type point(x as int, y as int)
    in main module?
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice