3
我一直在嘗試使用的Android NDK,OpenCV的-2.4.10和OpenCV的-2.4.10-Android的SDK編譯this源代碼的Android Studio 2.2中。 我已經能夠編譯使用此thread與Android NDK庫,但問題是,當我運行該應用程序也與此異常崩潰:Features2D +單應OpenCV的鏈接錯誤
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();
}
}
您的應用程序無法識別您的本機功能。試過用gradle來定義你的ndk Homography模塊嗎? – uelordi
是的,我做到了,但沒有奏效。我在android塊中添加了「ndk {moduleName」單應性「 }」。 – Shahzeb
btw我的本地代碼庫未能加載。你能猜出原因嗎? – Shahzeb