B4A Library OpenCV 3.x

moster67

Expert
Licensed User
Longtime User
Here is a video which is the result after some hours of coding to learn better OpenCV.

This video wants to demonstrate car detection in realtime using OpenCV for B4A.
The video was processed so each frame could be extracted and then a detection process was run..

The result can surely be much improved by experimenting with thresholds and other values to avoid false detection etc. This example could probably be improved to also distinguish cars from vans and lorries. You could count how many cars are passing by and their colors etc.

You can find examples of similar videos on the internet where c++ or python have been used. Now it is possible also with B4A!
Many thanks to @JordiCP for wrapping OpenCV for B4A and for letting me test it in this beta-phase!

 
Last edited:

stu14t

Active Member
Licensed User
Longtime User

Again I can't thank @JordiCP enough for this lib.

I'm working on something similar. What do you think the limit is for the number of simultaneous classifiers running at the same time? Some of the HAAR xml files get quite big.

Some of the OpenCV examples show two or three but that is not in Android.
 

moster67

Expert
Licensed User
Longtime User
What do you think the limit is for the number of simultaneous classifiers running at the same time?
I really don't know - I just started out learning OpenCV. However, we must remember that there might be some restrictions on Android (see Jordi's post) what regards optimization of code and of course that the hardware has less performance than a PC. The performance of the sample I posted varied quite a lot when I ran it on my old Samsung Galaxy S3 and my wife's much newer (and faster) LG phone so hardware is definitively an important factor, especially for real time tasks.
 
Last edited:

JordiCP

Expert
Licensed User
Longtime User
Totally agree. As with desktop PCs, if we are talking of real-time, maximum performance will need programming with C++ and taking advantage of hardware acceleration.

However, making use of some simple tips (this applies to whatever platform), will make your app faster.
  • Minimize number of operations: declare all your vars out of the main loop. Reuse all what can be reused.Not only because of memory: JNI calls also take time.
  • Input resolution. Depending on which features you need, most of the times 640X480 is more than enough, even in some cases 320x240
  • Color or gray: If you are looking for shapes, consider starting with a gray image instead of rgb.
  • Measure: talking about performance in 32-bit devices with @moster67, we realized that blurring with a kernel size above 16 caused a terrible drop in performance. It can be due to cache issues, or internal branches in how the algorithm is handled internally (up to 16, it fits in a 256 structure, so can be optimized by a certain algorithm branch. And if it's bigger, then another algo is used)
  • Compare: the same algorithms have parameters which we tend to use as found in the examples. However, they can have a determinant effect in performance.
  • Frame skipping: if you are not doing some kind of face morphing or tracking for AR, but for instance object detection and recognition, consider if you need all the frames to be processed, or it is enough once a second.
 

roberto64

Active Member
Licensed User
Longtime User
hi jordiCP, I found this error.
regards

B4X:
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
JavaCameraViewInitialize java camera
JavaCameraViewTrying to open back camera
JavaCameraViewTrying to open camera with new open(0)
mCamera=android.hardware.Camera@41c48098
JavaCameraViewgetSupportedPreviewSizes()
JavaCameraViewSet preview size to 352x288
JavaCameraViewstartPreview
HelloThread!!!
Error occurred on line: 114 (Main)
CvException [com.appiotic.ocv4b4a.core.CvException: cv::Exception: C:/Develop/git/opencv_320/modules/core/src/matrix.cpp:491: error: (-215) 0 <= _colRange.start && _colRange.start <= _colRange.end && _colRange.end <= m.cols in function cv::Mat::Mat(const cv::Mat&, const cv::Range&, const cv::Range&)
]
    at com.appiotic.ocv4b4a.core.Mat.n_submat_rr(Native Method)
    at com.appiotic.ocv4b4a.core.Mat.submat(Mat.java:875)
    at com.appiotic.ocv4b4a.samples.cameratest.main._frameprocessor_newframe(main.java:508)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:710)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:339)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:249)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:139)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:166)
    at com.appiotic.ocv4b4a.android.JavaCameraView.rapidDebugModeCameraWorker(JavaCameraView.java:483)
    at com.appiotic.ocv4b4a.android.JavaCameraView.onPreviewFrame(JavaCameraView.java:387)
    at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1005)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:146)
    at android.app.ActivityThread.main(ActivityThread.java:5511)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
    at dalvik.system.NativeStart.main(Native Method)
Error occurred on line: 114 (Main)
java.lang.NullPointerException
    at anywheresoftware.b4a.shell.Shell.runGoodChain(Shell.java:463)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:285)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:249)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:139)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:166)
    at com.appiotic.ocv4b4a.android.JavaCameraView.rapidDebugModeCameraWorker(JavaCameraView.java:483)
    at com.appiotic.ocv4b4a.android.JavaCameraView.onPreviewFrame(JavaCameraView.java:387)
    at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1005)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:146)
    at android.app.ActivityThread.main(ActivityThread.java:5511)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
    at dalvik.system.NativeStart.main(Native Method)
 

JordiCP

Expert
Licensed User
Longtime User
B4X:
CvException [com.appiotic.ocv4b4a.core.CvException: cv::Exception: C:/Develop/git/opencv_320/modules/core/src/matrix.cpp:491: error: (-215) 0 <= _colRange.start && _colRange.start <= _colRange.end && _colRange.end <= m.cols in function cv::Mat::Mat(const cv::Mat&, const cv::Range&, const cv::Range&)
The error is thrown when trying to define a subMat with a row/column range that is not within the original Mat boundaries (or defined in reverse order).

Is it the original example or you changed something?
 

JordiCP

Expert
Licensed User
Longtime User
It is strange because the example tries to initialize the camera at 640x480 which I supposed that all cameras have (and some part of the code relied on it without checking)
B4X:
JavaCameraViewSet preview size to 352x288  '<-- the camera has been initted to this preview size, so something went wrong

This modified example should work for you, I adapted code so that it depends on real preview size and not the intended one.

Which device are you using?
 

Attachments

  • CameraOpenCvTest5.zip
    3.3 KB · Views: 516

JordiCP

Expert
Licensed User
Longtime User
Really strange, in theory the device supports 640x480
The camera sets its preview size to the maximum (w,h) among the supported preview sizes, which is not superior to the minimum of (640,480) and (P.Width,P.height)

Did the new example work for you? If not I'll PM you and try to discover what happens
 

roberto64

Active Member
Licensed User
Longtime User
Hi JordiCP, the second example you have posted and ok, but for the example you first published by the same error, or even restarted the smatfhone but nothing, my fencing results support it.
Greetings
 

JordiCP

Expert
Licensed User
Longtime User
Thank you for testing and reporting
Yes, it seems that in some devices the setup routine fails to get the desired preview size, even if it exists. Will try to fix it.
 

JordiCP

Expert
Licensed User
Longtime User
You need to copy the library files ( .jar and .xml) to the additional libraries folder (and then add the lib to the project by checking it in the 'Libraries manager' Tab)
For any other issue please PM me
 

did2kan

New Member
Licensed User

Great job, thanks you to work on calibration ;-)
 

roberto64

Active Member
Licensed User
Longtime User
Hi Jordi
CP, I'm trying to open an avi file as by code in the list, with VideoCapture I do not understand why the avi file finds it but it does not open.
Greetings

B4X:
Dim video_src As String  =  "video1.avi"

Sub MainCamera()
    Dim inframe As OCVMat
    Dim grab As Boolean
    Dim apre As Boolean
    Dim Videscr As String
    Videscr = File.DirRootExternal&"/"&video_src
    If File.Exists(File.DirRootExternal,video_src) Then
        Log("Yes")
        Else
        Log("No")
       
    End If
   
    cvvideo.Initialize2(0)
    cvvideo.set(mvideo.CAP_PROP_FRAME_HEIGHT,480)
    cvvideo.set(mvideo.CAP_PROP_FRAME_WIDTH,640)
   
If cvvideo.open1(Videscr) Then
        Log( "Could not open the video file1")
        Else
        Log( "Video1 loaded")
End If
    apre = cvvideo.isOpened
    If cvvideo.isOpened Then
        Log( "failed")
        Else
        Log( "opened")
        cvvideo.read(inframe)
        'cvvideo.retrieve(inframe,1)
    End If
   
    Do While apre
        cvvideo.read(inframe) ' inframe Mat
    Loop

End Sub
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…