3

我正在开发一个简单的 nodejs 控制台实用程序,它将上传用于训练自定义视觉模型的图像。我这样做主要是因为 customvision 网络应用程序不允许您一次标记多个图像。

tl;dr:如何将图像发布到CreateImagesFromFilesAPI 端点?

我不知道如何传递我要上传的图像。该文档只是将 a 定义string为其中一个属性的类型(content我猜)。我尝试将本地文件的路径、在线文件的 url 甚至 base64 编码图像作为字符串传递。什么都没通过。

他们有一个测试控制台(链接文档页面上的蓝色按钮“打开 API 测试控制台”),但又一次......它很模糊,不会告诉你它实际期望什么样的数据。

这里的代码不是那么相关,但也许它有帮助......

const options = {
    host: 'southcentralus.api.cognitive.microsoft.com',
    path: `/customvision/v2.0/Training/projects/${projectId}/images/files`,
    method: 'POST',
    headers: {
        'Training-Key': trainingKey,
        'Content-Type': 'application/json'
    }
};

const data = {
    images: [
        {
            name: 'xxx',
            contents: 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAEklEQVR42mP8z8AARKiAkQaCAFxlCfyG/gCwAAAAAElFTkSuQmCC',
            tagIds: [],
            regions: []
        }
    ],
    tagIds: []
}

const req = http.request(options, res => {
  ...
})
req.write(JSON.stringify(data));
req.end();

回复:

BODY: { "statusCode": 404, "message": "Resource not found" }
No more data in response.
4

1 回答 1

3

我使用“API 测试控制台”功能让它工作,所以我可以帮助您确定您的问题(但抱歉,我不是专家,node.js所以我会用C#代码指导您)

contentAPI格式

你是对的,文档并不清楚 API 正在等待的内容。我进行了一些搜索,并在 Microsoft 的 Github 存储库中找到了一个项目,名为Cognitive-CustomVision-Windows, here

看到的是他们使用了一个名为的类ImageFileCreateEntry,其签名在此处可见

public ImageFileCreateEntry(string name = default(string), byte[] contents = default(byte[]), IList<System.Guid> tagIds = default(IList<System.Guid>))

所以我猜它使用的是byte[].

您还可以在他们的示例中看到他们在这种“批处理”模式下的表现:

// Or uploaded in a single batch 
var imageFiles = japaneseCherryImages.Select(img => new ImageFileCreateEntry(Path.GetFileName(img), File.ReadAllBytes(img))).ToList();
trainingApi.CreateImagesFromFiles(project.Id, new ImageFileCreateBatch(imageFiles, new List<Guid>() { japaneseCherryTag.Id }));

然后这个字节数组被序列化Newtonsoft.Json:如果你看他们的文档(这里)它说byte[]转换为String (base 64 encoded). 这就是我们的目标。

执行

正如您提到的,您尝试使用 base64 编码的图像,我试了一下。我拍摄了在本地下载的 StackOverflow 个人资料图片。然后使用以下内容,我得到了 base64 编码的字符串:

Image img = Image.FromFile(@"\\Mac\Home\Downloads\Picto.jpg");
byte[] arr;
using (MemoryStream ms = new MemoryStream())
{
    img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
    arr = ms.ToArray();
}

var content = Convert.ToBase64String(arr);

后来,我调用了不带标签的 API 以确保图像已发布且可见:

POST https://southcentralus.api.cognitive.microsoft.com/customvision/v2.2/Training/projects/MY_PROJECT_ID/images/files HTTP/1.1
Host: southcentralus.api.cognitive.microsoft.com
Training-Key: MY_OWN_TRAINING_KEY
Content-Type: application/json

{
  "images": [
    {
      "name": "imageSentByApi",
      "contents": "/9j/4AAQSkZJRgA...TOO LONG FOR STACK OVERFLOW...",
      "tagIds": [],
      "regions": []
    }
  ],
  "tagIds": []
}

收到的回复:200 OK

{
  "isBatchSuccessful": true,
  "images": [{
    "sourceUrl": "imageSentByApi",
    "status": "OK",
    "image": {
      "id": "GENERATED_ID_OF_IMAGE",
      "created": "2018-11-05T22:33:31.6513607",
      "width": 328,
      "height": 328,
      "resizedImageUri": "https://irisscuprodstore.blob.core.windows.net/...",
      "thumbnailUri": "https://irisscuprodstore.blob.core.windows.net/...",
      "originalImageUri": "https://irisscuprodstore.blob.core.windows.net/..."
    }
  }]
}

我的图像在自定义视觉门户中!

自定义视觉中的图像

调试你的代码

为了调试,您应该首先尝试再次提交您的内容,tagIds并且regions数组为空,就像我的测试中一样,然后提供 API 回复的内容

于 2018-11-05T22:48:45.687 回答