@ -57,12 +57,12 @@ Using async initialization is a **recommended** way for application development.
To run OpenCV Manager-based application the first time you need to install packages with the `OpenCV Manager` and `OpenCV binary pack` for you platform.
You can do it using Google Play Market or manually with ``adb`` tool:
There is a very base code snippet implementing the async initialization. It shows basic principles. See the "15-puzzle" OpenCV sample for details.
..code-block:: java
@ -107,7 +107,7 @@ There is a very base code snippet implementing the async initialization. It show
}
It this case application works with OpenCV Manager in asynchronous fashion. ``OnManagerConnected`` callback will be called in UI thread, when initialization finishes.
Please note, that it is not allowed to use OpenCV calls or load OpenCV-dependent native libs before invoking this callback.
Please note, that it is not allowed to use OpenCV calls or load OpenCV-dependent native libs before invoking this callback.
Load your own native libraries that depend on OpenCV after the successful OpenCV initialization.
Application development with static initialization
@ -130,27 +130,27 @@ This approach is deprecated for the production code, release package is recommen
:align:center
#. If your application project **doesn't have a JNI part**, just copy the corresponding OpenCV native libs from :file:`<OpenCV-2.4.2-android-sdk>/sdk/native/libs/<target_arch>` to your project directory to folder :file:`libs/<target_arch>`.
In case of the application project **with a JNI part**, instead of manual libraries copying you need to modify your ``Android.mk`` file:
In case of the application project **with a JNI part**, instead of manual libraries copying you need to modify your ``Android.mk`` file:
add the following two code lines after the ``"include $(CLEAR_VARS)"`` and before ``"include path_to_OpenCV-2.4.2-android-sdk/sdk/native/jni/OpenCV.mk"``
..code-block:: make
:linenos:
:linenos:
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
The result should look like the following:
..code-block:: make
:linenos:
:linenos:
include $(CLEAR_VARS)
include $(CLEAR_VARS)
# OpenCV
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
include ../../sdk/native/jni/OpenCV.mk
# OpenCV
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
include ../../sdk/native/jni/OpenCV.mk
After that the OpenCV libraries will be copied to your application :file:`libs` folder during the JNI part build.
@ -159,28 +159,28 @@ This approach is deprecated for the production code, release package is recommen
#. The last step of enabling OpenCV in your application is Java initialization code before call to OpenCV API.
It can be done, for example, in the static section of the ``Activity`` class:
..code-block:: java
:linenos:
..code-block:: java
:linenos:
static {
if (!OpenCVLoader.initDebug()) {
// Handle initialization error
}
}
static {
if (!OpenCVLoader.initDebug()) {
// Handle initialization error
}
}
If you application includes other OpenCV-dependent native libraries you should load them **after** OpenCV initialization:
If you application includes other OpenCV-dependent native libraries you should load them **after** OpenCV initialization:
..code-block:: java
:linenos:
..code-block:: java
:linenos:
static {
if (!OpenCVLoader.initDebug()) {
// Handle initialization error
} else {
System.loadLibrary("my_jni_lib1");
System.loadLibrary("my_jni_lib2");
}
}
static {
if (!OpenCVLoader.initDebug()) {
// Handle initialization error
} else {
System.loadLibrary("my_jni_lib1");
System.loadLibrary("my_jni_lib2");
}
}
Native/C++
----------
@ -198,33 +198,33 @@ To build your own Android application, which uses OpenCV from native part, the f
..code-block:: make
include C:\Work\OpenCV4Android\OpenCV-2.4.2-android-sdk\sdk\native\jni\OpenCV.mk
include C:\Work\OpenCV4Android\OpenCV-2.4.2-android-sdk\sdk\native\jni\OpenCV.mk
should be inserted into the :file:`jni/Android.mk` file **after** the line
..code-block:: make
include $(CLEAR_VARS)
include $(CLEAR_VARS)
#. Several variables can be used to customize OpenCV stuff, but you **don't need** to use them when your application uses the `async initialization` via the `OpenCV Manager` API.
Note: these variables should be set **before** the ``"include .../OpenCV.mk"`` line:
..code-block:: make
OPENCV_INSTALL_MODULES:=on
OPENCV_INSTALL_MODULES:=on
Copies necessary OpenCV dynamic libs to the project ``libs`` folder in order to include them into the APK.
..code-block:: make
OPENCV_CAMERA_MODULES:=off
OPENCV_CAMERA_MODULES:=off
Skip native OpenCV camera related libs copying to the project ``libs`` folder.
..code-block:: make
OPENCV_LIB_TYPE:=STATIC
OPENCV_LIB_TYPE:=STATIC
Perform static link with OpenCV. By default dynamic link is used and the project JNI lib depends on ``libopencv_java.so``.
@ -232,14 +232,14 @@ To build your own Android application, which uses OpenCV from native part, the f
..code-block:: make
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
Also the line like this one:
..code-block:: make
APP_ABI := armeabi-v7a
APP_ABI := armeabi-v7a
should specify the application target platforms.
@ -249,11 +249,11 @@ To build your own Android application, which uses OpenCV from native part, the f
..code-block:: make
APP_PLATFORM := android-9
APP_PLATFORM := android-9
#. Either use :ref:`manual <NDK_build_cli>```ndk-build`` invocation or :ref:`setup Eclipse CDT Builder <CDT_Builder>` to build native JNI lib before Java part [re]build and APK creation.
Hello OpenCV Sample
===================
@ -262,208 +262,217 @@ Here are basic steps to guide you trough the process of creating a simple OpenCV
It will be capable of accessing camera output, processing it and displaying the result.
#. Open Eclipse IDE, create a new clean workspace, create a new Android project (*File -> New -> Android Project*).
#. Set name, target, package and minSDKVersion accordingly.
#. Create a new class (*File -> New -> Class*). Name it for example: *HelloOpenCVView*.
.. image:: images/dev_OCV_new_class.png
:alt:Add a new class.
:align:center
* It should extend *SurfaceView* class.
..image:: images/dev_OCV_new_class.png
:alt:Add a new class.
:align:center
* It also should implement *SurfaceHolder.Callback*, *Runnable*.
* It should extend *SurfaceView* class.
* It also should implement *SurfaceHolder.Callback*, *Runnable*.
#. Edit *HelloOpenCVView* class.
* Add an *import* line for *android.content.context*.
* Add an *import* line for *android.content.context*.
* Modify autogenerated stubs: *HelloOpenCVView*, *surfaceCreated*, *surfaceDestroyed* and *surfaceChanged*.
* Modify autogenerated stubs: *HelloOpenCVView*, *surfaceCreated*, *surfaceDestroyed* and *surfaceChanged*.
.. code-block:: java
..code-block:: java
:linenos:
package com.hello.opencv.test;
package com.hello.opencv.test;
import android.content.Context;
import android.content.Context;
public class HelloOpenCVView extends SurfaceView implements Callback, Runnable {
public class HelloOpenCVView extends SurfaceView implements Callback, Runnable {
public HelloOpenCVView(Context context) {
super(context);
getHolder().addCallback(this);
}
public HelloOpenCVView(Context context) {
super(context);
getHolder().addCallback(this);
}
public void surfaceCreated(SurfaceHolder holder) {
(new Thread(this)).start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
cameraRelease();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
cameraSetup(width, height);
}
public void surfaceCreated(SurfaceHolder holder) {
(new Thread(this)).start();
}
* Add *cameraOpen*, *cameraRelease* and *cameraSetup* voids as shown below.
public void surfaceDestroyed(SurfaceHolder holder) {
cameraRelease();
}
* Also, don't forget to add the public void *run()* as follows:
.. code-block:: java
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
#. Create a new *Activity* (*New -> Other -> Android -> Android Activity*) and name it, for example: *HelloOpenCVActivity*. For this activity define *onCreate*, *onResume* and *onPause* voids.
.. code-block:: java
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mView = new HelloOpenCVView(this);
setContentView (mView);
}
protected void onPause() {
super.onPause();
mView.cameraRelease();
}
protected void onResume() {
super.onResume();
if( !mView.cameraOpen() ) {
// MessageBox and exit app
AlertDialog ad = new AlertDialog.Builder(this).create();
ad.setCancelable(false); // This blocks the "BACK" button
ad.setMessage("Fatal error: can't open camera!");
ad.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
ad.show();
}
}
..code-block:: java
:linenos:
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mView = new HelloOpenCVView(this);
setContentView (mView);
}
protected void onPause() {
super.onPause();
mView.cameraRelease();
}
protected void onResume() {
super.onResume();
if( !mView.cameraOpen() ) {
// MessageBox and exit app
AlertDialog ad = new AlertDialog.Builder(this).create();
ad.setCancelable(false); // This blocks the "BACK" button
ad.setMessage("Fatal error: can't open camera!");
ad.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
ad.show();
}
}
#. Add the following permissions to the AndroidManifest.xml file: