全网最详细阿里云图像识别API接入流程
-----来自蜗哩技术团队
引言
在开发APP时,需要接入阿里云图像识别功能,由于阿里云官方文档总体比较乱,在此整理一下整个过程。
1.初识阿里云图像识别
进入阿里云视觉智能开放平台,我们首先以图像识别中的颜色识别为例,来作为切入口。
可以看到,图像识别拥有众多API,而进入颜色识别窗口,就可以看到清晰的请求参数配置示例(并不清晰)
是的,从官方文档提供的参数看来,似乎只要携带三个参数即可返回相应检测结果,实际上远不如此...
2.完成阿里云相关配置
首先,当然是开通一条账号,并且申请属于自己的OSS(对象存储空间),可以理解为这是阿里云提供的临时数据存储空间。
创建bucket
在OSS系统中,阿里云采用了一种Bucket的说法,简单来说,它就是一个个数据分组。便于相关技术人员进行管理。
我们配置bucket时,最好选择地域为华东上海(便于后续调用图像识别功能)。我在测试功能时选择了区域为华北北京,导致调用API时需要进行URL中转,这本身并不难,但是涉及到性能问题,后续会提到。
创建Access Key
现在我们应该为我们的账户创建一个独一无二的标识符——Access Key,点击右上角的头像即可看到管理选项,记住申请了Access Key后一定要将id和secret妥善保存!
在搜索栏中直接搜索RAM访问控制台即可创建用户角色以及子用户的Access Key,并为之分配相应的权限,这就类似于数据库分配权限到角色上,这样可以产生多个用户角色(例如技术总管分配给不同的开发者)根据对应权限来调用相应的服务。
3.调用服务
开通对应服务
在调用服务前,先确保我们已经开通了对应的服务,可以看到目前图像识别只能通过华东上海的服务器进行调用
业务逻辑
根据文档,要顺利调用该服务,整体流程应该是:
- 上传本地图片或者网络图片URL到账户下的OSS中,此时OSS服务会返回对应的拥有阿里云服务器标识的新URL。
- 将该URL作为参数和其他参数一起发送到图像识别服务器,得到结果。
遇到的麻烦
获取STS凭证
然而实际操作下来,发现事情没有这么简单:
首先,用户想将图片上传到OSS中,就需要获取云端发配的临时访问凭证。
因为要在不同客户端之间调用相应的图像识别功能,自然需要经过鉴权才能安全有效的执行(不然钱就亏光了,谁都可以调用服务)。阿里云提供了一种叫做STS的授权服务,好在也提供了各种语言的SDK,方便了广大技术栈的开发者(Node.js狂喜)

获取STS凭证之前主账户的准备
要为账号开通STS服务,需要进行以下授权行为,前文提到过,我们可以创建不同的用户角色,给其分配不同的权限和对应的Access Key,接下来要做的就是为OSS服务创建一个用户,使其拥有颁发访问OSS的STS凭证的权限。
步骤一:创建RAM用户
- 登录RAM控制台。
- 在左侧导航栏的身份管理菜单下,单击用户。
- 单击创建用户。
- 输入登录名称和显示名称。
- 在访问方式区域下,选择Open API 调用访问,然后单击确定。
- 单击复制,保存访问密钥(AccessKey ID 和 AccessKey Secret)。
步骤二:为RAM用户授予请求AssumeRole的权限
- 单击已创建RAM用户右侧对应的添加权限。
- 在添加权限页面,选择AliyunSTSAssumeRoleAccess权限。

- 单击确定。
步骤三:创建用于获取临时访问凭证的角色
- 在左侧导航栏的身份管理菜单下,单击角色。
- 单击创建角色,选择可信实体类型为阿里云账号,单击下一步。
- 角色名称填写为RamOssTest,选择云账号为当前云账号。
- 单击完成。角色创建完成后,单击关闭。
- 在RAM角色管理页面,搜索框输入角色名称RamOssTest。
- 单击复制,保存角色的ARN。

步骤四:为角色授予上传文件的权限
-
创建上传文件的自定义权限策略。
-
在左侧导航栏的权限管理菜单下,单击权限策略管理。
-
单击创建权限策略。
-
在新建自定义权限策略页面,填写策略名称为RamTestPolicy,配置模式选择脚本配置,并在策略内容中赋予角色向目标存储空间examplebucket下的目录exampledir上传文件的权限。警告:以下示例仅供参考。您需要根据实际需求配置更细粒度的授权策略,防止出现权限过大的风险。关于更细粒度的授权策略配置详情,请参见通过RAM或STS服务向其他用户授权。
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "oss:PutObject" ], "Resource": [ "acs:oss:*:*:examplebucket/exampledir", "acs:oss:*:*:examplebucket/exampledir/*" ] } ] } -
单击确定。
-
-
为RAM角色RamOssTest授予自定义权限策略。
- 在左侧导航栏的身份管理菜单下,单击角色。
- 在角色页面,找到目标RAM角色RamOssTest。
- 单击RAM角色RamOssTest右侧的添加权限。
- 在添加权限页面下的自定义策略页签,选择已创建的自定义权限策略RamTestPolicy。
- 单击确定。
步骤五:获取临时访问凭证
调用提供的各语言SDK即可。
步骤六:使用临时访问凭证上传文件至OSS
在上传文件的所有SDK中,我们自然选择了Browser.js,这是阿里云唯一提供给web端(客户端)使用的SDK,至于为什么不选择Java或者Node.js,理由很简单,没有人想把图片资源先发送给后端(应用服务器),然后由后端再转发给阿里云的OSS存储。这意味着两倍的数据转发量和请求次数。造成的性能损失是不必要的。
public static void main(String[] args) {
// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "oss-cn-hangzhou.aliyuncs.com";
// 填写步骤五获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
// 填写步骤五获取的安全令牌SecurityToken。
String securityToken = "<yourSecurityToken>";
主要的四个参数如上。
至于如何获取返回的URL,文档已有详细说明,不再赘述。
万事俱备?
现在我们也有了上传的图片的URL,是不是可以调用服务了呢?
错!!!
查看API请求参数说明,发现只支持上海地域的OSS链接,而我创建的bucket是北京的,因此根据提示我们需要进行图片URL中转
根据提示我们需要再次获取对应的SDK,这里我使用了Node.js的SDK进行URL中转,要特别注意SDK使用的语言是TypeScript而非JS,因此我们要在本地使用npm安装TypeScript和tsnode用于启动服务,正好学习一下TypeScript。
import ViapiUtil from '@alicloud/viapi-utils'
import axios from 'axios'
export default class Client {
static async main(): Promise<string> {
// 您的AccessKeyID
let accessKeyId: string = 'LTAI5t76uKWM94qDWY3pjjXC'
// 您的AccessKeySecret
let accessKeySecret: string = 'WeXNHzPqApxLEdA3LMMM7WwLyTOujn'
// 要上传的文件路径,url 或 filePath
let fileUrl: string = 'https://gtms02.alicdn.com/tfs/TB1eYC7wi_1gK0jSZFqXXcpaXXa-2169-1074.png'
//上传成功后,返回上传后的文件地址
let fileLoadAddress: string = await ViapiUtil.upload(accessKeyId, accessKeySecret, fileUrl)
// console.log(fileLoadAddress);
return fileLoadAddress
}
}
最终我们成功获取到中转URL,很明显上面有了shanghai.aliyuncs的字样,说明成功了。
只欠东风?
回到最开始,我们也有了有效的图片URL,现在可以去调用服务了吧!
根据预设的三个参数,使用GET请求,尝试获取数据:
无奈还是一直报错 invalidVersion
查阅错误集合文档和只能诊断,都无济于事。最后偶然看到了公共请求参数这一栏!!!
原来是因为并不是只携带三个参数即可!实际上需要带上很多很多的和鉴权相关的参数,并且只能使用GET请求将参数作为查询字符串(也就是包裹在URL中)进行发送。
最后通过后端同学调用生成签名和签名唯一随机数的SDK,生成各个配置必需的参数,最终才成功的发出了请求。
这个过程也拖累了我们前后端同学很久,最主要的原因是生成签名的时候需要传入调用服务的特定信息(如调用颜色识别需要传入对应的图片URL和colorCount作为生成签名的参数),如果遗漏了这一步,则会导致一直一直报HttpMethod错误。一定要避开!
附上最终完成调用获取到的参数(喜极而泣)
`{`
`"RequestId": "8A4364B5-E0A9-56C8-8954-A553528462D2",`
`"Data": {`
`"ColorTemplateList": [`
`{`
`"Percentage": "0.237723",`
`"Color": "E8C0B5",`
`"Label": "red"`
`},`
`{`
`"Percentage": "0.232763",`
`"Color": "FBEEEC",`
`"Label": "white"`
`},`
`{`
`"Percentage": "0.207093",`
`"Color": "8E6256",`
`"Label": "red"`
`},`
`{`
`"Percentage": "0.187128",`
`"Color": "432929",`
`"Label": "red"`
`},`
`{`
`"Percentage": "0.135293",`
`"Color": "EA897B",`
`"Label": "red"`
`}`
`]`
`}`
`}`