2016-10-19 54 views
3

我一直在嘗試使用的Android NDKOpenCV的-2.4.10OpenCV的-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(); 
    } 


} 
+0

您的應用程序無法識別您的本機功能。試過用gradle來定義你的ndk Homography模塊嗎? – uelordi

+0

是的,我做到了,但沒有奏效。我在android塊中添加了「ndk {moduleName」單應性「 }」。 – Shahzeb

+0

btw我的本地代碼庫未能加載。你能猜出原因嗎? – Shahzeb

回答

0

@uelordi由於FO支持。

我已經把JNI文件夾中的項目目錄的根目錄,所以用ndk-build編譯後,我複製從libs文件夾中生成的*.so文件(在同一目錄下編譯後生成的),以MYAPP/src目錄/主/ jniLibs和我現在可以運行OpenCV代碼。我希望它可以幫助某人。