我一直在尝试使用 Android NDK , OpenCV-2.4.10 在 Android Studio 2.2 中编译this源代码和 OpenCV-2.4.10-android-sdk 。 我已经能够使用这个thread和Android NDK编译库,但问题是,当我运行应用程序时,它崩溃了这个例外:
10-19 13:16:52.401 27219-27219/? W/System.err: Native code library failed to load.
10-19 13:16:52.401 27219-27219/? W/System.err: java.lang.UnsatisfiedLinkError: com.android.tools.fd.runtime.IncrementalClassLoader$DelegateClassLoader[DexPathList[[dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-support-annotations-24.2.1_fed5c262a94aefc942781eb9d084010e5bac6a17-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-slice_9-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-slice_8-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-slice_7-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-slice_6-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-slice_5-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-slice_4-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-slice_3-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-slice_2-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-slice_1-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-slice_0-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-internal_impl-24.2.1_c5ce2ccc24f48fdeeaa83795c4a9965b3b0000bd-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-internal_impl-24.2.1_9180b436d4d87e2a23c5c519d7114d01fff80862-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-internal_impl-24.2.1_758040e3c9887b663eba33123666f0d3d8eb7843-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-internal_impl-24.2.1_756c53f48345dbb2e71bd2438ac9f2c3ae9d1134-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-internal_impl-24.2.1_62ee59c260ed6ea416c5d3215fa59796bfc5182d-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-com.android.support-support-vector-drawable-24.2.1_d52f38f279dcae00c9d3cbbeafe8ac633a0ecca4-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-com.android.support-support-v4-24.2.1_d95c4ed9fe44ddeb9a8a8aae5e16887920d4daf8-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-com.android.support-support-media-compat-24.2.1_9fa2c3bc1a23639dc03b19b5edb12c0d69de4a65-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-com.android.support-support-fragment-24.2.1_5761e83f1e521bc942c5fda0d5d1732e153d7fc2-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-com.android.support-support-core-utils-24.2.1_a2346acb90d9291006f5de9a4c03663e9a37e36b-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-com.android.support-support-core-ui-24.2.1_fb6dfb901874f3fff658664f859ae460d253e846-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-com.android.support-support-compat-24.2.1_b0964989f1de3db4f3e423aa1bea8410573c9efe-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-com.android.support-appcompat-v7-24.2.1_4842b08591f3514a767dfa2e4af7ee994ac6115e-classes.dex", dex file "/data/data/com.example.shahzeb.testingndk/files/instant-run/dex/slice-com.android.support-animated-vector-drawable-24.2.1_889e0b48597230c226324f209f1b26d855496bb4-classes.dex"],nativeLibraryDirectories=[/data/app/com.example.shahzeb.testingndk-2/lib/arm, /vendor/lib, /system/lib]]] couldn't find "libhomography.so"
java.lang.UnsatisfiedLinkError: No implementation found for void com.example.testingndk.MainActivity.runDemo() (tried Java_com_example_testingndk_MainActivity_runDemo and Java_com_example_testingndk_MainActivity_runDemo__)
at com.example.testingndk.MainActivity.runDemo(Native Method)
at com.example.testingndk.MainActivity.onCreate(MainActivity.java:34)
at android.app.Activity.performCreate(Activity.java:6251)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
我检查了我的包和方法名称,它们是相同的。我必须在Android.mk中遗漏一些东西。完整的源代码如下。
Android.mk
LOCAL_PATH := $(call my-dir)
OPENCV_PATH := C:/OpenCV-2.4.10-android-sdk/sdk/native/jni
include $(CLEAR_VARS)
OPENCV_INSTALL_MODULES := on
OPENCV_CAMERA_MODULES := off
include $(OPENCV_PATH)/OpenCV.mk
LOCAL_C_INCLUDES := \
$(LOCAL_PATH) \
$(OPENCV_PATH)/include
LOCAL_SRC_FILES := \
demo.cpp \
nonfree_init.cpp \
sift.cpp \
surf.cpp
LOCAL_MODULE := homography
LOCAL_CFLAGS := -Werror -O3 -ffast-math
LOCAL_LDLIBS := -llog -ldl
include $(BUILD_SHARED_LIBRARY)
demo.cpp
#include <jni.h>
#include <string.h>
#include <stdio.h>
#include <android/log.h>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/nonfree.hpp"
using namespace cv;
#define LOG_TAG "nonfree_jni_demo"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
typedef unsigned char uchar;
void run_demo();
void run_demo()
{
Mat img_object = imread( "/sdcard/DCIM/Camera/test1.jpg", CV_LOAD_IMAGE_GRAYSCALE );
Mat img_scene = imread( "/sdcard/DCIM/Camera/test2.jpg", CV_LOAD_IMAGE_GRAYSCALE );
if( !img_object.data || !img_scene.data ) {
// std::cout<< " --(!) Error reading images " << std::endl;
LOGI("Could not open or find the image!\n");
}
//-- Step 1: Detect the keypoints using SURF Detector
int minHessian = 400;
SurfFeatureDetector detector( minHessian );
std::vector<KeyPoint> keypoints_object, keypoints_scene;
detector.detect( img_object, keypoints_object );
detector.detect( img_scene, keypoints_scene );
//-- Step 2: Calculate descriptors (feature vectors)
SurfDescriptorExtractor extractor;
Mat descriptors_object, descriptors_scene;
extractor.compute( img_object, keypoints_object, descriptors_object );
extractor.compute( img_scene, keypoints_scene, descriptors_scene );
//-- Step 3: Matching descriptor vectors using FLANN matcher
FlannBasedMatcher matcher;
std::vector< DMatch > matches;
matcher.match( descriptors_object, descriptors_scene, matches );
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < descriptors_object.rows; i++ )
{ double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
// printf("-- Max dist : %f \n", max_dist );
// printf("-- Min dist : %f \n", min_dist );
//-- Draw only "good" matches (i.e. whose distance is less than 3*min_dist )
std::vector< DMatch > good_matches;
for( int i = 0; i < descriptors_object.rows; i++ )
{ if( matches[i].distance < 3*min_dist )
{ good_matches.push_back( matches[i]); }
}
Mat img_matches;
drawMatches( img_object, keypoints_object, img_scene, keypoints_scene,
good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
//-- Localize the object
std::vector<Point2f> obj;
std::vector<Point2f> scene;
for( int i = 0; i < good_matches.size(); i++ )
{
//-- Get the keypoints from the good matches
obj.push_back( keypoints_object[ good_matches[i].queryIdx ].pt );
scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
}
Mat H = findHomography( obj, scene, CV_RANSAC );
//-- Get the corners from the image_1 ( the object to be "detected" )
std::vector<Point2f> obj_corners(4);
obj_corners[0] = cvPoint(0,0); obj_corners[1] = cvPoint( img_object.cols, 0 );
obj_corners[2] = cvPoint( img_object.cols, img_object.rows ); obj_corners[3] = cvPoint( 0, img_object.rows );
std::vector<Point2f> scene_corners(4);
perspectiveTransform( obj_corners, scene_corners, H);
//-- Draw lines between the corners (the mapped object in the scene - image_2 )
line( img_matches, scene_corners[0] + Point2f( img_object.cols, 0), scene_corners[1] + Point2f( img_object.cols, 0), Scalar(0, 255, 0), 4 );
line( img_matches, scene_corners[1] + Point2f( img_object.cols, 0), scene_corners[2] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 );
line( img_matches, scene_corners[2] + Point2f( img_object.cols, 0), scene_corners[3] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 );
line( img_matches, scene_corners[3] + Point2f( img_object.cols, 0), scene_corners[0] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 );
//-- Show detected matches
imshow( "Good Matches & Object detection", img_matches );
waitKey(0);
}
void readme();
/** @function readme */
void readme(){
// std::cout << " Usage: ./SURF_descriptor <img1> <img2>" << std::endl;
LOGI(" Usage: ./SURF_descriptor <img1> <img2>\n");
}
extern "C" {
JNIEXPORT void JNICALL Java_com_example_testingndk_MainActivity_runDemo(JNIEnv * env, jobject obj);
};
JNIEXPORT void JNICALL Java_com_example_testingndk_MainActivity_runDemo(JNIEnv * env, jobject obj)
{
LOGI( "Start run_demo! \n");
run_demo();
LOGI( "End run_demo!\n");
}
MainActivity.java
package com.example.testingndk;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
static
{
try
{
// Load necessary libraries.
System.loadLibrary("homography");
}
catch( UnsatisfiedLinkError e )
{
System.err.println("Native code library failed to load.\n" + e);
}
}
public static native void runDemo();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("nonfree_jni_demo", "start runDemo");
// Call the JNI interface
runDemo();
}
}
答案 0 :(得分:0)
@uelordi感谢您的支持。
我已将 jni 文件夹放在项目目录的根目录中,因此在使用ndk-build
进行编译后,我从libs文件夹中复制了生成的*.so
文件(在编译后生成同一目录)到myapp / src / main / jniLibs我现在可以运行 OpenCV 代码了。我希望它可以帮助别人。