Wednesday, January 6, 2016

Encapsulate OpenCV 3.1 as Android AAR

In this post I describe how to encapsulate OpenCV as an Android AAR package such that it is easier to include it as a maven dependency.

[High Street, Guildford, England]  (LOC)


Disclaimer: Apparently there exist many other tutorials about OpenCV, my approach is a little bit unconventional. I also have to mention that there is a very well maintained library called JavaCV which does essentially the same.

The motivation for this blog post is that I want to have an convenient way to use OpenCV with my Android applications. Below I describe what I had to do to achieve this.

Step 1: Download the OpenCV library


On www.opencv.org there is a link to download the library for Android. Download it, unpack it.

If you've followed the post about compiling OpenCV yourself, you already have a directory in your
homedirectory somewhere:

opencv/
opencv/opencv-3.1/
opencv/build/

now, add the unpacked Android SDK:

opencv/
opencv/opencv-3.1/
opencv/build/
opencv/OpenCV-android-sdk-3/

You'll find the usual suspects in the directory, some samples, javadoc for the API, already pre build apk's:

apk/
samples/
sdk/

Now I want to discuss briefly the contents of those directories.

Directory apk: OpenCV Manager

OpenCV encourages you to use a separate application called OpenCV Manager which sole purpose is to make sure you have installed a compatible OpenCV library on your phone. This approach is fine but requires your users to install a second app on their phone. For the technical inclined this is no problem, but for end users this may seem a little bit awkward. I prefer to deliver a self contained app which has no apparent third party dependencies.

The apk directory contains this Manager application for environments where you don't want to use the OpenCV Manager from the play store.


Directory samples: OpenCV Android Samples


The samples directory contains several example apps which demonstrate various aspects of the OpenCV API for android.

./samples/example-15-puzzle.apk
./samples/example-camera-calibration.apk
./samples/example-color-blob-detection.apk
./samples/example-face-detection.apk
./samples/example-image-manipulations.apk
./samples/example-tutorial-1-camerapreview.apk
./samples/example-tutorial-2-mixedprocessing.apk
./samples/example-tutorial-3-cameracontrol.apk

I recommend to install some of the apk's on your device:

  adb install <example.apk>

This is the best way to get a feeling what can be done with the OpenCV Android API, so I suggest to play around with the samples. The source code for those samples is also included.

Directory sdk: Android OpenCV Java API

Here you'll find what you will need for your own app. There are  pre-built android libraries for various architectures and one java API to use the native code. The directory structure you'll find on the top of this directory looks like follows:

etc/ ... some configuration for special routines you could use 
java/ ... the java glue code you will program against
native/ ... prebuilt binaries for the android platform

Since I use maven for most of my projects and all of my open source stuff, I need some way to use the provided java glue code and the binaries in my projects. As long as you just use the default API for OpenCV, you can take the code provided almost off the shelf.

Create an OpenCV AAR ready to use with Maven

The following approach shows how you can create a maven module containing the OpenCV bindings - thanks to the android-maven-plugin it can then be used like a 'normal' maven dependency. The plugin will take care about including the AAR in the final APK, you just have to declare it as a dependency (see below).

For this to happen, I've restructured the source code in the following way:

Restructuring of the sdk subfolder
This is the default structure which works together with the android-maven-plugin and includes only code and binaries you'll need at runtime. The pom looks as follows:

pom.xml for an opencv aar

You can see that I'm referring to the standard android api of a certain version - this is needed in order to properly compile the OpenCV Java API.

In order to get the standard android api, you have to clone yet another project named maven-android-sdk-deployer and install the proper API level in your local maven repository. This can be done for
example by issuing following command:

mvn install -P 5.0

A prerequisite for this command to finish successfully is however that you have already installed the Android SDK itself.

Hint: It seems that the OpenCV 3.1 bindings for Android need at least API level 21, maybe you save some time by just downloading this API Level.

Anyway, if you look closely at the pom.xml you'll notice it is using a custom packaging method, namely 'aar' - this is possible since the android-maven-plugin provides the capabilities for maven to properly create such a file type.

Aar's are bundles which contain libraries (Java code, resources or native code) ready to use in Android Applications. Luckily, android-maven-plugin makes it possible to use aar's like normal maven dependencies.

By using this approach you can deploy the OpenCV bindings in your maven repository. OpenCV can then be treated like any other maven dependency, which is a nice thing.

To recap:

After a successful deploy or local install of this maven module (with mvn install) all you need is to include it in the dependency list of your main app, just like shown below:

dependency declaration for your homebrew opencv maven module

That's all there is to it - you should be able now to use OpenCV in your project. Of course, the maven coordinates change depending on which you've chosen before.

One nice aspect is that the download of the OpenCV Manager is not needed anymore. The drawback is of course that your apk is getting bigger - nothing comes without a price.

For a complete example have a look at the SudokuFX project. Thanks for reading.


No comments:

Post a Comment