caffe的android库编译比较费麻烦,网上的教程操作起来也会有很多的坑。思来想去,把caffe的库和java接口全部包装到一个aar库或者jar库,想用的时候直接导入到项目中,简直是不要太爽。

0 试玩一下andorid demo caffe_android.aar库

如果你想直接运行下效果,我在github上有一个android demo
github:https://github.com/liusanchuan/caffe-android-aar-library

1 添加本地AAR

(0)下载AAR库 https://github.com/liusanchuan/caffe-android-aar-library/blob/master/app/libs/caffe_android.aar
(1) 把 caffe_android.aar文件复制到你自己的项目的app/libs

(2) 在build.gradle(app)中添加引用:

apply plugin: 'com.android.application'

android {
... ...
}
// 这个
repositories {
    flatDir{
        dirs 'libs'
    }
}
dependencies {
    compile (name:'caffe_mobile',ext:'aar') // 和这个
... ...
}

2 Java代码示例

(1) 申请权限

AndroidManifest.xml 中

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

java代码中

private void checkMyPermission() {

    if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
        ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
    }
}

(2)设置运行主函数

// 全局变量
String[] IMAGENET_CLASSES;
CaffeMobile caffeMobile;
String[] IMAGENET_CLASSES;
CNNTask cnnTask;

// 初始化网络
void init_net(){
    // 1. 定义模型路径
    String modelDir = "/sdcard/caffe_mobile/bvlc_reference_caffenet";
    String modelProto = modelDir + "/deploy.prototxt";
    String modelBinary = modelDir + "/bvlc_reference_caffenet.caffemodel";
    // 2 加载标签列表
    AssetManager am = this.getAssets();
    try {
        InputStream is = am.open("synset_words.txt");
        Scanner sc = new Scanner(is);
        List<String> lines = new ArrayList<String>();
        while (sc.hasNextLine()) {
            final String temp = sc.nextLine();
            lines.add(temp.substring(temp.indexOf(" ") + 1));
        }
        IMAGENET_CLASSES = lines.toArray(new String[0]);
    } catch (IOException e) {
        e.printStackTrace();
    }
    // 3. 创建caffe 解释器实例
    caffeMobile = new CaffeMobile();
    caffeMobile.setNumThreads(4);
    caffeMobile.loadModel(modelProto, modelBinary);
    float[] meanValues = {104, 117, 123};
    caffeMobile.setMean(meanValues);
    // 4 创建输出结果监听器
    cnnTask = new CNNTask(new CNNListener() {
        @Override
        public void onTaskCompleted(int i) {
            Toast.makeText(getApplicationContext(),"鉴定结果:"+ IMAGENET_CLASSES[i],Toast.LENGTH_SHORT).show();
        }
    });
}

(3)异步运行的监听器类

private class CNNTask extends AsyncTask<String, Void, Integer> {
    private CNNListener listener;
    private long startTime;

    public CNNTask(CNNListener listener) {
        this.listener = listener;
    }
	// 监听器会把这个任务放后台执行
    @Override
    protected Integer doInBackground(String... strings) {
        startTime = SystemClock.uptimeMillis();
        return caffeMobile.predictImage(strings[0])[0];
    }

    @Override
    protected void onPostExecute(Integer integer) {
        Log.i(LOG_TAG, String.format("elapsed wall time: %d ms", SystemClock.uptimeMillis() - startTime));
        listener.onTaskCompleted(integer);
        super.onPostExecute(integer);
    }
}

(4) 启动神经网络识别任务

// 输入一张图片的路径,在监听器中获取结果
void run_caffe(String imgPath){
    cnnTask.execute(imgPath);
}
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐