接口调用
车辆分析私有化部署包部署成功后,即可获得与在线API基本相同的接口,相关接口将会启动,即可参考本文档开始调用测试。
车辆分析的各个接口拆分为不同的私有部署包,车型识别、车辆检测、车流统计对应3个不同的部署包,方便选取所需能力灵活应用。
接口格式说明
变量类型定义
类型 | 定义 |
---|---|
string | 普通的字符串,可能会有长度要求,具体参见接口说明中的备注 |
uint32 | 整形数字,最大取值为4字节int。自然数 |
int64 | 整形数字,最大取值为8字节int。允许负数 |
json | 无论是request还是response中某个字段定义为json,那么它其实是一个json格式的字符串,需要二次解析 |
array | request的query中表示array请使用key[] 。response的json中的array即为jsonArray |
double | 双精度,小数点后最大8位四舍五入 |
请求参数格式如下:
1json
2req_array = {
3 'appid': '123456',
4 'logid': logid,
5 'format': 'json',
6 'from': 'test-python',
7 'cmdid': '123',
8 'clientip': '0.0.0.0',
9 'data': base64.b64encode(data),
10 }
11 req_json = json.dumps(req_array)
python代码示例如下:
1import base64
2import json
3from proto import general_classify_client_pb2
4
5//输入图片为01.jpg
6image_file = "01.jpg"
7
8//将图片内容读取至image_data
9with open(image_file, 'rb') as f:
10 image_data = f.read()
11
12proto_data = general_classify_client_pb2.GeneralClassifyRequest()
13proto_data.image = image_data
14data = proto_data.SerializeToString()
15
16logid = random.randint(1000000, 100000000)
17
18# 将data转为json,并进行base64编码
19req_array = {
20 'appid': '123456',
21 'logid': logid,
22 'format': 'json',
23 'from': 'test-python',
24 'cmdid': '123',
25 'clientip': '0.0.0.0',
26 'data': base64.b64encode(data),
27
28 }
29# 最终应该传入http body的内容
30req_json = json.dumps(req_array)
返回格式
- error_code、error_msg即错误码和错误描述,详细含义请参考错误码表, error_code为0代表请求成功
- result是接口返回的详细信息, 格式为数组。
- log_id是请求的日志id, 13位长(bigint), 用于定位请求。
1{
2 "error_code" : 0, //错误码 0代表成功
3 "error_msg" : "SUCCESS", //错误信息
4 "result" : {...} //返回结果 具体内容详见相关接口
5 "log_id" : 3535325235 //请求的日志id
6 "timestamp" : 1512391548 //请求到达的时间戳 精确到秒级
7 "cached" : 0 //未启用 无需处理
8}
返回内容解析:
1res_json = json.loads(response)
2if res_json['err_no'] == 0:
3 proto_result = general_classify_client_pb2.GeneralClassifyResponse()
4 proto_result.ParseFromString(base64.decodestring(res_json['result']))
5 res_json['result'] = protobuf_to_dict(proto_result)
接口调用说明
车型识别
检测图片中的主体车辆位置,识别车辆品牌型号(如宝马X3)、年份、颜色信息,可识别近3000款常见车型(小汽车为主)。
调用接口的地址示例:[192.168.0.1]:8125/GeneralClassifyService/classify,其中ip需要替换为用户自己服务器的ip,端口默认为:8125,可以在配置文件car.conf中修改
路径
/GeneralClassifyService/classify
请求参数
参数 | 是否必选 | 类型 | 可选值范围 | 说明 |
---|---|---|---|---|
image | 是 | string | 0-255彩色图像(base64编码) | 图像数据,base64编码,size>50。异常:若图片尺寸长或宽小于50pixel,会提示尺寸过小 |
top_num | 否 | int | 返回车型识别结果的个数,按照概率高低排序;默认是5 |
请求参数构造及python代码示例
请求参数为json格式,请求时请将Content-Type设置为application/json格式。
请求参数格式如下:
1json
2{
3
4 'data':base64encode(
5 {
6 "image" : base64encode(binary image data),
7 "top_num" : 5,
8 }
9 )
10}
python代码示例如下:
1python
2import base64
3import json
4
5# 输入图片为/home/work/01.jpg
6image_file = "/home/work/01.jpg"
7
8# 将图片内容读取至image_data
9with open(image_file, 'rb') as f:
10 image_data = f.read()
11
12data = {
13# 将image_data进行base64编码
14 "image": base64.b64encode(image_data),
15 # 设置车型识别输出结果的前几位结果
16 "top_num": 5,
17}
18
19request_body = {
20# 将data转为json,并进行base64编码
21"data": base64.b64encode(json.dumps(data))
22}
23
24# 最终应该传入http body的内容
25print json.dumps(request_body)
返回参数
字段 | 是否必选 | 类型 | 说明 |
---|---|---|---|
color | 是 | string | 车型颜色,例如:红色 |
location | 是 | object | 车辆在图片中的位置信息 |
+height | 是 | float | 目标检测框高度 |
+left | 是 | float | 目标检测框左坐标 |
+top | 是 | float | 目标检测框顶坐标 |
+width | 是 | float | 目标检测框宽度 |
result | 是 | object[] | 车型识别结果数组 |
+class_name | 否 | string | 车型名称,如:宝马x6 |
+probability | 否 | float | 置信度,取值范围0-1 |
+year | 否 | string | 年份 |
返回示例
1json
2{
3 "color":"白色",
4 "location":
5 {
6 "height":445.0488586425781,
7 "left":0.0,
8 "top":267.1705017089844,
9 "width":1256.413696289062
10 },
11 "result":[
12 {
13 "class_name":"别克威朗(Verano)",
14 "probability":0.9993143677711487,
15 "year":"2017"
16 },
17 {
18 "class_name":"别克英朗",
19 "probability":9.359556133858860e-05,
20 "year":"2017"
21 },
22 {
23 "class_name":"通用(别克昂科拉)Mokka",
24 "probability":3.383650619070977e-05,
25 "year":"2017"
26 },
27 {
28 "class_name":"长城C50",
29 "probability":1.912148218252696e-05,
30 "year":"2012-2016"
31 },
32 {
33 "class_name":"吉利博瑞",
34 "probability":1.428041650797240e-05,
35 "year":"2015-2017"
36 }
37 ],
38 "type_name":"fg-car-online"
39}
错误返回值
参数 | 类型 | 必选 | 说明 |
---|---|---|---|
err_msg | string | 是 | 错误信息,只在异常中出现(参考错误码) |
err_code | unit32 | 是 | 错误码,只在异常中出现(参考错误码) |
错误码表
err_code | err_msg | 名称 | 解释 |
---|---|---|---|
1 | 无 | GENERAL_CLASSIFY_CONF_FILE_ERR | 部署包中配置文件错误 |
2 | car_damage_service[status:fail to parse rec_returned value] | GENERAL_CLASSIFY_PREDICT_ERR | 车型识别服务错误,无法解析识别结果 |
3 | fg_car_service[status:image size < 50] | GENERAL_CLASSIFY_IMAGE_ERR | 图像尺寸小于50像素 |
4 | fg_car_service[status:parse pb error] | GENERAL_CLASSIFY_PARSE_PB_ERR | 无法解析请求 |
5 | fg_car_service[status: topnum type error] | GENERAL_CLASSIFY_REQUEST_TYPE_ERR | 车型识别中设置的top_num的类别错误,应为uint |
6 | ImageClassify[status: authenticate error] | IMAGECLASSIFY_AUTHENTICATE_ERR | 鉴权失败 |
车辆检测
传入单帧图像,检测图片中所有机动车辆,返回每辆车的类型和坐标位置,可识别小汽车、卡车、巴士、摩托车、三轮车5类车辆,同时可定位小汽车、卡车、巴士的车牌位置。
当前主要适用于普通监控场景,如道路、停车场等,无人机高空拍摄的图片,因车辆目标较小,识别效果欠佳,后续会扩展面向高空拍摄场景的模型。
调用接口的地址示例:[192.168.0.1]:8125/GeneralClassifyService/classify,其中ip需要替换为用户自己服务器的ip,端口默认为:8125,可以在配置文件car.conf中修改
路径
/GeneralClassifyService/classify
请求参数
参数 | 是否必选 | 类型 | 可选值范围 | 说明 |
---|---|---|---|---|
image | 是 | string | 0-255彩色图像(base64编码) | 图像数据,base64编码,size>50。异常:若图片尺寸长或宽小于50pixel,会提示尺寸过小 |
请求参数构造及python代码示例
请求参数为json格式,请求时请将Content-Type设置为application/json格式。
请求参数格式如下:
1json
2{
3
4 'data':base64encode(
5 {
6 "image" : base64encode(binary image data),
7 }
8 )
9}
python代码示例如下:
1python
2import base64
3import json
4
5# 输入图片为/home/work/01.jpg
6image_file = "/home/work/01.jpg"
7
8# 将图片内容读取至image_data
9with open(image_file, 'rb') as f:
10 image_data = f.read()
11
12data = {
13# 将image_data进行base64编码
14 "image": base64.b64encode(image_data),
15}
16
17request_body = {
18# 将data转为json,并进行base64编码
19"data": base64.b64encode(json.dumps(data))
20}
21
22# 最终应该传入http body的内容
23print json.dumps(request_body)
返回参数
字段 | 是否必选 | 类型 | 说明 |
---|---|---|---|
objects | 是 | vector | 检测到的目标信息 |
+height | 是 | int32 | 目标检测框高度 |
+left | 是 | int32 | 目标检测框左坐标 |
+top | 是 | int32 | 目标检测框顶坐标 |
+width | 是 | int32 | 目标检测框宽度 |
+label | 是 | int32 | 目标物体类型:1 - car(小汽车);2 - mediumbus(中巴);3 - bus(大巴);4 - minivan(小型货车);5- truck(卡车);6 - heavytruck(重型卡车);7 - tricycle(三轮车);8 - motorbike(摩托车);9 - bicycle(自行车);10 - plate(车牌) |
+prob | 是 | float | 置信度分数,取值0-1 |
返回示例
1json
2{
3 'type_name': u'fg-car-det-surveillance',
4 'objects': [
5 {
6 'top': 413,
7 'height': 265,
8 'width': 506,
9 'label': 1,
10 'prob': 0.5790910124778748,
11 'left': 1389
12 },
13 {
14 'top': 144,
15 'height': 34,
16 'width': 53,
17 'label': 1,
18 'prob': 0.5447509288787842,
19 'left': 568
20 }
21 ]
22}
错误返回值
参数 | 类型 | 必选 | 说明 |
---|---|---|---|
err_msg | string | 是 | 错误信息,只在异常中出现(参考错误码) |
err_code | unit32 | 是 | 错误码,只在异常中出现(参考错误码) |
错误码表
err_code | err_msg | 解释 |
---|---|---|
GENERAL_CLASSIFY_REQUEST_ERR = 216100 | fg_car_service[status:parse pb error] | 输入错误 |
GENERAL_CLASSIFY_IMAGE_ERR=216201 | fg_car_service[status:no image] fg_car_service[status:image empty] fg_car_service[status:image size < 50] |
图像出错 |
GENERAL_CLASSIFY_BACKEND_ERROR = 216400 | conf文件读取错误 | |
GENERAL_CLASSIFY_SUCCEED=0 | fg_car_service[status:succeed] | 成功 |
车流量统计
- 车辆检测与追踪:检测图像中的所有车辆,识别每辆车的类型和坐标位置,可根据连续的视频图片序列,跟踪车辆轨迹。
- 动态车流量统计:在原图中指定区域,根据车辆轨迹判断驶入/驶出区域的行为,统计各类车辆进出区域的数量,可返回含统计值和跟踪框的渲染图。
调用接口的地址示例:[192.168.0.1]:8120/GeneralClassifyService/classify,其中ip需要替换为用户自己服务器的ip,端口默认为:8120
路径
/GeneralClassifyService/classify
请求参数
字段 | 必需 | 类型 | 取值范围 | 说明 |
---|---|---|---|---|
dynamic | 是 | bool | True/False | True:动态车流检测,返回总车辆数、跟踪ID、动态车流;False:只进行静态车辆检测,返回总车辆数 |
appid | 否 | string | 区分不同的应用,无实际含义 | |
case_id | 当dynamic为True时,必需 | int | 任务ID(服务通过case_id区分不同视频流,用户自拟,不同序列间不可重复) | |
case_init | 当dynamic为True时,必需 | bool | True/False | 每个case的初始化信号,为true时对该case下的跟踪算法进行初始化,为false时从redis上重载该case的跟踪状态。当为false且redis上读取不到相应case的信息时,直接重新初始化。redis时效6000s |
cmd | 当dynamic为True时,必需 | string | track, finish | 跟踪过程使用track命令,结束时使用finish命令。当前版本track和finish没有区别 |
image | 是 | string | 0-255彩色图像(base64编码),size>50 | 输入数据中["image"]字段,图像数据,base64编码。异常:若图片尺寸长或宽小于10pix或大于4096pix会提示尺寸不在范围内。支持图片格式:jpg,bmp,png。 注意:图片的base64编码是不包含图片头的,如(data:image/jpg;base64,) |
show | 可选 | bool | True/False | 是否返回结果图(含统计值和跟踪框)。缺省时不返回。 |
area_static | 可选 | array(int) | 原图像素范围 | 静态车流统计时,只返回区域内的车辆数,格式为[[x1,y1,x2,y2,...,xn,yn]],按顺序依次给出每个顶点的xy坐标(尾点和首点相连),形成闭合多边形区域。服务会做范围(顶点左边需在图像范围内)及个数校验(数组长度必须为偶数,且大于3个顶点)。暂时只支持每次单个多边形区域建议设置矩形框,即4个顶点。坐标取值不能超过图像宽度和高度,比如1280的宽度,坐标值最大到1279 |
area_dynamic | 当dynamic为True时,必需 | array(int) | 原图像素范围 | 动态车流统计时,进出区域的车辆会被统计,格式为[[x1,y1,x2,y2,...,xn,yn]],按顺序依次给出每个顶点的xy坐标(尾点和首点相连),形成闭合多边形区域。服务会做范围(顶点左边需在图像范围内)及个数校验(数组长度必须为偶数,且大于3个顶点)。暂时只支持每次单个多边形区域,建议设置矩形框,即4个顶点。坐标取值不能超过图像宽度和高度,比如1280的宽度,坐标值最大到1279 |
请求参数构造及python代码示例
请求参数为json格式,请求时请将Content-Type设置为application/json格式。
请求参数格式如下:
1json
2{
3 req_array = {
4 'appid': '1234567',
5 'logid': logid,
6 'format': 'json',
7 'from': 'tet-python',
8 'cmdid': '123',
9 'clientip': '0.0.0.0',
10 'data': req_data
11 }
12}
python代码示例如下:
1python
2import base64
3import json
4
5# 输入图片
6image_file = "01.jpg"
7
8# 将图片内容读取至image_data
9with open(image_file, 'rb') as f:
10 image_data = f.read()
11
12data={}
13#准备request data
14data["appid"] = "123456"
15data["image"] = base64.b64encode(image_data)
16data["dynamic"] = False
17data["cmd"] = "track"
18data["case_id"] = 1322323
19data["case_init"] = True
20
21req_data = base64.b64encode(json.dumps(data))
22
23request_body = {
24 'appid': '1234567',
25 'logid': "202112061234",
26 'format': 'json',
27 'from': 'tet-python',
28 'cmdid': '123',
29 'clientip': '0.0.0.0',
30 'data': req_data
31 }
32
33# 最终应该传入http array的内容
34req_json = json.dumps(request_body)
返回参数
返回值格式:
参数 | 类型 | 必须 | 说明 |
---|---|---|---|
err_msg | string | 是 | 错误信息(参考错误码) |
err_no | uint32 | 是 | 错误码(参考错误码) |
result | json string | 是 | 返回结果信息,格式详见后文“示例返回值”。 |
image | string | 否 | 0-255彩色图像(base64编码的jpg编码文件) |
正确返回值说明:
字段 | 类型 | 说明 |
---|---|---|
vehicle_num | object | 检测到的车辆数目(单图) |
+car | int | 小汽车数量 |
+truck | int | 卡车数量 |
+bus | int | 巴士数量 |
+motorbike | int | 摩托车数量 |
+tricycle | int | 三轮车数量 |
vehicle_info | object数组 | 每个框的具体信息 |
+location | object | 跟踪到的车辆检测框位置 |
++left | int | 车辆检测框左坐标 |
++top | int | 车辆检测框顶坐标 |
++width | int | 车辆检测框宽度 |
++height | int | 车辆检测框高度 |
+ID | int | 车辆的ID编号 |
+type | string | 车辆类别 |
+score | float | 类别置信度 |
vehicle_count | object | 进出区域的车流统计 |
+car | object | 小汽车 |
++in | int | 当前帧相应车辆驶入区域的瞬时数量,如要计算某一段时间内进入区域的累计车辆数,可基于连续帧图片的返回结果计算得到(下同) |
++out | int | 当前帧相应车辆驶出区域的瞬时数量,如要计算某一段时间内离开区域的累计车辆数,可基于连续帧图片的返回结果计算得到(下同) |
+truck | object | 卡车 |
++in | int | |
++out | int | |
+bus | object | 巴士 |
++in | int | |
++out | int | |
+motorbike | object | 摩托车 |
++in | int | |
++out | int | |
+tricyle | object | 三轮车 |
++in | int | |
++out | int | |
image | string(jpg encode,base64) | 结果图,含跟踪框和统计值(渲染jpg图片byte内容的base64编码,请求端得到后先做base64解码再以字节流形式imdecode) |
渲染结果图说明
画面里刚出现的车辆检测框都是红色,被跟踪锁定之后会变成其他颜色(颜色随机,不同颜色没有特定规律),模型根据同颜色框的运动轨迹来判断进出移动方向;车辆被跟踪锁定后,检测框上方会出现车辆的ID编号,ID的取值逻辑为:每个case从1开始,不同车辆向上递增但不一定连续。
返回示例
dynamic为true时,执行连续帧动态跟踪和车流统计,前后帧之间同一目标具有相同ID
未检测到任何车辆:
1{
2 "vehicle_num":
3 {
4 "car":0,
5 "truck":0,
6 ...
7 "tricycle":0
8 },
9 "vehicle_info":[],
10 “vehicle_count”:
11 {
12 "car":
13 {
14 "in":0,
15 "out":0
16 },
17 "truck":
18 {
19 "in":0
20 "out":0
21 },
22 ...
23 }
24}
检测到1辆小汽车、1辆卡车,无轨迹,无车进出区域:
1{
2 "vehicle_num":
3 {
4 "car":0,
5 "truck":1,
6
7 ...
8
9 "tricycle":0
10
11 },
12
13 "vehicle_info":[],
14 “vehicle_count”:
15 {
16 "car":
17 {
18 "in":0,
19 "out":0
20 },
21 "truck":
22 {
23 "in":0
24 "out":0
25 },
26
27 ...
28
29 }
30}
检测到2辆小汽车、1辆卡车,3条轨迹,1辆卡车离开区域:
1{
2 "vehicle_num":
3 {
4 "car":2,
5 "truck":1,
6
7 ...
8
9 "tricycle":0
10
11 },
12
13 "vehicle_info":
14 [
15 {
16 "ID":3
17 "location":
18 {
19 "left": 100,
20 "top": 200,
21 "width": 200,
22 "height": 400,
23 }
24 "type": "car"
25 },
26 {
27 "ID": 5
28 "location":
29 {
30 "left": 400,
31 "top": 200,
32 "width": 200,
33 "height": 400,
34 }
35 "type": "car"
36 },
37 {
38 "ID": 6
39 "location":
40 {
41 "left": 600,
42 "top": 200,
43 "width": 300,
44 "height": 400,
45 }
46 "type": "truck"
47 }
48 ],
49 “vehicle_count”:
50 {
51 "car":
52 {
53 "in":0,
54 "out":0
55 },
56 "truck":
57 {
58 "in":0
59 "out":1
60 },
61
62 ...
63
64 }
65}
dynamic为false时,只执行单帧检测,ID仅为单帧图像内不同车辆的序号,前后帧之间ID无关联
未检测到任何车辆:
1{
2 "vehicle_num":
3 {
4 "car":0,
5 "truck":0,
6 ...
7 "tricycle":0
8 },
9 "vehicle_info":[],
10 “vehicle_count”:
11 {
12 "car":
13 {
14 "in":0,
15 "out":0
16 },
17 "truck":
18 {
19 "in":0
20 "out":0
21 },
22 ...
23 }
24}
检测到2辆小汽车、1辆卡车:
1{
2 "vehicle_num":
3 {
4 "car":2,
5 "truck":1,
6
7 ...
8
9 "tricycle":0
10
11 },
12
13 "vehicle_info":
14 [
15 {
16 "ID":0
17 "location":
18 {
19 "left": 100,
20 "top": 200,
21 "width": 200,
22 "height": 400,
23 }
24 "type": "car"
25 },
26 {
27 "ID": 1
28 "location":
29 {
30 "left": 400,
31 "top": 200,
32 "width": 200,
33 "height": 400,
34 }
35 "type": "car"
36 },
37 {
38 "ID": 2
39 "location":
40 {
41 "left": 600,
42 "top": 200,
43 "width": 300,
44 "height": 400,
45 }
46 "type": "truck"
47 }
48 ],
49 “vehicle_count”:
50 {
51 "car":
52 {
53 "in":0,
54 "out":0
55 },
56 "truck":
57 {
58 "in":0
59 "out":0
60 },
61
62 ...
63
64 }
65}
错误返回值
参数 | 类型 | 必选 | 说明 |
---|---|---|---|
err_msg | string | 是 | 错误信息,只在异常中出现(参考错误码) |
err_code | unit32 | 是 | 错误码,只在异常中出现(参考错误码) |
错误码表
err_no | value | err_msg | 解释 |
---|---|---|---|
GENERAL_CLASSIFY_SUCCEED | 0 | fg-jinlong[status:person counting succeed] | 整体流程成功 |
GENERAL_CLASSIFY_CONF_FILE_ERR | 216401 | GeneralClassifyProcessorFactory[status:reading conf file error] | 读取conf文件出错 |
GENERAL_CLASSIFY_BBOX_PREDICT_ERR | 216401 | GeneralClassify[status: bbox predict error!] | boudingbox检测过程出错 |
GENERAL_CLASSIFY_IMAGE_EMPTY_ERR | 216200 | fg-jinlong[status:empty image] | 输入数据中不存在“image”字段 |
GENERAL_CLASSIFY_IMAGE_FORMAT_ERR | 216201 | fg-jinlong[status:image format error] | 读取base64输入图片出错 |
GENERAL_CLASSIFY_IMAGE_SIZE_ERR | 216202 | fg-jinlong[status:image size not between 10 and 4096] | 输入图片尺寸不在允许范围之内 |
GENERAL_CLASSIFY_AUTH_ERR | 216401 | fg-jinlong[status:auth verify error] | 鉴权出错 |
GENERAL_CLASSIFY_FEATURE_EXTRACT_ERR | 216401 | GeneralClassify[status: re-id feature extract error!] | 特征提取过程出错 |
GENERAL_CLASSIFY_REDIS_ERR | 216401 | fg-jinlong[status:access redis error] | 访问redis过程出错 |
GENERAL_CLASSIFY_INPUT_FORMAT_ERR | 216100 | fg-jinlong[status:invalid input param] | 输入参数无效 |
GENERAL_CLASSIFY_INPUT_ABSENCE_ERR | 216101 | fg-jinlong[status:not enough input param] | 输入参数不完整 |