Question

Apologies if my answer already lies somewhere on the Internet, but I have been at this for days now and there simply does not seem to exist an answer to my problems. I have looked at most other similar questions posted by other users, and I have tried every solution that has been offered, but it stubbornly refuses to work.

I've been trying to get a simple Android + OpenCV + JNI code running. I have configured all the necessary settings, including the Android & Application .mk files and I have also made sure all my OpenCV libraries are correctly imported, which they seem to be. My code does not give me any errors before launching, but once the application has been launched, I get a terrible'java.lang.UnsatisfiedLinkError: Native method not found: com.test.opencvcameratest.MainActivity.convertNativeGray(I)I' error for which there seems to be no logical reason as I'm fairly certain I've taken all the necessary steps to get to this point. I've included my code below, and I'd be extremely grateful to anyone who can help me resolve this baffling mystery.

package com.test.opencvcameratest;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.view.WindowManager;

public class MainActivity extends Activity implements CvCameraViewListener2 { //implement    cvcameraviewlistener2 for camera functionality

private Mat mRgba;
private Mat mGray;

private CameraBridgeViewBase mOpenCvCameraView;

public native int convertNativeGray(int n);

private final static String TAG = "MainActivity";

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this)
{
    @Override
    public void onManagerConnected(int status)
    {
        switch(status)
        {
            case LoaderCallbackInterface.SUCCESS:
            {
                System.loadLibrary("OpenCVCameraTest");// Load Native module
                Log.i(TAG, "OpenCV loaded successfully");
                mOpenCvCameraView.enableView();

            }
        }
    }
};


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    setContentView(R.layout.activity_main);
    mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.HelloOpenCvView);
    mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
    mOpenCvCameraView.setCvCameraViewListener(this);


}

@Override
public void onPause()
{
    super.onPause();
    if(mOpenCvCameraView != null)
        mOpenCvCameraView.disableView();
}

@Override
public void onResume()
{
    super.onResume();
    OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_8, this, mLoaderCallback);
    Log.i("LOG MESSAGE", "OPENCV LOADED");
}

@Override
public void onDestroy()
{
    super.onDestroy();
    if(mOpenCvCameraView != null)
        mOpenCvCameraView.disableView();
}

@Override
public void onCameraViewStarted(int width, int height)
{
    //
}

@Override
public void onCameraViewStopped()
{
    //
}

@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame)
{
    mRgba = inputFrame.rgba();
    //mGray = null;

    int i = convertNativeGray(5);

    return mRgba;
}

}

This is the native .cpp file (OpenCVCameraTest.cpp). It is clearly true that there DOES exist a convertNativeGray method, as opposed to what is being claimed by the linker.

#include <jni.h>
#include "opencv2/core/core.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <stdio.h>

using namespace cv;

extern "C"
{

JNIEXPORT jint JNICALL Java_com_test_opencvcameratest_convertNativeGray(JNIEnv*, jobject, jint n);

JNIEXPORT jint JNICALL Java_com_test_opencvcameratest_convertNativeGray(JNIEnv*, jobject, jint n)
{
    return n*2;
}

}

This is the Android.mk file.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on

LOCAL_SRC_FILES := OpenCVCameraTest.cpp

include C:\Users\user\Downloads\OpenCV-2.4.8-android-sdk\sdk\native\jni\OpenCV.mk

LOCAL_LDLIBS +=  -llog -ldl
LOCAL_MODULE    := OpenCVCameraTest

include $(BUILD_SHARED_LIBRARY)

And I'll include the error cropping up too, for good measure.

03-31 16:57:47.627: E/AndroidRuntime(14335): FATAL EXCEPTION: Thread-33554
03-31 16:57:47.627: E/AndroidRuntime(14335): Process: com.test.opencvcameratest, PID: 14335
03-31 16:57:47.627: E/AndroidRuntime(14335): java.lang.UnsatisfiedLinkError: Native method not found: com.test.opencvcameratest.MainActivity.convertNativeGray:(I)I
03-31 16:57:47.627: E/AndroidRuntime(14335):    at com.test.opencvcameratest.MainActivity.convertNativeGray(Native Method)
03-31 16:57:47.627: E/AndroidRuntime(14335):    at com.test.opencvcameratest.MainActivity.onCameraFrame(MainActivity.java:101)
03-31 16:57:47.627: E/AndroidRuntime(14335):    at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:387)
03-31 16:57:47.627: E/AndroidRuntime(14335):    at org.opencv.android.JavaCameraView$CameraWorker.run(JavaCameraView.java:328)
03-31 16:57:47.627: E/AndroidRuntime(14335):    at java.lang.Thread.run(Thread.java:864)
Was it helpful?

Solution

The Native function should be

JNIEXPORT jint JNICALL Java_com_test_opencvcameratest_MainActivity_convertNativeGray() 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top