我一直在尝试实现一个C#客户端应用程序以与Tensorflow服务服务器进行交互,现在已经有几周没有成功了。我有一个可以成功运行的Python客户端,但无法使用C#复制其功能。 Python客户端
import requests
#import json
from keras.preprocessing.image import img_to_array, array_to_img, load_img
from keras.preprocessing import image
flowers = 'c:/flower_photos/cars/car1.jpg'
image1 = img_to_array(image.load_img(flowers, target_size=(128,128))) / 255
payload = {
"instances": [{"image":image1.tolist()},
]
}
print("sending request...")
r = requests.post('http://localhost:8501/v1/models/flowers/versions/1:predict', json=payload)
print(r.content)
服务器正确响应。我正在使用Tensorflow版本1.12.0和相应的最新投放图片。他们都工作正常。
根据REST API documentation,给出了API结构,但对我来说根本不清楚。我需要将图像发送到服务器。如何在C#中将图像有效载荷添加到JSON请求中?浏览了许多站点之后,我发现该图像应该位于base64string中。
所以我将图像转换为base64
private string GetBase64ImageBytes(string ImagePath)
{
using (Image image = Image.FromFile(ImagePath))
{
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
}
请求部分如下:(服务器正确响应GET请求的元数据)
public string PostImageToServerAndClassify(string imageArray)
{
//https://stackoverflow.com/questions/9145667/how-to-post-json-to-a-server-using-c
string result = null;
string ModelName = cmbProjectNames.Text.Replace(" ", "");
string status_url = String.Format("http://localhost:{0}/v1/models/{1}/versions/{2}:predict", txtPort.Text, ModelName, txtVersion.Text);
var httpWebRequest = (HttpWebRequest)WebRequest.Create(status_url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
try
{
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
// string json = "{"+ @"""instances""" + ": [{" + @"""image""" + @":" + imageArray + "}]}";
// imageArray = @""" + imageArray + @""";
string json = "{ " + @"""instances""" + ": [{" + @"""image""" + @": { " + @"""b64"": """ + imageArray + @"""}}]}";
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
}
对于POST请求,我收到错误消息“远程服务器返回错误:(400)Bad Request。”。服务器也终止其服务。在邮递员中,我得到 详细的错误信息为:
{ "error": "Failed to process element: 0 key: image of \'instances\' list. Error: Invalid argument: JSON Value: {\n \"b64\": \"/9j/4AAQSkZJRgABAQEAAAAAAAD/4QBSRXhpZgAATU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAZKGAAcAAAAcAAAALAAAAABVTklDT0RFAABBAHAAcABsAGUATQBhAHIAaw ... .....(image string data)
因此,感觉就像我发送的数据格式不正确。 有人可以告诉我这里有什么问题吗?非常感谢任何图像转换和POST请求的示例。在TF网站中,找不到任何地方base64string格式是该图像的正确格式。 Python客户端数据格式不同,因此,实际上需要了解任何参考文档的正确格式。 我在Java客户端上发现here时最接近的参考,但不适用于我的,可能是由于TF版本不同。