3

我正在开发一个涉及一些图像处理的 Android 应用程序。我现在正在使用 OpenCV 拼接图像。我正在用 C++ 做。因此,我将 OpenCV(本地 c++ 和 Java)集成到我的 Android 项目中。但是当我在 c++ 中使用拼接功能并运行我的项目时,它给了我编译错误。

这是我用于拼接图像的整个 c++ 库(native-lib)。

//
// Created by Acer on 3/28/2018.
//

#include <jni.h>
#include <string>

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <iostream>
#include <fstream>
#include <opencv2/stitching.hpp>

using namespace std;
using namespace cv;

extern "C" {
jstring
Java_media_memento_memento_SphereCameraActivity_stitchPhotos(
        JNIEnv *env,
        jobject /* this */, jlong addrMat, jlong addrNewMat, jlongArray addrsPreviews) {



    Mat &in = *(Mat *) addrMat;
    Mat &newMat = *(Mat *) addrNewMat;
    int size = env->GetArrayLength(addrsPreviews);
    jlong *addrPreviewArray = env->GetLongArrayElements(addrsPreviews, NULL);
    vector<Mat> imgs(size);
    for (long i = 0; i < size; i++) {
        jlong previewAddress = addrPreviewArray[i];
        imgs[i] = *(Mat *) previewAddress;
    }


    bool try_use_gpu = false;
    Mat pano;
    Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
    Stitcher::Status status = stitcher.stitch(imgs, pano);

    if (status != Stitcher::OK) {
        //the return map would be null
    } else {
        //copy the map.
        pano.copyTo(newMat);
        newMat = pano;
    }

    env->ReleaseLongArrayElements(addrsPreviews, addrPreviewArray, 0);
}

}

这是我的 CMakeList.txt 文件

set(pathToProject C:/Users/iljim/Desktop/memento/memento-android)
set(pathToOpenCv C:/Users/iljim/Desktop/OpenCV-3.1.0-android-sdk/OpenCV-android-sdk)

# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.

cmake_minimum_required(VERSION 3.4.1)

set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")

include_directories(C:/Users/iljim/Desktop/OpenCV-3.1.0-android-sdk/OpenCV-android-sdk/sdk/native/jni/include)


# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add_library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.

add_library( # Specifies the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )

add_library( # Specifies the name of the library.
            cubemap

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/cubemap.cpp )


add_library( lib_opencv SHARED IMPORTED )
set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so)




# Searches for a specified prebuilt library and stores the path as a
# variable. Because system libraries are included in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in the
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       native-lib

                       # OpenCV lib
                       lib_opencv

                       # Cubemap lib
                       cubemap

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

当我运行时,我得到了提到的错误。

Error:error: linker command failed with exit code 1 (use -v to see invocation)
Error:(49) undefined reference to 'cv::Stitcher::createDefault(bool)'
Error:(50) undefined reference to 'cv::Stitcher::stitch(cv::_InputArray const&, cv::_OutputArray const&)'

我找到了这个链接 -对 `cv::Stitcher::createDefault(bool)' 的未定义引用。但我相信我正确地集成了 c++ opencv 本机库。这就是为什么我可以使用其他库。当我检查 SDK 文件夹中的文件时,stitching.hpp 存在。那么,什么是可能的,我该如何解决呢?

4

1 回答 1

2

我有一个非常相似的问题,并通过在我的 CMakeLists.txt 文件中链接来自 OpenCV SDK 的“libopencv_stitching.a”静态库来解决它。

file(GLOB CVLIBS 
path/to/your/opencv/sdk/staticlibs/${ANDROID_ABI}/libopencv_stitching.a)
...
target_link_libraries( # Specifies the target library.
...
${CVLIBS}
# Links the target library to the log library
# included in the NDK.
${log-lib})

这个答案也很有用:Building OpenCV for Android and using it with the NDK

于 2020-02-28T08:57:47.123 回答