如何在Google机器学习中将jpeg图像转换为json文件

时间:2021-10-14 17:07:01

I'm working on Google cloud ML, and I want to get prediction on jpeg image. To do this, I would like to use:

我正在开发Google云端ML,我希望能够预测jpeg图像。为此,我想使用:

gcloud beta ml predict --instances=INSTANCES --model=MODEL [--version=VERSION]

gcloud beta ml预测--instances = INSTANCES --model = MODEL [--version = VERSION]

(https://cloud.google.com/ml/reference/commandline/predict)

Instances is the path to a json file with all info about image. How can I create the json file from my jpeg image?

Instances是json文件的路径,其中包含有关image的所有信息。如何从jpeg图像创建json文件?

Many thanks!!

3 个解决方案

#1


4  

The first step is to make sure that the graph you export has a placeholder and ops that can accept JPEG data. Note that CloudML assumes you are sending a batch of images. We have to use a tf.map_fn to decode and resize a batch of images. Depending on the model, extra preprocessing of the data may be required to normalize the data, etc. This is shown below:

第一步是确保导出的图形具有占位符和可以接受JPEG数据的操作。请注意,CloudML假定您正在发送一批图像。我们必须使用tf.map_fn来解码和调整一批图像的大小。根据型号的不同,可能需要额外的数据预处理来规范化数据等。如下所示:

# Number of channels in the input image
CHANNELS = 3

# Dimensions of resized images (input to the neural net)
HEIGHT = 200
WIDTH = 200

# A placeholder for a batch of images
images_placeholder = tf.placeholder(dtype=tf.string, shape=(None,))

# The CloudML Prediction API always "feeds" the Tensorflow graph with
# dynamic batch sizes e.g. (?,).  decode_jpeg only processes scalar
# strings because it cannot guarantee a batch of images would have
# the same output size.  We use tf.map_fn to give decode_jpeg a scalar
# string from dynamic batches.
def decode_and_resize(image_str_tensor):
  """Decodes jpeg string, resizes it and returns a uint8 tensor."""

  image = tf.image.decode_jpeg(image_str_tensor, channels=CHANNELS)

  # Note resize expects a batch_size, but tf_map supresses that index,
  # thus we have to expand then squeeze.  Resize returns float32 in the
  # range [0, uint8_max]
  image = tf.expand_dims(image, 0)
  image = tf.image.resize_bilinear(
      image, [HEIGHT, WIDTH], align_corners=False)
  image = tf.squeeze(image, squeeze_dims=[0])
  image = tf.cast(image, dtype=tf.uint8)
  return image

decoded_images = tf.map_fn(
    decode_and_resize, images_placeholder, back_prop=False, dtype=tf.uint8)

# convert_image_dtype, also scales [0, uint8_max] -> [0, 1).
images = tf.image.convert_image_dtype(decoded_images, dtype=tf.float32)

# Then shift images to [-1, 1) (useful for some models such as Inception)
images = tf.sub(images, 0.5)
images = tf.mul(images, 2.0)

# ...

Also, we need to be sure to properly mark the inputs, in this case, it's essential that the name of the input (the key in the map) end in _bytes. When sending base64 encoded data, it will let the CloudML prediction service know it needs to decode the data:

此外,我们需要确保正确标记输入,在这种情况下,输入的名称(地图中的键)以_bytes结尾至关重要。发送base64编码数据时,它会让CloudML预测服务知道它需要解码数据:

inputs = {"image_bytes": images_placeholder.name}
tf.add_to_collection("inputs", json.dumps(inputs))

The data format that the gcloud command is expecting will be of the form:

gcloud命令期望的数据格式将是以下形式:

{"image_bytes": {"b64": "dGVzdAo="}}

(Note, if image_bytes is the only input to your model you can simplify to just {"b64": "dGVzdAo="}).

(注意,如果image_bytes是模型的唯一输入,则可以简化为{“b64”:“dGVzdAo =”})。

For example, to create this from a file on disk, you could try something like:

例如,要从磁盘上的文件创建它,您可以尝试以下方法:

echo "{\"image_bytes\": {\"b64\": \"`base64 image.jpg`\"}}" > instances

And then send it to the service like so:

然后将其发送到服务,如下所示:

gcloud beta ml predict --instances=instances --model=my_model

Please note that when sending data directly to the service, the body of the request you send needs to be wrapped in an "instances" list. So the gcloud command above actually sends the following to the service in the body of the HTTP request:

请注意,当直接向服务发送数据时,您发送的请求正文需要包含在“实例”列表中。所以上面的gcloud命令实际上将以下内容发送到HTTP请求正文中的服务:

{"instances" : [{"image_bytes": {"b64": "dGVzdAo="}}]}

#2


2  

Just to pile onto the previous answer...

只是为了填写上一个答案......

Google published a blog post on the image recognition task and some associated code that will directly address your question and several more you may discover. It includes an images_to_json.py file to help with building the json request

谷歌发布了一篇关于图像识别任务的博客文章和一些相关代码,这些代码将直接解决您的问题以及您可能发现的其他问题。它包含一个images_to_json.py文件,以帮助构建json请求

#3


-1  

In python, you can create the base64 JSON file that works with "gcloud ml-engine predict" with the following code:

在python中,您可以使用以下代码创建与“gcloud ml-engine predict”一起使用的base64 JSON文件:

import json
import base64
with open('path_to_img.jpg', 'rb') as f:
    img_bytes = base64.b64encode(f.read())
json_data = {'image_bytes': {'b64': img_bytes.decode('ascii')}}
with open('path_to_json_file.json', 'w+') as f:
    json.dump(json_data, f)

I spent a long time getting all of this working for a TensorFlow Keras model and Google Cloud ML. After finally getting everything to work, I put together a code example in the hopes that it might help others who are struggling through the same issues with deploying TF models to Google cloud ML. It can be found here: https://github.com/mhwilder/tf-keras-gcloud-deployment.

我花了很长时间才开始使用TensorFlow Keras模型和Google Cloud ML。在最终完成所有工作后,我整理了一个代码示例,希望它可以帮助其他正在努力解决将TF模型部署到Google Cloud ML的相同问题。它可以在这里找到:https://github.com/mhwilder/tf-keras-gcloud-deployment。

#1


4  

The first step is to make sure that the graph you export has a placeholder and ops that can accept JPEG data. Note that CloudML assumes you are sending a batch of images. We have to use a tf.map_fn to decode and resize a batch of images. Depending on the model, extra preprocessing of the data may be required to normalize the data, etc. This is shown below:

第一步是确保导出的图形具有占位符和可以接受JPEG数据的操作。请注意,CloudML假定您正在发送一批图像。我们必须使用tf.map_fn来解码和调整一批图像的大小。根据型号的不同,可能需要额外的数据预处理来规范化数据等。如下所示:

# Number of channels in the input image
CHANNELS = 3

# Dimensions of resized images (input to the neural net)
HEIGHT = 200
WIDTH = 200

# A placeholder for a batch of images
images_placeholder = tf.placeholder(dtype=tf.string, shape=(None,))

# The CloudML Prediction API always "feeds" the Tensorflow graph with
# dynamic batch sizes e.g. (?,).  decode_jpeg only processes scalar
# strings because it cannot guarantee a batch of images would have
# the same output size.  We use tf.map_fn to give decode_jpeg a scalar
# string from dynamic batches.
def decode_and_resize(image_str_tensor):
  """Decodes jpeg string, resizes it and returns a uint8 tensor."""

  image = tf.image.decode_jpeg(image_str_tensor, channels=CHANNELS)

  # Note resize expects a batch_size, but tf_map supresses that index,
  # thus we have to expand then squeeze.  Resize returns float32 in the
  # range [0, uint8_max]
  image = tf.expand_dims(image, 0)
  image = tf.image.resize_bilinear(
      image, [HEIGHT, WIDTH], align_corners=False)
  image = tf.squeeze(image, squeeze_dims=[0])
  image = tf.cast(image, dtype=tf.uint8)
  return image

decoded_images = tf.map_fn(
    decode_and_resize, images_placeholder, back_prop=False, dtype=tf.uint8)

# convert_image_dtype, also scales [0, uint8_max] -> [0, 1).
images = tf.image.convert_image_dtype(decoded_images, dtype=tf.float32)

# Then shift images to [-1, 1) (useful for some models such as Inception)
images = tf.sub(images, 0.5)
images = tf.mul(images, 2.0)

# ...

Also, we need to be sure to properly mark the inputs, in this case, it's essential that the name of the input (the key in the map) end in _bytes. When sending base64 encoded data, it will let the CloudML prediction service know it needs to decode the data:

此外,我们需要确保正确标记输入,在这种情况下,输入的名称(地图中的键)以_bytes结尾至关重要。发送base64编码数据时,它会让CloudML预测服务知道它需要解码数据:

inputs = {"image_bytes": images_placeholder.name}
tf.add_to_collection("inputs", json.dumps(inputs))

The data format that the gcloud command is expecting will be of the form:

gcloud命令期望的数据格式将是以下形式:

{"image_bytes": {"b64": "dGVzdAo="}}

(Note, if image_bytes is the only input to your model you can simplify to just {"b64": "dGVzdAo="}).

(注意,如果image_bytes是模型的唯一输入,则可以简化为{“b64”:“dGVzdAo =”})。

For example, to create this from a file on disk, you could try something like:

例如,要从磁盘上的文件创建它,您可以尝试以下方法:

echo "{\"image_bytes\": {\"b64\": \"`base64 image.jpg`\"}}" > instances

And then send it to the service like so:

然后将其发送到服务,如下所示:

gcloud beta ml predict --instances=instances --model=my_model

Please note that when sending data directly to the service, the body of the request you send needs to be wrapped in an "instances" list. So the gcloud command above actually sends the following to the service in the body of the HTTP request:

请注意,当直接向服务发送数据时,您发送的请求正文需要包含在“实例”列表中。所以上面的gcloud命令实际上将以下内容发送到HTTP请求正文中的服务:

{"instances" : [{"image_bytes": {"b64": "dGVzdAo="}}]}

#2


2  

Just to pile onto the previous answer...

只是为了填写上一个答案......

Google published a blog post on the image recognition task and some associated code that will directly address your question and several more you may discover. It includes an images_to_json.py file to help with building the json request

谷歌发布了一篇关于图像识别任务的博客文章和一些相关代码,这些代码将直接解决您的问题以及您可能发现的其他问题。它包含一个images_to_json.py文件,以帮助构建json请求

#3


-1  

In python, you can create the base64 JSON file that works with "gcloud ml-engine predict" with the following code:

在python中,您可以使用以下代码创建与“gcloud ml-engine predict”一起使用的base64 JSON文件:

import json
import base64
with open('path_to_img.jpg', 'rb') as f:
    img_bytes = base64.b64encode(f.read())
json_data = {'image_bytes': {'b64': img_bytes.decode('ascii')}}
with open('path_to_json_file.json', 'w+') as f:
    json.dump(json_data, f)

I spent a long time getting all of this working for a TensorFlow Keras model and Google Cloud ML. After finally getting everything to work, I put together a code example in the hopes that it might help others who are struggling through the same issues with deploying TF models to Google cloud ML. It can be found here: https://github.com/mhwilder/tf-keras-gcloud-deployment.

我花了很长时间才开始使用TensorFlow Keras模型和Google Cloud ML。在最终完成所有工作后,我整理了一个代码示例,希望它可以帮助其他正在努力解决将TF模型部署到Google Cloud ML的相同问题。它可以在这里找到:https://github.com/mhwilder/tf-keras-gcloud-deployment。