B4A Library OpenCV 3.x

moster67

Expert
Licensed User
Longtime User
open an avi file as by code in the list
I did not look at your code. Which codec is the video encoded in?

As far as I know, OpenCV for Android (and thus also the B4A-library) only supports MJPEG within an AVI-container. If you need to work with a video in another format/codec, you must convert it first to MJPEG.
 

JordiCP

Expert
Licensed User
Longtime User
(edit, didn't see the reply until it was too late )

Hi roberto,

Out-of-the-box OpenCV for Android build only has support for MJPEG encoded videos in .AVI container (even if the API allows so many options ... I was also surprised at the beginning). HERE you can read a bit more about it.

So I would check first if your file is MJPEG encoded.
  • If the answer is positive (i.e., your video file is already MJPEG encoded), please test your video with the attached code. It is an example that I was just preparing. You will see that there are some things slightly different that in your code ( I think the initialize2() method that you are using is not correct in my library and have to fix or remove it)
  • If not, you should convert it either externally on your PC, or internally with some transcoder (I tested not much ago @moster67 ffmpeg and it worked perfect for me)
In the future I may add internal ffmpeg support (if I find time and get how to do it), or an internal H264 encoder/decoder if I find a nice example to integrate. But it is not in my priority list since there are workarounds, and is not a limitation of my wrapper but of the standard OpenCV for Android build.

B4X:
#Region  Project Attributes
   #ApplicationLabel: OCV VideoCapture
   #VersionCode: 1
   #VersionName:
   'SupportedOrientations possible values: unspecified, landscape or portrait.
   #SupportedOrientations: landscape
   #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
   #FullScreen: False
   #IncludeTitle: True
#End Region


Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
 
   Dim t As Timer
 
   Dim VIDEO_SRC As String = "myvideo9.avi"         'Has to be MJPEG encoded.
 
End Sub

Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
   Dim ocl As OCVOpenCVLoader 
 
   Dim mCore As OCVCore
   Dim mImgProc As OCVImgproc 

   Dim MyMatBGR As OCVMat
 
   Dim mVideoCapture As OCVVideoCapture
 
   Dim myVideoCaptureMat As OCVMat
   Dim myVideoCaptureBitmap As Bitmap
 
   Dim capturing As Boolean=False
   Dim P As Panel
   Dim btnStartStop As Button
 
End Sub

Sub Activity_Create(FirstTime As Boolean)
   'Do not forget to load the layout file created with the visual designer. For example:

   ' As it is a demo, set everything to 640X480, since we know the video has that size
   P.Initialize("")
   Dim HH As Int = 80%Y
   Dim WW As Int = HH*640/480       'Keep aspect ratio for this example.
   Activity.AddView(P,(100%X-WW)/2,(100%Y-HH)/2,WW,HH)     ' Center screen

   myVideoCaptureBitmap.InitializeMutable(640,480)
   P.SetBackgroundImage(myVideoCaptureBitmap)
 
   'Control Button
   btnStartStop.Initialize("btnStartStop")
   btnStartStop.Text="Start"
   Activity.AddView(btnStartStop,20dip,20dip,80dip,40dip) 
 
   t.Initialize("t",500)
 
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)
   capturing=False
   mVideoCapture.release
   t.Enabled=False
   Activity.Finish
End Sub

Sub btnStartStop_Click
 
   If Not(capturing) Then
     InitVideoCapture
   Else
     mVideoCapture.release
     btnStartStop.text="Start"
     t.Enabled=False
     capturing=False
   End If

End Sub


Sub t_tick
   If Not(t.Enabled) Then Return     'just in case it was a pending event
   If Not(capturing) Then Return
   Log("Tick")
   If mVideoCapture.isOpened Then
     If (mVideoCapture.read(myVideoCaptureMat)) Then
     
       If Not(myVideoCaptureMat.empty) Then 'really needed? should test
     
         'From https://github.com/opencv/opencv/issues/4974
         '// get some meta data about frame.
         'double fps = capture.get(Videoio.CAP_PROP_FPS);
         'double frameCount = capture.get(Videoio.CAP_PROP_FRAME_COUNT);
         'double h = capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
         'double w = capture.get(Videoio.CAP_PROP_FRAME_WIDTH);
         'double posFrames = capture.get(Videoio.CAP_PROP_POS_FRAMES);
         'double posMsec = capture.get(Videoio.CAP_PROP_POS_MSEC);
         'double speed = capture.get(Videoio.CAP_PROP_SPEED);
     
         Log("mVideoCapture has read!" & myVideoCaptureMat.rows &" "&myVideoCaptureMat.cols)
         Dim mUtils As OCVUtils
         mUtils.matToBitmap(myVideoCaptureMat, myVideoCaptureBitmap,False)
         P.Invalidate
     
       End If
     End If
   Else 
     Log("mVideoCapture is not open")
   End If
 
End Sub


Sub InitVideoCapture
 
   mVideoCapture.Initialize1(File.Combine(File.DirRootExternal,VIDEO_SRC),0)
   If mVideoCapture.isOpened Then
     Log("VideoCapture file correctly opened")
     t.Enabled=True
     capturing=True
     btnStartStop.Text = "Stop"
   Else 
     ToastMessageShow("VideoCapture failed to open.",True)
     capturing=False
     btnStartStop.Enabled = False
   End If
 
End Sub
 

Attachments

  • VideoCapture.zip
    3.2 KB · Views: 455
Last edited:

rbghongade

Active Member
Licensed User
Longtime User
Dear JordiCP,
Can you please share the link for release 1.0?
I could not get time for playing with the beta versions. Plan to do it by this weekend.
warm regards,
 

JordiCP

Expert
Licensed User
Longtime User
BlobDetector4 example in the first post has been updated. Previous uploaded file made use of some syntax that was specific to beta versions.
 

jchal

Active Member
Licensed User
Longtime User
hi jordi
nice to hear the good news from you releasing the library.
is it possible to have a tutorial - example of a human detection or a cat detection or maybe a dog wich ever is easy ?
but with a step by step explenation so evreybody can make his own detections after the tutorial -example?
 

moster67

Expert
Licensed User
Longtime User
@JordiCP has already published some tutorials, for example:

https://www.b4x.com/android/forum/t...ction-examples-by-moster67-and-friends.80593/
https://www.b4x.com/android/forum/t...ulation-ocvmats-ocvcore-and-ocvimgproc.80577/

The first link above talks about detection and should be useful for you.

Just some personal considerations:
OpenCV is not a matter of taking some code and use it for your purposes. You should also understand the concepts and the classes at your disposal. There are many ways to obtain what you want, some ways are more optimized (faster) than others but might be less reliable.
I would suggest that B4Ausers who would like to learn more about OpenCV to study code which you can find easily by googling. There are also many books available.
Many code-examples are in C++ and Python and you should try to "translate" them into B4A - this is the best way to learn it.
 

stu14t

Active Member
Licensed User
Longtime User

Something else to consider; some of the work required to carry out cat / dog / human detection is more than just coding. You will have to learn how to teach the computer vision using HAAR / LBP / HOG cascade classifiers
 

jchal

Active Member
Licensed User
Longtime User
i tryed to run this but it tels me video capture fail to open, i am using the beta lib
 

JordiCP

Expert
Licensed User
Longtime User
You need the v1.0 lib.
The lib is too big to be uploaded. If you want to use it, just PM me with your mail address and I will send it to you.

As you didn't send me any mail address (I required it in the first post) I couldn't add you to the distribution list (since next version it will not be needed anymore, since I'll publish the link here). Now just PM'd you with the "good" one.
 

roberto64

Active Member
Licensed User
Longtime User
Hi JordiCP, I try to create some examples without getting any results, reading the opencv3.2 manual with the C ++ scripts and turning them into android no results, I try to make an example with the OCVVideoCapture class as the example below without any Now I'm getting a mistake from "The B4A Example program has been interconnected" where I'm wrong ?.
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim ocl As OCVOpenCVLoader
   
    Dim mVideoCapture As OCVVideoCapture
    Dim mFrame As OCVMat
    Dim mUtils As OCVUtils
    Dim mVio As OCVVideoio
    Dim mCasc As OCVCascadeClassifier
    Dim mImgProc As OCVImgproc
    Dim carsrect As OCVMatOfRect
    Dim graycarframe As OCVMat
    Dim mMinSize, mMaxSize As OCVSize
    Dim mRect() As OCVRect
    Dim mScalar As OCVScalar
   
   
    Dim writer As OCVVideoWriter
    Dim codec As OCVVideoio           'CAP_PROP_FOURCC
   
    Dim fps As Double
    Dim src As OCVMat
    Dim isColor As Int
   
   
    Dim mCore As OCVCore
    Dim mImgProc As OCVImgproc
   
End Sub

Sub Activity_Create(FirstTime As Boolean)
ImV.Initialize("ImV")
    ImV.Gravity = Gravity.FILL
    Activity.AddView(ImV,0,0,100%x,100%y)
    mVideoCapture.open2(0,mVio.CAP_ANY)
    Dim apri As Boolean
    apri = mVideoCapture.isOpened
    If mVideoCapture.isOpened Then
        Log("Errore Camera")
    End If
       
    mFrame.Initialize
    mBmap.InitializeMutable(520,520)
    ImV.Bitmap = mBmap
    Do While mVideoCapture.isOpened
        If mVideoCapture.read(mFrame) Then
            If mFrame.rows <> mBmap.Height Or mFrame.cols <> mBmap.Width Then
            mBmap.InitializeMutable(mFrame.cols,mFrame.rows)
            ImV.Bitmap = mBmap
        End If
        End If
        mUtils.matToBitmap1(mFrame,mBmap)
        ImV.Invalidate
           
            Loop
End Sub
 

JordiCP

Expert
Licensed User
Longtime User
In OpenCV for Android (the "official") , VideoCapture is only related to video files, differently to what happens in OpenCV for windows where you can link it to a webcam, for instance. It is not a thing from my library, they simply did it this way: those parts that interact directly with hardware are in different modules (highgui for most of them, but not in Android). The API still exposes some initialization methods suitable for camera access, but they only make sense if you have special binary builds in which native camera is included.
So, for camera access, in Android you can use JavaCameraView (most of the released examples use it) or CameraEx (if you need more control of the camera, but examples get more complicated).
Anyway, I see that I should hide those methods that, even if exposed in the Java API, make no sense for the current build. Will do it in next release.

Please study the released examples and the advanced ones. I will be happy to assist you with any doubt you may have


"The B4A Example program has been interconnected"
Is this the original message or google translated?
 

stu14t

Active Member
Licensed User
Longtime User
Something else to consider; some of the work required to carry out cat / dog / human detection is more than just coding. You will have to learn how to teach the computer vision using HAAR / LBP / HOG cascade classifiers

Just to follow on from this. I've found this great piece of software that can create the XML cascade classifiers needed for cat / dog / human, in fact, whatever detection. It's a simple GUI and there are some good tutorials to help you along CLICK HERE
 

JordiCP

Expert
Licensed User
Longtime User
in FaceDetector4.zip example how can i put insted of glasses the square round the face as this is more tipical in detection?
Just change a few lines in the inner processing loop

B4X:
  If facesArray.Length>0 Then     'We are only interested in first detection

     Dim drawRectangle As Boolean=True  '<-- define this here or in Sub Globals if you want a bounding rectangle around the detected face.
   
     If drawRectangle=True Then
     
       Dim myColorScalar As OCVScalar
       myColorScalar.Initialize4(0,255,0,255)   'Order is R,G,B,A. In this case we are drawing a green rectangle
       ' We draw a green rectangle (with line thickness=4). As facesArray() already holds the detected faces rectangles, just need
       ' the top-left (tl) and bottom-right (br) points to draw it
       mImgProc.rectangle1(mRgba,facesArray(0).tl,facesArray(0).br,myColorScalar,4)

     Else    '<--- original code (glasses)

       'The detected face rectangle size is: W_face x H_face
       Dim W_glasses As Int = facesArray(0).width   ' Will rescale our original glasses Mat width to W_face,
       Dim H_glasses As Int = W_glasses/3       ' keep its original aspect ratio (3:1)
       Dim mScaledGlasses As OCVMat
       mScaledGlasses.Initialize
       Dim scaledGlassesSize As OCVSize
       scaledGlassesSize.Initialize2( Array As Double( W_glasses,H_glasses))

       mImgProc.resize1( mOriginalGLasses, mScaledGlasses,scaledGlassesSize)

       'Now apply the effect to the full color image.
     
       Dim mBGRA_ROI As OCVMat = mRgba.submat( _     'This does NOT create a copy, but a reference to a region of interest
         facesArray(0).tl.y + facesArray(0).height/4, _
         facesArray(0).tl.y + facesArray(0).height/4+H_glasses, _
         facesArray(0).tl.x, _
         facesArray(0).br.x)
     
       ' We want to copy the glasses to the selected region of the face
       ' As the square containing them has some transparent pixels, we use them as a mask
       Dim glassesMask As OCVMat
       glassesMask.Initialize
       mCore.extractChannel(mScaledGlasses,glassesMask,3)   'Use alpha (channel 3) from overlay image to define the mask to be used for copy
       mScaledGlasses.copyTo1(mBGRA_ROI, glassesMask)

     End If
  End if

--EDIT-- Just updated the facedetector example in first post. Now both options are allowed (glasses and rectangle). Rectangle option is defined at the end of Sub Globals as a boolean (it is disabled by default, just set it to True)
 
Last edited:

jchal

Active Member
Licensed User
Longtime User
thanks jordi
if i have more than one faces how do you amend the code?
 

JordiCP

Expert
Licensed User
Longtime User
facesArray() holds all the detected faces for each frame. In the example I was only using the first one, as it is a demo

You should change the line where it says
B4X:
  if facesArray.Length>0
    '... 
  End If
and replace it by
B4X:
  For k=0 to facesArray.Length-1
    ' The same content but replacing facesArray(0) by facesArray(k)
  Next

Please notice that detectors may fail in detecting all faces (in general, any object) and also can give some false positives: If there is a carton box with some drawings, detector can think it is a face. It depends both on the detector and scene lighting.
You can also program more advanced filters to make it more robust, such as filtering them by size, or by scenes: if you are capturing 'live' video, detected faces should appear reasonably 'near' to where the previous were detected. If not, it is probably a false positive.
 

jchal

Active Member
Licensed User
Longtime User
i am trying to test the folowing cascade files cascadG is for human detection and forfire is for fire detection, when i try it using the face detection it is not acurate why?
 

jchal

Active Member
Licensed User
Longtime User
sorry i forgot to uplad the files
 

Attachments

  • cascadG.xml
    26.6 KB · Views: 279
  • forfire.xml
    115.1 KB · Views: 263
Cookies are required to use this site. You must accept them to continue using the site. Learn more…