How To Create a FastCV Application with the RICOH THETA Plug-in SDK

fastcv
android-ndk
computer-vision

#1

FastCV Part 3

Part 1 - FastCV introduction and installation

Part 2 - How To Use Android NDK to Build FastCV for the RICOH THETA

This article was originally published in Japanese by roohi_3.

Create a FastCV application

Attempt to use FastCV API in the project.

  1. Adding an NDK source file

Select Project from the window tool bar and put the view in Project mode.

  • Follow (project) > app> src > main > jni from the project tree, right click and select New > C/C++ Source File
  • Enter the appropriate C++ file name and click OK
  • Create a header file from New> C/C++ Header File
  • A file will be created under jni

Open Android.mk and add the .cpp file name added to LOCAL_SRC_FILES

Example:

LOCAL_SRC_FILES := \
    FastCVSample.cpp

Click Sync Now displayed at the top of the editor window.

Implementation

Exchange of Java and native functions

As I am still learning about the NDK, I am not able to explain too much detail about the Java and native functions work together. There seems to be special rules for functions used for Java :left_right_arrow: native (C++) exchanges.

It seems to use a special return type and argument type.

For details, refer to the JNI type and data structure etc.

Native side function naming convention.

JNIEXPORT [return type] JNICALL Java _ [relative path of Java source from top level source directory] _ [caller's Java class name] _ [function name] (JNIEnv *, jobject, [argument], ... ))

Example:

JNIEXPORT jstring Java_com_theta360_fastcvsimplesample_MainActivity_getFastCVVersion(JNIEnv * env, jobject obj);

Calling native functions from Java

It seems necessary to do the following

  • Call System.loadLibrary ("[.so file name]") at startup

  • Declare function with native keyword

    // example

    static {
    // Load JNI Library
    Log.i(TAG, “Load JNI Library”);
    System.loadLibrary(“fastcvsimplesample”); // <–
    }

    private void foo(){

    // call native function
    String versionText = "FastCV Version: " + getFastCVVersion(); // <–
    Log.i(TAG, versionText);
    }
    }

    // Define native function
    public native String getFastCVVersion(); // <–

Basic API of FastCV

The basic API is defined in the Miscellaneous module.

When using FastCV, it is necessary to call the following initialization / termination processing API.

  • Initialization processing: fcvSetOperationMode (fcvOperationMode mode);
    • It seems to set performance level as argument.
    • As in the document (fcvOperationMode section), five level setting values are defined.
  • Termination processing: fcvCleanUp (void);
  • Version acquisition: fcvGetVersion (char * version, unsigned int versionLength);
    • In the argument, pass a pointer and number of characters for storing version information.

Code description example

Native Header File

FastCVSample.h
#ifndef THETA_PLUGIN_FASTCV_SIMPLE_SAMPLE_FASTCVSAMPLE_H
#define THETA_PLUGIN_FASTCV_SIMPLE_SAMPLE_FASTCVSAMPLE_H

#include <jni.h>

// Declarations
extern "C" {
JNIEXPORT void JNICALL Java_com_theta360_fastcvsimplesample_MainActivity_initFastCV
        (
                JNIEnv* env,
                jobject obj
        );
JNIEXPORT void JNICALL Java_com_theta360_fastcvsimplesample_MainActivity_cleanupFastCV
        (
                JNIEnv * env,
                jobject obj
        );
JNIEXPORT jstring JNICALL Java_com_theta360_fastcvsimplesample_MainActivity_getFastCVVersion
        (
                JNIEnv* env,
                jobject obj
        );
};

#endif //THETA_PLUGIN_FASTCV_SIMPLE_SAMPLE_FASTCVSAMPLE_H

Native C++ File

FastCVSample.cpp
#include <fastcv/fastcv.h>
#include "FastCVSample.h"

JNIEXPORT void JNICALL Java_com_theta360_fastcvsimplesample_MainActivity_initFastCV
(
        JNIEnv* env,
        jobject obj
)
{
    fcvSetOperationMode( (fcvOperationMode) FASTCV_OP_PERFORMANCE );
    return;
}

JNIEXPORT void JNICALL Java_com_theta360_fastcvsimplesample_MainActivity_cleanupFastCV
(
        JNIEnv * env,
        jobject obj
)
{
    fcvCleanUp();
}

JNIEXPORT jstring JNICALL Java_com_theta360_fastcvsimplesample_MainActivity_getFastCVVersion
        (
                JNIEnv * env,
                jobject obj
        )
{
    char sVersion[32];
    fcvGetVersion(sVersion, 32);

    return env->NewStringUTF(sVersion);
}

Java File

I’m implementing the Java file based on MainActivity.java of the RICOH THETA Plug-in SDK.

I am trying to call getFastCVVersion() in onKeyDown(). This makes it possible to display the version when you press the shutter button of THETA.

// MainActivity.java
// (partial snippet)

public class MainActivity extends PluginActivity {
    private static final String TAG = "FastCVSimpleSample";

    static {
        // Load JNI Library
        Log.i(TAG, "Load JNI Library");
        System.loadLibrary("fastcvsimplesample");   // <--
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Set enable to close by pluginlibrary, If you set false, please call close() after finishing your end processing.
        setAutoClose(true);

        // Set a callback when a button operation event is acquired.
        setKeyCallback(new KeyCallback() {
            @Override
            public void onKeyDown(int keyCode, KeyEvent event) {
                if (keyCode == KeyReceiver.KEYCODE_CAMERA) {

                    // call native function
                    String versionText = "FastCV Version: " + getFastCVVersion();   // <--
                    Log.i(TAG, versionText);
                }
            }

            @Override
            public void onKeyUp(int keyCode, KeyEvent event) {

            }

            @Override
            public void onKeyLongPress(int keyCode, KeyEvent event) {

            }
        });
    }

    @Override
    protected void onResume()
    {
        super.onResume();
        initFastCV();   // <--
    }

    @Override
    protected void onPause() {
        cleanupFastCV();    // <--
        super.onPause();
    }

    // define native function
    public native void initFastCV();            // <--
    public native void cleanupFastCV();         // <--
    public native String getFastCVVersion();    // <--
}

Build and run

  • Click Run > Run app from the menu to build and execute
  • When the Select Deployment Target window appears, select THETA V and click OK
  • Check Build in the tool window to confirm that the build succeeded

When describing the code, the version of FastCV is displayed in Logcat when the shutter button is pressed.

Note: Filtering with the TAG name set in Log.i () is easy to see

Conclusion

I think that the work to be completed this time was somewhat fun and challenging. It was quite a difficult task …

In the next article series, we will introduce the procedure to actually process the image.


FastCV Image Processing Part 4