簡體   English   中英

使用JNI獲取“ UnsatisfiedLinkError”以將字符串從C ++傳遞給帶有w / OpenCV的Java

[英]getting 'UnsatisfiedLinkError' using JNI to pass string from C++ to java w/OpenCV

下面的圖片鏈接顯示了我遇到的特定異常。 我不太確定為什么會遇到這個特定問題,因為我已將所有內容都構建在同一目錄中,因此庫文件在那里。 據我了解,這與我從c ++函數返回主方法有關。

我本質上想做的是將識別的人的名字(printId)作為字符串從我的c ++函數傳遞給java。

命令行圖片:

命令行圖片

這是我的C ++代碼:

#include <jni.h>
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/objdetect.hpp"
#include "opencv2/face.hpp"
#include "opencv2/face/facerec.hpp"
#include <vector>
#include <string>
#include "recognitionJNI.h"

#include <fstream>
#include <sstream>

using namespace cv;
using namespace std;


String face_cascade_name = "/Users/greg/Downloads/opencv-3.4.2/data/haarcascades/haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;
String fn_csv = "/Users/greg/Desktop/faceBuild/faceRecognition/faceRecognition/csv.txt";

//User Defined Function for reading csv
static void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ';') {

ifstream file(filename.c_str(), ifstream::in); //opens file for reading
if(!file) {
    cout << "ERROR: There was a problem loading the csv file" << endl;
}

string line, path, classlabel;
while(getline(file,line)) {
    stringstream liness(line);
    getline(liness, path, separator); //read stream object up to the semicolon
    getline(liness, classlabel);      //read the rest of stream object up to null terminated character

    //make sure that the filepath and userID are not empty
    if(!path.empty() && !classlabel.empty()) {
        images.push_back(imread(path,0)); //appends grayscale image to images vector
        labels.push_back(atoi(classlabel.c_str())); //appends userID to labels vector
      }

   }

}

JNIEXPORT jstring JNICALL Java_testJNIString_userName(JNIEnv *env, jobject thisObj, jstring inJNIStr) {

const char *inCStr = env->GetStringUTFChars(inJNIStr, NULL);
if (NULL == inCStr) return NULL;
string outCppStr;

cout << "In C++, the received string is: " << inCStr << endl;
env->ReleaseStringUTFChars(inJNIStr, inCStr);

string printId;
vector<Mat> images; //This vector will hold the images
vector<int> labels; //This vector will hold the userID

//read the csv file contain image paths and userID's
try {
    read_csv(fn_csv, images, labels);
} catch (Exception& e) {
    cerr << "Error opening file\"" << fn_csv << "\". Reason: " << e.msg << endl;
    exit(1);
}
//we'll need to resize the images to their origal size
//These two lines capture the length and width of the mat object
int im_width = images[0].cols;
int im_height = images[0].rows;

for(int j=0; j < images.size(); j++) {
    resize(images[j],images[j],Size(im_width, im_height),1.0,1.0,INTER_CUBIC);
}

//int numComponents = 2;
//double threshold = 10.0;

//creats a faceRecognizer to train with given images
Ptr<cv::face::FisherFaceRecognizer> model = cv::face::FisherFaceRecognizer::create();
model->train(images, labels);

string camera_msg = "No camera found";

Mat webcam;             // creates Mat object for to store frames
VideoCapture cap(0);    // opens default webcam
if(!cap.isOpened()) {
    return env->NewStringUTF(camera_msg.c_str());
}

face_cascade.load(face_cascade_name); //loads xml file into classifier

//load capture device into Mat object
while (cap.read(webcam)) {


    vector<Rect> faces;
    Mat frame_gray; //will be used to store grayscale copy of webcam

    cvtColor(webcam, frame_gray, COLOR_BGR2GRAY); //coverts Mat object frames into grayscale
    equalizeHist(frame_gray, frame_gray);         //maps input distrubution to more uniform distribution


    //locate the faces in the frame
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 5, 0|CASCADE_SCALE_IMAGE,Size(30,30));

    for(size_t i=0; i < faces.size(); i++) {

        Rect face_i = faces[i]; //process faces by frame
        Mat face = frame_gray(face_i); //takes the face from the live images

        //resize faces for prediction
        Mat face_resized;
        resize(face,face_resized,Size(im_width, im_height),1.0,1.0,INTER_CUBIC);

        int prediction = model->predict(face_resized); //predict based on resize faces

        if(prediction == 1 ) {
            printId = "Matthew";
        }
        else if (prediction == 2) {
            printId = "Greg";
            return env->NewStringUTF(printId.c_str());

        }
        else if(prediction != 1 || 2 ){
            printId = "Unknown";
        }

        rectangle(webcam, face_i, CV_RGB(0,255,0), 1); //draws a rectangle around the face
        string box_text = "Prediction = " + printId;

        int pos_x = std::max(face_i.tl().x - 10, 0);
        int pos_y = std::max(face_i.tl().y - 10, 0);

        putText(webcam, box_text, Point(pos_x,pos_y), FONT_HERSHEY_PLAIN, 1.0, CV_RGB(0,255,0), 1);

    }

    imshow("Webcam", webcam);
    waitKey(1);
    destroyAllWindows();

  }

return env->NewStringUTF(printId.c_str());

}

這是我的Java代碼:

public class recognitionJNI{
    static {
    System.loadLibrary("recogjni");
}
    private native String userName(String msg);

    public static void main(String args[]) {
    String result = new recognitionJNI().userName("Pass arg from c++ function");
    System.out.println(result);
    }
}

嘗試重新生成頭文件,看起來您同時更改了類名,並且該名稱不再是最新的。 我從那個Java類得到的名稱是:

Java_recognitionJNI_userName

但是你有

Java_testJNIString_userName

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM