3

I am developing an Android application that involves some image processing. I am now stitching images using OpenCV. I am doing it in c++. So, I integrated the OpenCV (both native c++ and Java) into my Android project. But when I use the stitching features in c++ and run my project, it is giving me the compilation error.

This is my whole c++ library (native-lib) for stitching images.

//
// 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);
}

}

This is my CMakeList.txt file

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} )

When I run, I got the mentioned error.

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&)'

I found this link - undefined reference to `cv::Stitcher::createDefault(bool)'. But I believe I integrated the c++ opencv native lib properly. That is why I can use other libraries. When I check the file in the SDK folder, the stitching.hpp exists. So, what might be possible and how can I solve it?

Yogi
  • 609
  • 1
  • 8
  • 21
Wai Yan Hein
  • 13,651
  • 35
  • 180
  • 372

1 Answers1

2

I had a quite similar problem and solved it with linking "libopencv_stitching.a" static library from OpenCV SDK in my CMakeLists.txt file.

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})

Also this answer can be useful as well: Building OpenCV for Android and using it with the NDK

Victor Shpyrka
  • 232
  • 3
  • 10