1.比较各类商业图像识别接口:
1.火山引擎:对于人体、人像的识别功能较多,对于动物几乎没有,分类较少只有两三个,而且识别精度较差,往往识别不出图像中的实体。
2.谷歌引擎:识别精度、细节相当高,但没有分类,识别元素过多,且在国外,调试和支付不太方便。
3.百度引擎:识别精度优秀,分类较多,有明确的动物识别分类,且能衍生出百科知识,返回的标签为中文标签。
4.阿里云引擎:识别分类没有动物分类,但是在阿里云市场有其他公司的接口,相当于外包。
2.选用接口:
综合考虑使用百度动物识别,使用语言为node.js。但其官方示例没有node.js的语言示例,需要自己琢磨开发。
1.调用百度获取token的接口:
一开始的想法是将这个过程作为中间件,但发现作为中间件使用后,原接口就不能再发起请求了,原因不得而知,只能将其封装在方法中:
async function getToken() {
const param = qs.stringify({
grant_type: "client_credentials",
client_id: "your client_id",
client_secret: "your client_secret",
});
//通过秘钥获取token相关属性
try {
//但这个方法需要考虑到异步问题
// axios({
// method: "get",
// baseURL: "https://aip.baidubce.com/",
// //两种url写法均可以请求到
// // url: `oauth/2.0/token?grant_type=client_credentials&client_id=${client_id}&client_secret=${client_secret}`,
// url: "oauth/2.0/token?" + param,
// }).then((res) => {
// // var stream = res.data.pipe(fs.createWriteStream("./baidu-token.json"));
// // stream.on("finish", () => {
// // console.log("传输完成!");
// // });
// return axios.get("https://aip.baidubce.com/oauth/2.0/token?" + param);
// });
return axios.get("https://aip.baidubce.com/oauth/2.0/token?" + param);
} catch (error) {
console.log(error);
}
}
之前考虑过将获取到的token存放在文件中,这样不太会占用内存,但使用fs.createWriteStream(“./baidu-token.json”)浏览器会报同源跨域错误,虽然没什么影响,但如果不想看见报错还是不要使用这种优雅的写法了。
2.将图像转换为base64格式:
const image2base64 = require("image-to-base64");
let imageBase64 = await image2base64(
// "http://localhost:4000/" + req.file.filename
imageUrl
);
//这里的imageUrl直接使用的是阿里云存储OSS返回的url,比较方便
3.调用动物识别接口:
async function getAnimal(imageUrl, response) {
try {
let token = await getToken();
let imageBase64 = await image2base64(
// "http://localhost:4000/" + req.file.filename
imageUrl
);
const bodyFormData = new FormData();
bodyFormData.append("image", imageBase64);
return await axios({
method: "post",
url: `https://aip.baidubce.com/rest/2.0/image-classify/v1/animal?access_token=${token.data.access_token}`,
headers: { "content-type": "application/x-www-form-urlencoded" },
data: bodyFormData,
});
} catch (error) {
response.send(error);
}
}
注意这里一定要将imageBase64添加到bodyFormData,官方文档中没有说,是一个坑。