动物识别能够识别近八千种动物,接口返回动物名称,并获取百科信息,适用于拍照识图类APP中。
应用场景
拍照识别:根据拍摄照片,识别图片中动物的名称,可配合其它识图能力对识别的结果进一步细化,提高用户体验,广泛应用于拍照识图类APP中
接口描述 用于识别一张图片,即对于输入的一张图片(可正常解码,且长宽比较合适),输出动物识别结果。
请求说明
HTTP 方法: POST
请求 URL: https://aip.baidubce.com/rest/2.0/image-classify/v1/animal
URL参数: access_token
Header 参数: Content-Type
= application/x-www-form-urlencoded
Body 参数:见下表
参数
是否必选
类型
默认值
说明
image
是
string
-
图像数据,base64
编码,要求 base64
编码后大小不超过 4M,最短边至少 15px
,最长边最大 4096px
, 支持 jpg/png/bmp
格式 。注意:图片需要 base64
编码、去掉编码头后再进行 urlencode
top_num
否
integer
6
返回预测得分 top 结果数,默认为 6
baike_num
否
integer
0
返回百科信息的结果数,默认不返回
返回说明 返回参数如下表:
字段
类型
是否必选
说明
log_id
uint64
是
id,用于问题定位
result
arrry(object)
是
识别结果数组
+name
string
是
动物名称,示例:蒙古马
+score
string
是
置信度,示例:0.5321
+baike_info
object
否
对应识别结果的百科词条名称
++baike_url
string
否
对应识别结果百度百科页面链接
++image_url
string
否
对应识别结果百科图片链接
++description
string
否
对应识别结果百科内容描述
返回示例如下:
{ "log_id" : 7392482912853822863 , "result" : [ { "score" : "0.993811" , "name" : "叉角羚" , "baike_info" : { "baike_url" : "http://baike.baidu.com/item/%E5%8F%89%E8%A7%92%E7%BE%9A/801703" , "description" : "叉角羚(学名:Antilocapra americana):在角的中部角鞘有向前伸的分枝,故名。体型中等,体长1-1.5米,尾长7.5-10厘米,肩高81-104厘米,成体重36-60千克,雌体比雄体小;背面为红褐色,颈部有黑色鬃毛,腹部和臀部为白色,颊面部和颈部两侧有黑色块斑;毛被下面为绒毛,上覆以粗糙、质脆的长毛,由于某些皮肤肌的作用,能使其毛被呈不同角度,以利于保暖或散热。植食。叉角羚奔跑速度非常快,最高时速达100千米。一次跳跃可达3.5-6米。善游泳。夏季组成小群活动,冬季则集结成上百只的大群。为寻找食物和水源,一年中常进行几次迁移。性机警,视觉敏锐,能看到数千米外的物体。遇险时,臀部的白色毛能立起,向同伴告警。分布于北美洲。" } } , { "score" : "0.000289439" , "name" : "印度羚" } , { "score" : "0.000186248" , "name" : "藏羚羊" } , { "score" : "0.000147176" , "name" : "跳羚" } , { "score" : "0.000134434" , "name" : "驯鹿" } , { "score" : "9.86555e-05" , "name" : "高鼻羚羊" } ] }
C++ 代码实现调用 这里假设已经将环境配置好了,环境配置的文章可以参考 Windows 下使用 Vcpkg 配置百度 AI 图像识别 C++开发环境(VS2017) 。
为了方便,首先根据返回参数定义了一个结构体,该结构体包括了返回参数中的参数,如下:
struct AnimalInfo { std::string name; std::string score; std::string baikeurl; std::string imageurl; std::string baikedesc; void print () { std::cout << std::setw (30 ) << std::setfill ('-' ) << '\n' ; std::cout << "name: " << name << "\n" ; std::cout << "score: " << std::fixed << std::setprecision (4 ) << std::stof (score) << "\n" ; if (baikeurl != "null" ) std::cout << "baikeurl: " << baikeurl << "\n" ; if (imageurl != "null" ) std::cout << "imageurl: " << imageurl << "\n" ; if (baikedesc != "null" ) std::cout << "baikedesc: " << baikedesc << "\n" ; } };
在 AnimalInfo
结构体中,定义了一个 print
方法以打印获取的结果。
然后定义了一个类来调用接口并获取结果
class Animal { public : Animal (); ~Animal (); Json::Value request (std::string imgBase64, std::map<std::string, std::string>& options) ; void getAllResult (std::vector<AnimalInfo>& results) ; void getResult (AnimalInfo& result) ; private : Json::Value obj_; std::string url_; int top_num_; std::string filename_; };
类中的私有成员 obj_
表示返回结果对应的 json 对象。url_
表示请求的 url,top_num_
表示请求参数中对应的 topnum,`filename 表示用于存储
access token` 的文件的文件名。
request
函数输入请求图像的 base64 编码以及请求参数,返回一个 json 对象,json 对象中包含请求的结果。
getAllResult
获取请求的结果,总共有 top_num 条结果。
getResult
获取 score 最高的一条结果。
完整代码如下
util.h
和 util.cpp
代码参见 (简单调用篇 01) 通用物体和场景识别高级版 - C++ 简单调用
Animal.h
代码如下:
#pragma once #include <string> #include <map> #include <curl/curl.h> #include <json/json.h> #include <iostream> #include <vector> #include <cstdlib> #include "util.h" struct AnimalInfo { std::string name; std::string score; std::string baikeurl; std::string imageurl; std::string baikedesc; void print () { std::cout << std::setw (30 ) << std::setfill ('-' ) << '\n' ; std::cout << "name: " << name << "\n" ; std::cout << "score: " << std::fixed << std::setprecision (4 ) << std::stof (score) << "\n" ; if (baikeurl != "null" ) std::cout << "baikeurl: " << baikeurl << "\n" ; if (imageurl != "null" ) std::cout << "imageurl: " << imageurl << "\n" ; if (baikedesc != "null" ) std::cout << "baikedesc: " << baikedesc << "\n" ; } }; class Animal { public : Animal (); ~Animal (); Json::Value request (std::string imgBase64, std::map<std::string, std::string>& options) ; void getAllResult (std::vector<AnimalInfo>& results) ; void getResult (AnimalInfo& result) ; private : Json::Value obj_; std::string url_; int top_num_; std::string filename_; }; void animalTest () ;
Animal.cpp
代码如下:
#include "animal.h" Animal::Animal () { url_ = "https://aip.baidubce.com/rest/2.0/image-classify/v1/animal" ; top_num_ = 6 ; } Animal::~Animal () { } Json::Value Animal::request (std::string imgBase64, std::map<std::string, std::string>& options) { if (!options["top_num" ].empty ()) { top_num_ = std::stoi (options["top_num" ]); } std::string response; Json::Value obj; std::string token; std::string body; mergeHttpPostBody (body, imgBase64, options); std::string url = url_; getHttpPostUrl (url, filename_, token); int status_code = httpPostRequest (url, body, response); if (status_code != CURLcode::CURLE_OK) { obj["curl_error_code" ] = status_code; obj_ = obj; return obj; } generateJson (response, obj); if (obj["error_code" ].asInt () == 110 || obj["error_code" ].asInt () == 111 ) { token = getTokenKey (); writeFile (filename_, token); return request (imgBase64, options); } obj_ = obj; checkErrorWithExit (obj); return obj; } void Animal::getAllResult (std::vector<AnimalInfo>& results) { results.reserve (top_num_); AnimalInfo tmp; for (int i = 0 ; i < top_num_; ++i) { tmp.name = UTF8ToGB (obj_["result" ][i]["name" ].asString ().c_str ()); tmp.score = obj_["result" ][i]["score" ].asString (); tmp.baikeurl = obj_["result" ][i]["baike_info" ].get ("baike_url" , "null" ).asString (); tmp.imageurl = obj_["result" ][i]["baike_info" ].get ("image_url" , "null" ).asString (); tmp.baikedesc = UTF8ToGB (obj_["result" ][i]["baike_info" ].get ("description" , "null" ).asString ().c_str ()); results.push_back (tmp); } } void Animal::getResult (AnimalInfo & result) { result.name = UTF8ToGB (obj_["result" ][0 ]["name" ].asString ().c_str ()); result.score = obj_["result" ][0 ]["score" ].asString (); result.baikeurl = obj_["result" ][0 ]["baike_info" ].get ("baike_url" , "null" ).asString (); result.imageurl = obj_["result" ][0 ]["baike_info" ].get ("image_url" , "none" ).asString (); result.baikedesc = UTF8ToGB (obj_["result" ][0 ]["baike_info" ].get ("description" , "none" ).asString ().c_str ()); } void animalTest () { std::string img_file = "./images/cat.jpg" ; std::string out; readImageFile (img_file.c_str (), out); std::string img_base64 = base64_encode (out.c_str (), (int )out.size ()); std::map<std::string, std::string> options; options["top_num" ] = "5" ; options["baike_num" ] = "5" ; Json::Value obj; Animal animalObj; AnimalInfo result; obj = animalObj.request (img_base64, options); animalObj.getResult (result); result.print (); std::vector<AnimalInfo> results; animalObj.getAllResult (results); for (auto & vec : results) { vec.print (); } }
main.cpp
代码如下:
#include "util.h" #include "Animal.h" #include <stdlib.h> int main () { animalTest (); system ("pause" ); return EXIT_SUCCESS; }
运行结果 测试图像