首先,我很抱歉我可能出现英语错误。我试图使用JNI从我的Java应用程序调用C ++ / OpenCV函数(返回直方图),该应用程序使用Processing(我使用Kinect进行手势识别,我想调用C ++代码来比较一些直方图)即时的)。要做到这一点,我部分遵循这个tuto: ibm.com/developerworks/java/tutorials/j-jni/j-jni.html
我使用Eclipse和Visual Studio 2010,Windows 8 64位,JDK 1.8 32位。
所以我使用javac构建我的类文件没有问题但是当我尝试使用javah构建我的头文件时出现此错误:
Error: cannot access processing.core.PApplet
class file for processing.core.PApplet not found
请注意,如果我不尝试使用我的javah工具,那么我的Java程序会正确编译并运行(在这种情况下,当它尝试调用JNI方法时崩溃)
以下是我的代码:
MyProcessingSketch.java
package v2;
//imports
public class MyProcessingSketch extends PApplet {
//various attributes
public native static void histo(String inFile, long addr);
static {
System.load("C:/Users/Richard/Documents/Visual Studio 2010/Projects/Test/Debug/Test.dll");
}
//various methods, among them setup() and draw()
public static Mat histogram(String inFile)
{
Mat m=new Mat();
histo(folder+inFile, m.getNativeObjAddr());
return m;
}
public static void main(String args[]) {
PApplet.main(new String[] { "--present", "v2.MyProcessingSketch" });
}
}
Test.cpp的
#include "c:/users/richard/workspace/Kinect/src/v2_MyProcessingSketch.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
JNIEXPORT void JNICALL Java_v2_MyProcessingSketch_histo (JNIEnv *env, jobject obj, jstring inFile, jlong addr) {
Mat base;
const char* str = env->GetStringUTFChars(inFile, 0);
base = imread(str, 1 );
/// Convert to HSV
cvtColor( base, base, COLOR_BGR2HSV );
/// Using 50 bins for hue and 60 for saturation
int h_bins = 50; int s_bins = 60;
int histSize[] = { h_bins, s_bins };
// hue varies from 0 to 179, saturation from 0 to 255
float h_ranges[] = { 0, 180 };
float s_ranges[] = { 0, 256 };
const float* ranges[] = { h_ranges, s_ranges };
// Use the o-th and 1-st channels
int channels[] = { 0, 1 };
/// Histograms
Mat hist;
/// Calculate the histograms for the HSV images
calcHist( &base, 1, channels, Mat(), hist, 2, histSize, ranges, true, false );
normalize( hist, hist, 0, 1, NORM_MINMAX, -1, Mat() );
Mat* mat=(Mat*) addr;
mat->create(hist.rows, hist.cols, hist.type());
memcpy(mat->data, (&hist)->data, mat->step * mat->rows);
}
int main(){return 0;}
我的Eclipse工具
Javac工具:http://hpics.li/4c612ea
Javah工具+我的项目资源管理器:http://hpics.li/1054ea2
请注意,在相同的C ++代码(仅通过替换名称和包含)和没有Processing部分的其他Java代码的情况下,所有工作都适用,例如:
Test.java
package v2;
//imports
public class Test {
public native static void histo(String inFile, long addr);
static {
System.load("C:/Users/Richard/Documents/Visual Studio 2010/Projects/Test/Debug/Test.dll");
}
public static void main(String[] args)
{
Mat m = new Mat();
Mat m2 = new Mat();
histo(folder+"front.jpg", m.getNativeObjAddr());
histo(folder+"up.jpg", m2.getNativeObjAddr());
System.out.println(Imgproc.compareHist(m, m2, Imgproc.CV_COMP_BHATTACHARYYA));
}
}
提前致谢!
编辑:
我不知道为什么(而且非常恼人),但最后javah建立了我的头文件:
v2_MyProcessingSketch.h
**/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class v2_MyProcessingSketch */
#ifndef _Included_v2_MyProcessingSketch
#define _Included_v2_MyProcessingSketch
#ifdef __cplusplus
extern "C" {
#endif
#undef v2_MyProcessingSketch_serialVersionUID
#define v2_MyProcessingSketch_serialVersionUID 1i64
/*
* Class: v2_MyProcessingSketch
* Method: histo
* Signature: (Ljava/lang/String;J)V
*/
JNIEXPORT void JNICALL Java_v2_MyProcessingSketch_histo
(JNIEnv *, jclass, jstring, jlong);
#ifdef __cplusplus
}
#endif
#endif
v2_MyProcessingSketch_DisposeHandler.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class v2_MyProcessingSketch_DisposeHandler */
#ifndef _Included_v2_MyProcessingSketch_DisposeHandler
#define _Included_v2_MyProcessingSketch_DisposeHandler
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
但是当我的程序调用本机函数时,我遇到了一个新错误:
Exception in thread "Animation Thread" java.lang.UnsatisfiedLinkError:v2.MyProcessingSketch.histo(Ljava/lang/String;J)V