最近在做这一块,通过我自己的程序,简要写一些笔记。简单说来,先通过一个java类,调用C++的库中的函数
1、先写java类,写好类后,使用javac FeatureExtract.java编译
1 import java.util.List;
2import java.util.ArrayList;
4
5class FeatureExtract
6 {
7 public List<float[]>features;
8 static{
9 try{
10 System.loadLibrary("AsiftGPU"); //调用自己的C++库,libAsiftGPU.so
11 }
12 catch(UnsatisfiedLinkError e){
13 System.err.println("Cannot load ASIFTlibrary\n"+e.toString());
14 }
15 }
16
17 public FeatureExtract(){
18 features = new ArrayList<float[]>();
19 }
21 public nativevoid ExtractASIFT(String filename, List<float[]> features) throws Exception;
22 //声明表明这个函数在引入的C++库中,注意要处理C++函数中抛出的异常
23 public static void main(String[] args){
24 String filename = "01.png";
25
26 FeatureExtrac t = new FeatureExtract();
27
29 try{
30 t.ExtractASIFT(filename,t.features);
31 }catch (Exception e){
32 e.printStackTrace();
33 return;
34 }
35 System.out.println("compute success!");
36
37 }
38 }
2、javah FeatureExtract 让jni自动生成对应的c++头文件FeatureExtract.h,文件内容如下
1 /* DO NOT EDIT THIS FILE - it is machine generated */
2 #include <jni.h>
3/* Header for class FeatureExtract */
4
5#ifndef _Included_FeatureExtract
6#define _Included_FeatureExtract
7#ifdef __cplusplus
8extern "C" {
9#endif
10/*
11 *Class: FeatureExtract
12 *Method: ExtractASIFT
13 *Signature: (Ljava/lang/String;Ljava/util/List;)V
14 */
15 JNIEXPORT void JNICALL Java_FeatureExtract_ExtractASIFT
16 (JNIEnv *, jobject, jstring, jobject);
17
18#ifdef __cplusplus
19 }
20#endif
21#endif
3、实现C++函数,编译生成.so链接库。java的一些基本类型都有对应的类型,例如String对应jstring。
编译的指令为:
gcc -Wall -rdynamic`pkg-config --cflags opencv` -fopenmp-shared -L/home/OpenCV-2.4.3/ lib -lopencv_core -lopencv_highgui-L/usr/local/cuda/lib -L/home/public/HadoopInstall/jdk1. 7.0_07/include -lcudart -olibAsiftGPU.so $(ALL) 把用过的库都要包括上,否则链接成动态链接库时不会报错,但java调用时会出现某函数找不到的情况。
1 #include "jni.h"
2#include "FeatureExtract.h"
5#include <stdio.h>
7#include <string>
8#include "cv.h"
9#include "highgui.h"
10#include <string.h>
11using namespace std;
//jstring可以被转化成char*的,但是不能直接转化成string
39 string jstringtoStr(JNIEnv* env, jstringjstr)
40 {
41 const char* str = env->GetStringUTFChars(jstr,false);
42 string value(str);
43 return value;
44 }
45
46JNIEXPORT void JNICALL Java_FeatureExtractASIFT_1GPU_ExtractASIFT(JNIEnv *env ,jobject arg , jstring filename, jobject list){
47 float* image1;
48 size_t w1, h1;
49 image1 = ReadImage(jstringtoStr(env, filename), &w1, &h1);
50 if(image1 == NULL)
51 return ;
52 printf("%d %d \n", w1, h1);
53
54 SiftParm siftparm;
55 SetDefaultSiftParm(siftparm);
56 vector< vector< KeyPointsList > > keys_all1;
57 int num_of_tilts = NumOfTilts;
58 KeyPointsList keys;
59
60 N= 50;
63 compute_asift_keypoints( image1, w1, h1, num_of_tilts, 0, keys_all1, siftparm);
64
66
67 //get class List
68 jclass list_cls = env->FindClass("java/util/List");//获取java中的list类别
69 if(env->ExceptionOccurred()) //由于上面获取java类可能出错,一定要进行异常捕获!!可能出现java.lang.NULLPointerError
70 {
71 env->ExceptionDescribe();
72 env->ExceptionClear();
73 printf("list class get error!");
74 }
jmethodID list_add =env->GetMethodID(list_cls, "add","(Ljava/lang/Object;)Z"); //获取list的add方法
95 if(env->ExceptionOccurred())
96 {
97 env->ExceptionDescribe();
98 env->ExceptionClear();
99 printf("list add get error!");
100 }
101 jfloatarray[VecLength+4]; //给java float数组赋值
102 for(int i = 0; i < keys_all1.size(); i++){
103 int size = keys_all1[i].size();
104 for(int j = 0; j < size; j++){
105 KeyPointsList temp =keys_all1[i][j];
106 for(int p = 0; p < temp.size();p++){
107 keypoint key = temp[p];
109 array[0] = key.x;
110 array[1] = key.y;
111 array[2] = key.scale;
112 array[3] = key.angle;
113 for(int z = 0; z <VecLength; z++)
114 array[z+4] = key.vec[z];
115 jfloatArray features = env->NewFloatArray(VecLength+4);
116 if(env->ExceptionOccurred())
117 {
118 printf("new floatarray error!");
119 env->ExceptionDescribe();
120 env->ExceptionClear();
121 }
122
123 env->SetFloatArrayRegion(features,0, VecLength+4, array);
124 if(env->ExceptionOccurred())
{
126 printf("set floatarray error!");
127 env->ExceptionDescribe();
128 env->ExceptionClear();
129 }
130 env->CallBooleanMethod(list, list_add, features);
131 if(env->ExceptionOccurred())
132 {
133 printf("addlist error!");
134 env->ExceptionDescribe();
135 env->ExceptionClear();
136 }
137 }
138 }
139 }
140 printf("over!\n");
141 return ;
142 }