1

Firebase 関数でトレーニングされた AutoML モデルによって予測されたラベルを画像に付けようとしています。この画像は Google Cloud Storage に保存されています。この方法で画像を読み取ろうとしました:

const gcs = require('@google-cloud/storage')();
const myBucket = gcs.bucket(object.bucket);
const file = myBucket.file(object.name);
const stream = file.createReadStream();

var data = '';
stream.on('error', function(err) {
  console.log("error");
})
.on('data', function(chunk) {
  data = data + chunk;
  console.log("Writing data");
})
.on('end', function() {
});

データの読み取りが完了したら、データを「バイナリ」形式に転送します

var encoded = new Buffer(data)
encoded = encoded.toString('binary');

しかし、これらのエンコードされたデータを「imageBytes」にフィードします。

const payload = {
  "image": {
    "imageBytes": encoded
  },
};
var formattedName = client.modelPath(project, location, model);

var request = {
  name: formattedName,
  payload: payload,
};

client.predict(request)
.then(responses => {
  console.log("responses:", responses);
  var response = responses[0];

  console.log("response:", response);
})
.catch(err => {
  console.error(err);
});

エラーがスローされます:

Error: invalid encoding
at Error (native)
at Object.decode (/user_code/node_modules/@google-cloud/automl/node_modules/@protobufjs/base64/index.js:105:19)
at Type.Image$fromObject [as fromObject] (eval at Codegen (/user_code/node_modules/@google-cloud/automl/node_modules/@protobufjs/codegen/index.js:50:33), <anonymous>:9:15)
at Type.ExamplePayload$fromObject [as fromObject] (eval at Codegen (/user_code/node_modules/@google-cloud/automl/node_modules/@protobufjs/codegen/index.js:50:33), <anonymous>:10:20)
at Type.PredictRequest$fromObject [as fromObject] (eval at Codegen (/user_code/node_modules/@google-cloud/automl/node_modules/@protobufjs/codegen/index.js:50:33), <anonymous>:13:22)
at serialize (/user_code/node_modules/@google-cloud/automl/node_modules/grpc/src/protobuf_js_6_common.js:70:23)
at Object.final_requester.sendMessage (/user_code/node_modules/@google-cloud/automl/node_modules/grpc/src/client_interceptors.js:802:37)
at InterceptingCall._callNext (/user_code/node_modules/@google-cloud/automl/node_modules/grpc/src/client_interceptors.js:418:43)
at InterceptingCall.sendMessage (/user_code/node_modules/@google-cloud/automl/node_modules/grpc/src/client_interceptors.js:460:8)
at InterceptingCall._callNext (/user_code/node_modules/@google-cloud/automl/node_modules/grpc/src/client_interceptors.js:424:12)

しかし、画像を「base64」でエンコードすると、エラーがスローされます。

Error: 3 INVALID_ARGUMENT: Provided image is not valid.
at Object.exports.createStatusError (/user_code/node_modules/@google-cloud/automl/node_modules/grpc/src/common.js:87:15)
at Object.onReceiveStatus (/user_code/node_modules/@google-cloud/automl/node_modules/grpc/src/client_interceptors.js:1188:28)
at InterceptingListener._callNext (/user_code/node_modules/@google-cloud/automl/node_modules/grpc/src/client_interceptors.js:564:42)
at InterceptingListener.onReceiveStatus (/user_code/node_modules/@google-cloud/automl/node_modules/grpc/src/client_interceptors.js:614:8)
at callback (/user_code/node_modules/@google-cloud/automl/node_modules/grpc/src/client_interceptors.js:841:24)
code: 3,
metadata: Metadata { _internal_repr: { 'grpc-server-stats-bin': [Object] } },
details: 'Provided image is not valid.' 

Pythonでもローカル画像ファイル予測を試みましたが、「バイナリ」バイナリ表現を使用しており、うまく機能しています。Python で「base64」を使用すると、「提供されたイメージは無効です」が返されます。firebase 関数のように。

Cloud Storage から画像を間違った方法で読み取ったのか、画像を間違った方法でエンコードしたのか、混乱しています。

完全な Firebase 関数のコード:

const automl = require('@google-cloud/automl');
var client = new automl.v1beta1.PredictionServiceClient();
const gcs = require('@google-cloud/storage')();
const myBucket = gcs.bucket(object.bucket);
const file = myBucket.file(object.name);
const stream = file.createReadStream();
var data = '';
stream.on('error', function(err) {
  console.log("error");
})
.on('data', function(chunk) {
  data = data + chunk;
  console.log("Writing data");
})
.on('end', function() {
  var encoded = new Buffer(data)
  encoded = encoded.toString('binary');
  console.log("binary:", encoded);

  const payload = {
    "image": {
      "imageBytes": encoded
    },

  };

  var formattedName = client.modelPath(project, location, model);

  var request = {
    name: formattedName,
    payload: payload,
  };

  client.predict(request)
  .then(responses => {
    console.log("responses:", responses);
    var response = responses[0];

    console.log("response:", response);
  })
  .catch(err => {
    console.error(err);
  });
  stream.destroy();
});

Python での完全なコード:

import sys

from google.cloud import automl_v1beta1
from google.cloud.automl_v1beta1.proto import service_pb2

# Import the base64 encoding library.
import base64


def get_prediction(content, project_id, model_id):
  prediction_client = automl_v1beta1.PredictionServiceClient()

  name = 'projects/{}/locations/us-central1/models/{}'.format(project_id, model_id)
  payload = {'image': {'image_bytes': content }}

  params = {}
  request = prediction_client.predict(name, payload, params)
  return request  # waits till request is returned

if __name__ == '__main__':
  file_path = sys.argv[1]
  project_id = sys.argv[2]
  model_id = sys.argv[3]
  with open(file_path, 'rb') as ff:
    content = ff.read()
    print(content)
    # Encoded as base64
    # content = base64.b64encode(content)

  print(get_prediction(content, project_id,  model_id))
4

1 に答える 1

0

私はfile.download()を使用していますが、動作します。

file.download().then(imageData => {
  const image = imageData[0];
  const buffer = image.toString('base64');
  const payload = {
    "image": {
      "imageBytes": buffer
    }
  }
  const request = {
    name: formattedName,
    payload: payload
  };
  client.predict(request).then(result => {
    console.log('predict:', result);
  }).catch(err => console.error(err));
});
于 2018-08-08T01:45:17.943 に答える