您的位置:首页 > 其它

tensorflow 目标检测API学习之protobuf

2017-12-27 10:27 1161 查看
[TOC]

google protobuf 谷歌开发者网站

proto

示例

syntax = "proto2";   //使用proto2语法编写

package protobuf;

message Object {
required int32 class = 1;
required float xmin = 2;
required float ymin = 3;
required float xmax = 4;
required float ymax = 5;
optional bool diffcult = 6 [default=false]; //设置默认值
}

message Label {
optional string filename = 1 [default=""];
optional int32 width = 2 [default=1];
optional int32 height = 3 [default=1];
enum Format {
option allow_alias = true; //允许出现别名
JPEG = 0;
JPG = 0;
BMP = 2;
PNG = 3;
}
optional Format format = 4 [default=JPG]; // 使用Format作为属性类型
repeated Object object = 5; //使用前面定义的Object作为属性类型
}


注释

protobuf中添加注释的方法和C++一样,使用//和/… /

指定包

给proto指定所属包能防止命名冲突。在Python里没有效果,因为Python模块是按照文件位置组织的。不过最好加上这一句,为其他语言编译此proto提供便利。

定义消息

定义message比较简单,每个message含有一个或多个属性(field)。定义属性按照属性规则 属性类型 属性名 = 编号;

属性规则

属性规则含义
required有且只有一个该属性
optional该属性有一个或零个,可设置默认值。若消息解析时没有找到该属性,则该属性被设成默认值
repeated该属性有零个或多个,且记录顺序

属性类型

标量类型



其他类型

其他类型包括枚举以及其他定义的消息类。

枚举允许出现别名,即同一个值对应不同的枚举常量, 只要在枚举类里设置option allow_alias = true;

编号

每个属性分配一个编号,且编号必须唯一。最小可用的编码是1,最大可用为2^29-1。不能使用19000到19999, 因为这是protobuf保留数字,使用会报错。将编号1到15分配给经常出现的属性, 同时给未来可能添加的属性预留编号。因为这些属性用一个字节编码,而16到2047用两个字节编码。

编译

protoc [OPTION] PROTO_FILES
--proto_path= PATH # proto_path: proto导入路径, 如果不给出, 使用当前工作路径
--python_out= OUT_DIR   # 生成Python源文件
例
protoc label.proto --python_out=. # 在当前目录下生成一个label_pb2.py文件


API

import label_pb2

label = label_pb2.Label()
label.filename = "test"
# label.filename = 1 TypeError: 1 has type int, but expected one of: bytes, unicode
# label.name = "test" AttributeError: Assignment not allowed (no field "name" in protocol message object).
label.format = label_pb2.Label.JPG

for i in range(2):
obj = label.object.add()

obj.catId = i
obj.xmin = float(i)
obj.ymin = float(i)
obj.xmax = float(i)
obj.ymax = float(i)

print label

"""
filename: "test"
format: JPG
object {
catId: 0
xmin: 0.0
ymin: 0.0
xmax: 0.0
ymax: 0.0
}
object {
catId: 1
xmin: 1.0
ymin: 1.0
xmax: 1.0
ymax: 1.0
}

"""


二进制写入

with open('test.record', 'wb') as f:
f.write(label.SerializeToString())


二进制读入

def read():
""""""
label = label_pb2.Label()
with open('test.record', 'rb') as f:
label.ParseFromString(f.read())
print label.filename
print label.width
print label.height
print label.format
print "objects: "
for obj in label.object:
print obj.catId, obj.diffcult
print obj.xmin, obj.ymin, obj.xmax, obj.ymax

"""
test.jpg
1
1
0
objects:
0 False
0.0 0.0 0.0 0.0
1 False
1.0 1.0 1.0 1.0
"""


配置文件读入

目标检测API采用是这种方法

"""
配置文件test.config内容如下:

filename: "test"
# 假如是ABC会报错google.protobuf.text_format.ParseError: 2:9 : Enum type
# "protobuf.Label.Format" has no value named abc.
format: JPG
object {
catId: 0
xmin: 0.0
ymin: 0.0
xmax: 0.0
ymax: 0.0
}
object {
catId: 1
xmin: 1.0
ymin: 1.0
xmax: 1.0
ymax: 1.0
}
"""
def readFromConfig():
""""""
from google.protobuf import text_format
label = label_pb2.Label()
with open('test.config', 'r') as f:
text_format.Merge(f.read(), label)

print label.filename
print label.width
print label.height
print label.format
print "objects: "
for obj in label.object:
print obj.catId, obj.diffcult
print obj.xmin, obj.ymin, obj.xmax, obj.ymax

"""
test
1
1
0
objects:
0 False
0.0 0.0 0.0 0.0
1 False
1.0 1.0 1.0 1.0
"""
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  tensorflow protobuf