编译tensorflow并在Android上运行图像分类

下载bazel并安装

下载地址

chmod +x bazel-version-installer-os.sh
/bazel-version-installer-os.sh --user

下载tensorflow源码

git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git

编译tensorflow

进入tensorflow目录并configure, 按照提示选择即可

cd tensorflow
./configure
bazel build -c opt --config=cuda //tensorflow/tools/pip_package:build_pip_package

注意configure之前应当检查LD_LIBRARY_PATH等环境变量,不正确的环境变量可能会导致错误

制作whl包并安装

生成python安装包并安装。如果系统中已安装其他版本的tensorflow,此步骤会覆盖系统版本。如果仅编译Android版本,则此步骤可省略

mkdir /tmp/tensorflow_pkg
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
python -m pip install /tmp/tensorflow_pkg/tensorflow-0.10.0-py2-none-any.whl

安卓demo编译

修改tensorflow/WORKSPACE,将以下内容注释去掉,并填入正确的Android Studio路径
需要保证sdk和ndk均已正确安装, 并且sdk路径、api的版本、build tool、ndk版本都需要与已安装的版本完全一致

android_sdk_repository(
    name = "androidsdk",
    api_level = 23,
    build_tools_version = "23.0.3",
    # Replace with path to Android SDK on your system
    path = "/home/yaochuanqi/Android/Sdk",
)
android_ndk_repository(
    name="androidndk",
    path="/home/yaochuanqi/Android/Sdk/ndk-bundle",
    api_level=21)

下载weight文件解压到assets目录
Inceptionv5下载地址
下载后的inceptionv5是用于物体识别分类(TF Classify)的weight,其他两个应用(transfer style、detection)的weight给出的链接并不正确。
使用bazel命令行进行编译,加上–verbose_failures是为了在编译出错时查看详细信息

bazel build --verbose_failures -c opt //tensorflow/examples/android:tensorflow_demo

如果执行成功,则会在生成安装包在bazel-bin/tensorflow/examples/android/tensorflow_demo.apk

使用Android studio编译demo

首先保证前面的编译均没有问题,也就是能够使用bazel正确编译
然后修改tensorflow/examples/android/build.gradle文件,将bazel的位置填入

def bazel_location = '/home/yaochuanqi/bin/bazel'

使用Android Studio 导入该工程,并打开build.gradle
在task copyNativeLibs处右键,run gradle:copyNativeLibs生成libtensorflow_demo.so,大概需要10分钟时间。
如果编译没有问题的话,就可以正常build apk了。安装后,运行TF Classify可以识别摄像头拍摄到的物体。

在自己的Android项目中使用tensorflow

如果需要在自己的项目中使用tensorflow,只需要将上一步编译好libtensorfow_demo.so
以及demo程序中的
org/tensorflow/contrib/android/TensorFlowInferenceInterface.java
org/tensorflow/demo/Classifier.java
org/tensorflow/demo/TensorFlowImageClassifier.java
assets/imagenet_comp_graph_label_strings.txt
assets/tensorflow_inception_graph.pb
三个文件加入到工程中的正确目录即可使用tensorflow的图像分类功能。

public class MainActivity extends Activity {

    private static final int NUM_CLASSES = 1008;
    private static final int INPUT_SIZE = 224;
    private static final int IMAGE_MEAN = 117;
    private static final float IMAGE_STD = 1;
    private static final String INPUT_NAME = "input:0";
    private static final String OUTPUT_NAME = "output:0";
    private static final String MODEL_FILE = "file:///android_asset/tensorflow_inception_graph.pb";
    private static final String LABEL_FILE = "file:///android_asset/imagenet_comp_graph_label_strings.txt";
    private Classifier classifier;


    private Bitmap cropImageAndResize(Bitmap srcBmp)
    {
        Bitmap dst;
        if (srcBmp.getWidth() >= srcBmp.getHeight()){

            dst = Bitmap.createBitmap(
                    srcBmp,
                    srcBmp.getWidth()/2 - srcBmp.getHeight()/2,
                    0,
                    srcBmp.getHeight(),
                    srcBmp.getHeight()
                    );
        }else{
            dst = Bitmap.createBitmap(
                    srcBmp,
                    0,
                    srcBmp.getHeight()/2 - srcBmp.getWidth()/2,
                    srcBmp.getWidth(),
                    srcBmp.getWidth()
                    );
        }
        return Bitmap.createScaledBitmap(dst.copy(Bitmap.Config.ARGB_8888,true), INPUT_SIZE, INPUT_SIZE, false);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        try {
              classifier =
              TensorFlowImageClassifier.create(
                  getAssets(),
                  MODEL_FILE,
                  LABEL_FILE,
                  NUM_CLASSES,
                  INPUT_SIZE,
                  IMAGE_MEAN,
                  IMAGE_STD,
                  INPUT_NAME,
                  OUTPUT_NAME);
        } catch (final Exception e) {
              throw new RuntimeException("Error initializing TensorFlow!", e);
        }
        InputStream is = getResources().openRawResource(R.raw.example);
                Bitmap bitmap = BitmapFactory.decodeStream(is);
        final List results = classifier.recognizeImage(cropImageAndResize(bmp));
        if(results.size()>0) {
            String title = results.get(0).getTitle();
            system.out.println(title);
        }
    }
}

你可能感兴趣的:(python)