绘本图片搜索
更新时间:2023-02-08
接口格式说明
变量类型定义
| 类型 | 定义 |
|---|---|
| string | 普通的字符串,可能会有长度要求,具体参见接口说明中的备注 |
| uint32 | 整形数字,最大取值为4字节int。自然数 |
| int64 | 整形数字,最大取值为8字节int。允许负数 |
| json | 无论是request还是response中某个字段定义为json,那么它其实是一个json格式的字符串,需要二次解析 |
| list | 与字符串的索引一样,列表索引从0开始。列表可以进行截取、根据索引读取 |
| float | 浮点型 |
| bytes | bytes以字节序列的形式(二进制形式)来存储数据(文本、图片、音频等) |
接口调用说明
调用接口的地址示例:[192.168.0.1]:8120/GeneralClassifyService/classify, 示例中的ip[192.168.0.1]需要替换为用户自己服务器的ip,示例中的端口8120需根据所调用接口进行替换:
- 特征接口默认端口8120
- 检索接口默认端口8027
- 底库管理默认端口8103
一、绘本图片搜索-特征接口
调用接口的地址示例:[192.168.0.1]:8120/GeneralClassifyService/classify, 示例中的ip[192.168.0.1]需要替换为用户自己服务器的ip
参数说明
| 参数 | 值类型 | 取值示例 | 备注 |
|---|---|---|---|
| logid | uint32 | 100 | 后台标记不同请求的日志,每个请求对 应不同logid,logid取值范围为32位无符 号整数。 |
| format | string | "json" | 当值为“json”时,传入参数中img和feature_data为base64编码,建议使用格式 |
| from | string | "test-python-tom" | 必填 方便as确认请求来源 |
| cmdid | string | "123" | |
| data | string | [pb base64编码] | 上传的后端服务访问输入参数 |
注:data[pb base64编码]格式如下(重点修改):(如需使用自定义库,自定义库 APPID 请写死为"same")
请求参数
| 参数名称 | 请求关键字 | 参数类型 | 参数取值示例 | 参数说明 |
|---|---|---|---|---|
| featureids | featureids | string | "" | 必填,指定服务输出特征结果 |
| image | image | string | 图像的二进制数据 | 必选,上传的查询图片 |
| appid | appid | string | "same" | |
| sub_lib | sub_lib | string | "1" | 可选,与appid拼接成完整的 appid |
请求代码示例
Plain Text
1特征服务,一般不开放接口
2same_private_example.py
3#!/usr/bin/env python
4#coding:utf-8
5import os
6import os.path
7import json
8import sys
9import urllib
10import urllib2
11import base64
12from proto import imgfeature_pb2
13import logging
14import time
15import subprocess
16import random
17logger = logging.getLogger()
18
19
20class CalFeatureError(Exception):
21 """when call remote server error"""
22 pass
23
24def calfeature_idlapi_remote(serverurl, imagedata, infos, logid=0):
25 """ cropmethod will pass to server as alignflag parameter"""
26
27 def _createprotobufdata(imagestr, info):
28 """create protobuf from image and info"""
29 proto_data = imgfeature_pb2.FeatureRequest()
30 proto_data.image = imagestr
31 proto_data.query_sign = '0,0'
32
33 def addinfo(key, value):
34 """add info to proto"""
35 infoele = proto_data.info.texts.add()
36 infoele.key = key
37 infoele.value = value
38
39 if info is not None:
40 for key, value in info.iteritems():
41 addinfo(key, value)
42 data = proto_data.SerializeToString()
43 return data
44
45 protodata = _createprotobufdata(imagedata, infos)
46 protodata = base64.b64encode(protodata)
47 req_json = {
48 'appid': "123456",
49 'logid': logid,
50 'format': 'json',
51 'from': 'test-python',
52 'cmdid': '123',
53 'clientip': '0.0.0.0',
54 'data': protodata,
55 }
56
57 conn = urllib2.urlopen(serverurl, data=json.dumps(req_json))
58 resultjson = conn.read()
59 result = json.loads(resultjson)
60 if result['err_no'] != 0:
61 errorinfo = '%s:%s' % (result['err_no'], result['err_msg'])
62 logger.warn('got error from server:%s', errorinfo)
63 raise CalFeatureError(errorinfo)
64
65 res_data = result['result'].decode('base64')
66 proto_result = imgfeature_pb2.FeatureResponse()
67 proto_result.ParseFromString(res_data)
68 features = {fea.fea_id: fea.fea_data for fea in proto_result.features}
69 return features
70
71def calfeature_remote(filename, feaaddr, featureids=''):
72 import urllib2
73 feaserverurl = 'http://%s/GeneralClassifyService/classify' % (feaaddr)
74 param = {"detect": "1", "usedb": "0"}
75 imagedata = open(filename, 'rb').read()
76 start = time.time()
77 features = calfeature_idlapi_remote(feaserverurl, imagedata, params)
78 print "time cost: %.2f ms" % ((time.time() - start)*1000)
79 for feaname in features:
80 print "-------------"*5
81 print feaname, features[feaname], len(features[feaname])
82
83def main():
84 img_path = 'query.jpg'
85 calfeature_remote(img_path,'127.0.0.1:8120','')
86 pass
87
88if __name__ == '__main__':
89 if len(sys.argv)>1 :
90 func = getattr(sys.modules[__name__], sys.argv[1])
91 func(*sys.argv[2:])
92 else:
93 print >> sys.stderr,'tools.py command'
二、绘本图片搜索-入库/更新/检索/删除/查接口
调用接口的地址示例:[192.168.0.1]:8027/GeneralClassifyService/classify, 示例中的ip[192.168.0.1]需要替换为用户自己服务器的ip
请求参数
| 参数名称 | 参数类型 | 是否必填 | 参数说明 |
|---|---|---|---|
| logid | uint64 | 否 | 日志号,可不传 |
| format | string | 否 | 当值为“json”时,传入参数中img和 feature_data为base64编码,建议使用格式 |
| from | string | 是 | 必填 方便as确认请求来源 |
| appid | string | 是 | 必填用户名same_1/same_2(上面设置的用户id,id不能带逗号) |
| image | bytes | 否 | 图片二进制,当format为json时,需进 行base64编码。如果请求是传图,as会 通过图片计算contsign值 |
| pn | unit32 | 否 | 返回结果开始位置,检索search时可用 |
| rn | unit32 | 否 | 返回结果取多少条,检索search时可用 |
| consign | ContSign | 否 | ContSign {uint32 sign1, uint32 sign2} 。如果同时传了image信息,as会以图片计算出的contsign值为准。 |
| consigns | repeated ContSign | 否 | 删除一组数据时使用,进行删除操作时,以contsigns数据为准,当contsigns中无数据才会删除contsign对应的数据 |
| image | bytes | 否 | 图片二进制,当format为json时,需进 行base64编码。如果请求是传图,as会 通过图片计算contsign值 |
| features | repeated FeatureData | add必填 | add时features中必须要传入brief信息 :fea_id:1000, 在fea_data中传入当前add的图片的简要说明,search时会返回该参数)fea_id:999, 固定传入一个struct,struct值参考示例代码update时features只需要传入feaid=1000的需要更新的信息即可 |
入库/更新/检索/删除 请求示例
Plain Text
1same_private_example_add_remove.py:
2#coding:utf-8
3import urllib2
4import base64
5import json
6import os
7import sys
8import logging
9logger = logging.getLogger()
10
11AS_SERVER = 'http://10.255.140.17:8027'
12
13ADD_IMG = 'query.jpg'
14APPID='test'
15
16
17def rts_as_add(filename=ADD_IMG, appid=APPID):
18 params = {
19 "appid": appid,
20 "format": "json",
21 "from": "from_xx",
22 "logid": 666,
23 "brief": "brief",
24 "image": base64.b64encode(open(filename,'rb').read()),
25 "features": [{"fea_id":1000, "fea_data" : base64.b64encode("addtest")}, {"fea_id":999, "fea_data": base64.b64encode(struct.pack('II', 0, 4))}]
26 }
27 conn = urllib2.urlopen(AS_SERVER+'/RTSAsService/add', data=json.dumps(params)).read()
28 print conn
29
30def rts_as_update(filename=IMG, appid=APPID):
31 params = {
32 "appid": appid,
33 "format": "json",
34 "from": "from_xx",
35 "logid": 666,
36 "image": base64.b64encode(open(filename,'rb').read()),
37 "features": [{"fea_id":1000, "fea_data" : base64.b64encode("addtest")}]
38 }
39 conn = urllib2.urlopen(AS_SERVER+'/RTSAsService/update', data=json.dumps(params)).read()
40 print conn
41
42def rts_as_search(filename=IMG, appid=APPID):
43 params = {
44 "appid": appid,
45 "image": base64.b64encode(open(filename,'rb').read()),
46 "format": "json",
47 "from": "from_yyy",
48 "logid": 44,
49 }
50 conn = urllib2.urlopen(AS_SERVER+'/RTSAsService/search', data=json.dumps(params)).read()
51 print conn
52
53def rts_as_delete(contsign, appid=APPID):
54 sign1, sign2 = map(int,contsign.split(','))
55
56 params = {
57 "appid": appid,
58 "format": "json",
59 "from": "from_xx",
60 "logid": 666,
61 #"image": base64.b64encode(open('1.jpg','rb').read()),
62 "contsign" : {'sign1':sign1,"sign2":sign2},
63 }
64 conn = urllib2.urlopen(AS_SERVER+'/RTSAsService/remove', data=json.dumps(params)).read()
65 print conn
66
67def rts_as_snapshot(appid=APPID):
68 params = {
69 "appid": appid,
70 "from": "from_xx",
71 "logid": 666,
72 }
73 conn = urllib2.urlopen(AS_SERVER+'/RTSAsService/snapshot', data=json.dumps(params)).read()
74 print conn;
75
76def signup(appid=APPID):
77 params = {
78 "appid": appid,
79 "from": "from_xx",
80 "logid": 666,
81 }
82 conn = urllib2.urlopen(AS_SERVER+'/RTSAsService/signup', data=json.dumps(params)).read()
83 print conn;
84
85if __name__ == '__main__':
86 if len(sys.argv) > 1:
87 func = getattr(sys.modules[__name__], sys.argv[1])
88 func(*sys.argv[2:])
89 else:
90 print >> sys.stderr, 'api.py {rts_as_add,rts_as_search,rts_as_delete}'
返回参数
| 参数名称 | 参数类型 | 参数说明 |
|---|---|---|
| err_no | int32 | 错误码,详见下方错误码列表信息 |
| err_msg | string | 错误信息,详见下方错误码列表信息 |
| data_items | ResultItem | search的返回结果 |
| features | FeatureData | 分类检索的返回结果 |
| has_more | unit32 | 除了返回的检索结果外是否还有更多的结果 |
| index_capacity | int32 | 使用snapshot接口(查询用户的基本信息和用户已插入数据量等信息)的返回参数,表示当前数据库可支持的总容量 |
| index_size | int32 | 使用snapshot接口(查询用户的基本信息和用户已插入数据量等信息)的返回参数,表示已使用容量 |
返回示例
| 接口 | 正确返回示例 | 错误返回示例 |
|---|---|---|
| add入库 | {"err_no":0,"err_msg":"OK"} | {"err_no":101,"err_msg":"duplicated add","data_items":[{"contsign":{"sign1":1143248165,"sign2":1517467661},"features":[{"fea_id":1000,"fea_data":"eWFoYWhh"}]}]} |
| update更新 | {"err_no":0,"err_msg":"OK"} | |
| search检索 | {"err_no":0,"err_msg":"OK","data_items":[{"contsign":{"sign1":1143248165,"sign2":1517467661},"score":1.0000001192092896,"features":[{"fea_id":1000,"fea_data":"dXBkYXRl"}]},{"contsign":{"sign1":2904947031,"sign2":1496948683},"score":0.33452537655830386,"features":[{"fea_id":1000,"fea_data":"dHVkb3UxMTEx"}]}],"has_more":0} | |
| delete删除 | {"err_no":0,"err_msg":"OK"} | |
| snapshot查询 | {"err_no":0,"err_msg":"OK","snapshot":{"tag":0,"index_size":1,"index_capacity":0,"queue_size":0}} | |
| signup增加注册用户 | "err_no":0,"err_msg":"OK"} | {"err_no":0,"err_msg":"OK"} |
错误码
| 错误码 | 错误信息 |
|---|---|
| -1 | 服务初始化失败 |
| 0 | ok |
| 1 | 请求参数不合法 |
| 2 | feature服务超时 |
| 3 | bs服务超时 |
| 4 | meta服务超时 |
| 5 | 无效的feature服务 |
| 6 | 无效的bs服务 |
| 7 | 无效的meta服务 |
| 8 | 提取feature失败 |
| 9 | 请求bs失败 |
| 10 | 获取meta信息失败 |
| 11 | 服务内部错误 |
| 12 | 鉴权失败 |
| 99 | 服务忙 |
| 100 | 由于用户输入原因提取特征失败(1003,1004,1005,101003,216200(空图)216201(解码/图像格式错误)216202(图像尺寸错误)) |
| 101 | 重复add |
| 102 | 更新不在table中的数据 |
| 103 | 用户未注册 |
| 104 | 用户已存在 |
