无法在Android JNI中使用c ++ native中的重映射

时间:2018-04-04 10:13:34

标签: android c++ opencv java-native-interface

我正在使用Java开发Android应用程序。在我的应用程序中,我正在进行一些图像处理。所以我使用c ++和Open CV,并通过JNI调用c ++函数。我试图将equirectangular /球形图像转换为立方体贴图图像。

我找到了此转化链接https://code.i-harness.com/en/q/1c4dbae/。我从Java传递Mat并尝试将转换后的图像返回给Java。

这是我的C ++代码

#include <jni.h>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>

using namespace std;
using namespace cv;
extern "C"
JNIEXPORT jstring



JNICALL
Java_media_memento_memento_VRPhotoSphereActivity_convertEquiRectToCubeMap(
        JNIEnv *env,
        jobject /* this */, jlong addrMat, jlong addrNewMat) {


    Mat& mat = *(Mat*)addrMat;
    Mat& newMat = *(Mat*)addrNewMat;

    newMat.create(mat.rows, mat.cols, mat.type());
    memcpy(newMat.data, mat.data , sizeof(mat.data) -1);


    //EquiRec to Cubemap conversion starts from here
    float faceTransform[6][2] =
            {
                    {0, 0},
                    {M_PI / 2, 0},
                    {M_PI, 0},
                    {-M_PI / 2, 0},
                    {0, -M_PI / 2},
                    {0, M_PI / 2}
            };


    //conversion ends here
    const Mat &in= mat;
    Mat face = newMat;
    int faceId = 0;
    const int width = -1;
    const int height = -1;

    float inWidth = in.cols;
    float inHeight = in.rows;

    // Allocate map
    Mat mapx(height, width, CV_32F);
    Mat mapy(height, width, CV_32F);

    // Calculate adjacent (ak) and opposite (an) of the
    // triangle that is spanned from the sphere center
    //to our cube face.
    const float an = sin(M_PI / 4);
    const float ak = cos(M_PI / 4);

    const float ftu = faceTransform[faceId][0];
    const float ftv = faceTransform[faceId][1];

    // For each point in the target image,
    // calculate the corresponding source coordinates.
    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {

            // Map face pixel coordinates to [-1, 1] on plane
            float nx = (float)y / (float)height - 0.5f;
            float ny = (float)x / (float)width - 0.5f;

            nx *= 2;
            ny *= 2;

            // Map [-1, 1] plane coords to [-an, an]
            // thats the coordinates in respect to a unit sphere
            // that contains our box.
            nx *= an;
            ny *= an;

            float u, v;

            // Project from plane to sphere surface.
            if(ftv == 0) {
                // Center faces
                u = atan2(nx, ak);
                v = atan2(ny * cos(u), ak);
                u += ftu;
            } else if(ftv > 0) {
                // Bottom face
                float d = sqrt(nx * nx + ny * ny);
                v = M_PI / 2 - atan2(d, ak);
                u = atan2(ny, nx);
            } else {
                // Top face
                float d = sqrt(nx * nx + ny * ny);
                v = -M_PI / 2 + atan2(d, ak);
                u = atan2(-ny, nx);
            }

            // Map from angular coordinates to [-1, 1], respectively.
            u = u / (M_PI);
            v = v / (M_PI / 2);

            // Warp around, if our coordinates are out of bounds.
            while (v < -1) {
                v += 2;
                u += 1;
            }
            while (v > 1) {
                v -= 2;
                u += 1;
            }

            while(u < -1) {
                u += 2;
            }
            while(u > 1) {
                u -= 2;
            }

            // Map from [-1, 1] to in texture space
            u = u / 2.0f + 0.5f;
            v = v / 2.0f + 0.5f;

            u = u * (inWidth - 1);
            v = v * (inHeight - 1);

            // Save the result for this pixel in map
            mapx.at<float>(x, y) = u;
            mapy.at<float>(x, y) = v;
        }
    }

    // Recreate output image if it has wrong size or type.
    if(face.cols != width || face.rows != height ||
       face.type() != in.type()) {
        face = Mat(width, height, in.type());
    }

    // Do actual resampling using OpenCV's remap
    Mat i = in;
    Mat f = face;
    remap(i, f, mapx, mapy,
          CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));



    //send the image back here. For now the feature is not implemented yet.

    std::string hello = "Spherical equirectangular photo converted to cubemap face photo";
    return env->NewStringUTF(hello.c_str());



}

当我尝试运行我的应用程序时,它给了我这个编译错误。

Error:(146) undefined reference to `cv::remap(cv::_InputArray const&, cv::_OutputArray const&, cv::_InputArray const&, cv::_InputArray const&, int, int, cv::Scalar_<double> const&)'

这是截图。

enter image description here

如何修复该错误?

修改

实际上,它从这一行开始抛出错误

Mat mapx(height, width, CV_32F);
    Mat mapy(height, width, CV_32F);

这是截图

enter image description here

0 个答案:

没有答案