如何使用适用于Android的Google Cloud Machine Learning Services

这些天的新闻充满了自动化,人工智能和机器学习等流行语。 这可能就是为什么越来越多的智能手机用户开始寻找更智能的应用程序的原因。 但是,作为一名常规的Android应用程序开发人员,您可能缺少从头开始创建此类应用程序所需的资源。

幸运的是,Google最近推出了一个Cloud Machine Learning平台,该平台提供了经过预先训练以执行各种任务的神经网络。 它的大多数模型不仅高度准确,而且还在不断改进。 你猜怎么着? 您可以通过简单地进行一些REST API调用来使用它们!

在本教程中,我将向您介绍Cloud Machine Learning平台,并向您展示如何使用它来创建一个智能Android应用程序,该应用程序可以识别现实世界中的对象并以多种语言对其进行命名。

先决条件

要充分利用本教程,您需要做的是:

1.获取API密钥

为了能够在您的Android应用中使用Google的机器学习服务,您需要一个API密钥。 您可以通过在Google Cloud Platform 控制台中创建一个新项目来获得一个。

首先登录控制台,然后按“ 创建新项目”按钮。 在弹出的对话框中,为项目指定一个有意义的名称。

建立新专案

创建项目后,转到“ API管理器”>“仪表板” ,然后按“ 启用API”按钮。

在下一屏幕的Google Cloud Machine Learning标题下,您将能够看到所有可用的机器学习API。 在本教程中,我们将仅使用视觉翻译 API。

机器学习库

要启用Vision API,请单击其链接,然后按启用按钮。

启用视觉API

同样,要启用Translation API,请点击其链接,然后按启用按钮。

您只需一个密钥即可使用这两个API。 要获取它,请转到“ 凭证”选项卡,按“ 创建凭证”按钮,然后选择“ API密钥”

选择API密钥

现在,您应该会看到一个包含您的秘密API密钥的弹出窗口。

2.创建一个新的Android项目

启动Android Studio并创建一个活动为空的新项目。 我建议您至少为最低支持的SDK选择API级别19。

尽管您不必这样做,但是使用强大的网络库与Google Cloud Machine Learning平台进行通信始终是一个好主意。 在本教程中,我们将使用一个名为Fuel的此类库。 将其作为compile依赖项添加到app模块的build.gradle文件中:

compile 'com.github.kittinunf.fuel:fuel-android:1.5.0'

立即同步以更新您的项目。

接下来,我们的应用将需要INTERNET权限才能与Google的服务器进行通信。 因此,在项目的清单文件中添加以下行:

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

最后,将您的API密钥添加到values / strings.xml文件中:

<string name="mykey">ABCDEF12345-abcdef12345-123</string>

3.使用视觉API

Vision API可帮助您创建可以查看并了解用户环境的应用程序。 人脸检测,情感检测,光学字符识别和图像注释是其许多功能中的一部分。 目前,我们将仅关注功能强大的图像注释功能,也称为标签检测-我认为这非常有用。

如您所料,API希望将图片作为其输入之一。 因此,现在让我们创建一个屏幕,用户可以在其中使用设备的相机拍照。

步骤1:建立版面

屏幕的布局应具有用户可以按其拍照的Button小部件,用于显示图片的ImageView小部件以及用于显示API生成的标签或注释的TextView小部件。 因此,将以下代码添加到活动的布局XML文件中:

<Button android:text="Take a picture"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/takePictureButton"
    android:onClick="takePicture"/>

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/takePictureButton"
    android:id="@+id/previewImage"
    android:layout_centerHorizontal="true"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/resultsText"
    android:layout_below="@id/previewImage"/>

请注意,我们已经将onClick处理程序与按钮相关联。 我们将在下一步中定义它。

步骤2:建立意图

通过使用ACTION_IMAGE_CAPTURE动作创建一个新的意图并将其传递给startActivityForResult()方法,您可以要求用户设备的默认相机应用进行拍照并将其传递给您的应用。 因此,将以下代码添加到您的Activity类:

public final static int MY_REQUEST_CODE = 1;

public void takePicture(View view) {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent, MY_REQUEST_CODE);
}

为了接收默认相机应用程序捕获的图像,您必须重写Activity类的onActivityResult()方法。 在该方法内部,您可以访问包含所有图像数据的Bundle对象。 您可以通过简单地将其转换为Bitmap并将其传递给ImageView小部件来渲染图像数据。

@Override
protected void onActivityResult(int requestCode, int resultCode,
                                Intent data) {
    if(requestCode == MY_REQUEST_CODE && resultCode == RESULT_OK) {

        // Convert image data to bitmap
        Bitmap picture = (Bitmap)data.getExtras().get("data");

        // Set the bitmap as the source of the ImageView
        ((ImageView)findViewById(R.id.previewImage))
                                .setImageBitmap(picture);

        // More code goes here
    }
}

如果您现在运行该应用程序并拍照,您将看到图片的尺寸很小。 没关系,即使有图像缩略图,Cloud Vision API也非常准确。

步骤3:对图像进行编码

视觉API无法直接使用Bitmap对象。 相反,它需要压缩图像数据的Base64编码字符串。

若要压缩图像数据,可以使用Bitmap类的compress()方法。 作为其参数,该方法期望使用压缩格式,所需的输出质量和ByteArrayOutputStream对象。 以下代码使用JPEG格式压缩位图,并确保生成的图像的质量足够高:

ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
picture.compress(Bitmap.CompressFormat.JPEG, 90, byteStream);

现在,您可以使用Base64类的encodeToString()方法生成Base64字符串。

String base64Data = Base64.encodeToString(byteStream.toByteArray(), 
                                          Base64.URL_SAFE);

步骤4:处理图像

经过所有这些艰苦的工作,您拥有了与Vision API交互所需的一切。 首先创建一个包含API URL和API密钥的字符串:

String requestURL = 
        "https://vision.googleapis.com/v1/images:annotate?key=" +
         getResources().getString(R.string.mykey);

要将数据发送到API,您必须创建一个HTTP POST请求。 请求的正文必须是包含Base64编码的图像数据的JSON文档。 对于标签检测,文档还必须具有一个包含值LABEL_DETECTIONfeatures数组。 这是JSON文档的格式:

{"requests": [{
      "image": {
        "content": <Base64-encoded image data>
      },
      "features": [{
          "type": "LABEL_DETECTION"
      }]
}]}

尽管可以手动编码JSON文档,但是以编程方式创建它的错误率较低。 以下代码显示了如何使用JSONObjectJSONArray类来执行此操作:

// Create an array containing
// the LABEL_DETECTION feature
JSONArray features = new JSONArray();
JSONObject feature = new JSONObject();
feature.put("type", "LABEL_DETECTION");
features.put(feature);

// Create an object containing
// the Base64-encoded image data
JSONObject imageContent = new JSONObject();
imageContent.put("content", base64Data);

// Put the array and object into a single request
// and then put the request into an array of requests
JSONArray requests = new JSONArray();
JSONObject request = new JSONObject();
request.put("image", imageContent);
request.put("features", features);
requests.put(request);
JSONObject postData = new JSONObject();
postData.put("requests", requests);

// Convert the JSON into a
// string
String body = postData.toString();

至此,我们可以使用Fuel类的post()方法发出HTTP POST请求。 作为唯一的参数,该方法需要API的URL。 您还必须在请求中包含content-lengthcontent-type标头。 为此,请使用header()方法。 同样,为了将JSON文档添加到POST请求的主体中,请使用post()方法。

最后,通过调用responseString()方法并向其传递Handler类的新实例,您可以以字符串的形式异步获取请求的响应。 相应地,添加以下代码:

Fuel.post(requestURL)
    .header(
        new Pair<String, Object>("content-length", body.length()),
        new Pair<String, Object>("content-type", "application/json")
        )
    .body(body.getBytes())
    .responseString(new Handler<String>() {
        @Override
        public void success(@NotNull Request request,
                            @NotNull Response response,
                            String data) {
            // More code goes here
        }

        @Override
        public void failure(@NotNull Request request,
                            @NotNull Response response,
                            @NotNull FuelError fuelError) {}
    });

使用标签检测功能时,Vision API将返回包含标签的JSON文档。 与每个标签一起,您还将获得一个分数,用于指定标签的准确性。 该文档如下所示:

{"responses":[{
  "labelAnnotations": [
    {
      "mid": "/m/id1",
      "description": "label1",
      "score": 0.91
    },
    {
      "mid": "/m/id2",
      "description": "label2",
      "score": 0.90
    },
  ...
}]}

现在,让我们循环遍历labelAnnotations数组中的所有对象,并将每个description键的值添加到布局的TextView小部件中。 您可以在Handler类的success()方法中执行以下操作:

// Access the labelAnnotations arrays
JSONArray labels = new JSONObject(data)
                    .getJSONArray("responses")
                    .getJSONObject(0)
                    .getJSONArray("labelAnnotations");

String results = "";

// Loop through the array and extract the
// description key for each item
for(int i=0;i<labels.length();i++) {
    results = results + 
              labels.getJSONObject(i).getString("description") +
              "\n";
}

// Display the annotations inside the TextView
((TextView)findViewById(R.id.resultsText)).setText(results);

现在,您可以运行该应用程序,为附近的任何物体拍照,并查看Vision API为其生成的标签。

为笔记本电脑生成的标签

4.使用翻译API

顾名思义,Cloud Translation API可以在100多种语言之间来回翻译文本。 通过有效地使用它,您可以创建可以使用自己的语言与用户通信的智能应用程序。

在上一步中,您看到我们的应用程序生成的标签是英文的。 现在让我们向其添加一个按钮,以将这些标签翻译为德语。

步骤1:更新版面

使用以下代码在活动布局的末尾添加一个Button小部件:

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/resultsText"
    android:text="in German"
    android:onClick="translateToGerman"/>

注意,此按钮也具有必须在您的Activity类中定义的onClick事件处理程序。

步骤2:翻译标签

使用Translation API比使用Vision API容易得多,这主要是因为您不必创建JSON文档来定义请求。 相反,您只需在查询字符串中将参数传递给它即可。

创建translateToGerman()方法,并在其中创建一个包含Translation API URL的字符串。

public void translateToGerman(View view) {
    String requestURL = 
        "https://translation.googleapis.com/language/translate/v2";

    // More code goes here
}

要将字段添加到上述URL的查询字符串中,我们可以使用Pair对象List 。 以下字段很重要:

  • key ,指定您的秘密API密钥
  • source ,指定您要翻译的语言
  • target ,指定要翻译成的语言
  • q ,指定要翻译的文本

以下代码显示了如何配置API以将英语翻译为德语:

List<Pair<String, String>> params = new ArrayList<>();
// Add API key
params.add(new Pair<String, String>("key", 
                        getResources().getString(R.string.mykey)));

// Set source and target languages
params.add(new Pair<String, String>("source", "en"));
params.add(new Pair<String, String>("target", "de"));

由于查询字符串可以包含多个q字段,因此我们将为布局的TextView小部件中存在的每个标签添加一个。 这是如何做:

String[] queries = ((TextView)findViewById(R.id.resultsText))
                    .getText().toString().split("\n");

for(String query:queries) {
    params.add(new Pair<String, String>("q", query));
}

最后,您可以调用Fuel类的get()方法向Translation API发出HTTP GET请求。 同样,这一次,您也可以使用responseString()方法以字符串形式异步获取响应。

Fuel.get(requestURL, params).responseString(new Handler<String>() {
    @Override
    public void success(@NotNull Request request, 
                        @NotNull Response response,
                        String data) {
        // More code here
    }

    @Override
    public void failure(@NotNull Request request, 
                        @NotNull Response response, 
                        @NotNull FuelError fuelError) { }
});

Translation API的响应是一个包含一系列翻译的JSON文档。 它具有以下格式:

{ "data": { "translations": [
  {
    "translatedText": "...."
  },
  {
    "translatedText": "...."
  },
  ...
] } }

现在,在Handler类的success()方法内部,让我们简单地循环浏览上述JSON文档的translations数组,并使用与translatedText键相关联的值更新TextView小部件的内容。

// Access the translations array
JSONArray translations = new JSONObject(data)
                        .getJSONObject("data")
                        .getJSONArray("translations");

// Loop through the array and extract the translatedText
// key for each item
String result = "";
for(int i=0;i<translations.length();i++) {
    result += translations.getJSONObject(i)
                .getString("translatedText") + "\n";
}

// Update the contents of the TextView widget
((TextView)findViewById(R.id.resultsText)).setText(result);

如果现在运行该应用程序,为图片生成标签,然后按第二个按钮,则应该可以看到德语标签。

德语标签

结论

在本教程中,您学习了如何在Android应用中使用Cloud Vision和Cloud Translation API,它们是Google Cloud Machine Learning平台的一部分。 该平台提供了更多此类API。 您可以通过参考官方文档进一步了解它们。

翻译自: https://code.tutsplus.com/tutorials/how-to-use-google-cloud-machine-learning-services-for-android--cms-28630

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值