You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非JSON兼容的Protobuf风格目标检测结果字符串解析优化咨询

最优解析方案:用Protobuf官方文本解析库

既然你处理的是Protobuf文本格式,官方原生解析工具是最靠谱的选择——完全适配格式规则,比正则或字符串替换稳定得多,也能轻松应对字段嵌套、类型变化等场景。

步骤实现

  1. 定义匹配的Protobuf结构文件
    根据你的ObjectDetectionPredictionResult结构,编写.proto文件(字段名、类型需和实际数据一致,示例如下):

    syntax = "proto3";
    
    message ObjectDetectionPredictionResult {
        string current_time = 1;
        repeated IdentifiedBox identified_boxes = 2;
    }
    
    message IdentifiedBox {
        float x_min = 1;
        float y_min = 2;
        float x_max = 3;
        float y_max = 4;
        string label = 5;
        float score = 6;
    }
    
  2. 生成Python解析代码
    用protoc编译proto文件,生成对应Python类:

    protoc --python_out=. your_proto_file.proto
    
  3. 解析文本并转JSON
    借助google.protobuf.text_format解析字符串,再转换为字典后生成目标JSON:

    from google.protobuf.text_format import Parse
    from your_proto_file_pb2 import ObjectDetectionPredictionResult
    import json
    
    # 从其他进程接收的Protobuf文本字符串
    proto_text = """
    current_time: "2024-05-20 14:30:00"
    identified_boxes {
        x_min: 100.5
        y_min: 80.2
        x_max: 200.7
        y_max: 180.3
        label: "car"
        score: 0.95
    }
    identified_boxes {
        x_min: 300.1
        y_min: 150.6
        x_max: 400.4
        y_max: 250.8
        label: "person"
        score: 0.92
    }
    """
    
    # 解析文本到Protobuf对象
    result = ObjectDetectionPredictionResult()
    Parse(proto_text, result)
    
    # 把Protobuf对象转成Python字典
    def proto_to_dict(proto_obj):
        result_dict = {}
        for field in proto_obj.DESCRIPTOR.fields:
            value = getattr(proto_obj, field.name)
            if field.type == field.TYPE_MESSAGE:
                if field.label == field.LABEL_REPEATED:
                    result_dict[field.name] = [proto_to_dict(item) for item in value]
                else:
                    result_dict[field.name] = proto_to_dict(value)
            elif field.type == field.TYPE_ENUM:
                result_dict[field.name] = value.name
            else:
                result_dict[field.name] = value
        return result_dict
    
    # 生成最终JSON
    output_json = json.dumps(proto_to_dict(result), indent=2)
    print(output_json)
    
备选方案:手动转换为JSON兼容格式(临时场景用)

如果不想依赖Protobuf编译,可通过字符串替换+字段格式化快速处理,适合临时调试:

import json

def proto_text_to_json(proto_text):
    lines = [line.strip() for line in proto_text.splitlines() if line.strip()]
    current_time = None
    boxes = []
    current_box = {}
    in_box = False

    for line in lines:
        if line.startswith("current_time:"):
            # 提取时间并补引号
            time_val = line.split(":", 1)[1].strip()
            current_time = time_val if time_val.startswith('"') else f'"{time_val}"'
        elif line == "identified_boxes {":
            in_box = True
            current_box = {}
        elif line == "}":
            in_box = False
            boxes.append(current_box)
        elif in_box:
            # 处理box内字段,补JSON格式的键值对
            key, val = line.split(":", 1)
            key = key.strip()
            val = val.strip()
            # 数字直接保留,字符串补引号
            if not val.replace(".", "").isdigit():
                val = f'"{val}"'
            current_box[key] = float(val) if "." in val else int(val) if val.isdigit() else val.strip('"')

    # 组装成目标JSON结构
    result = {
        "current_time": current_time.strip('"'),
        "identified_boxes": boxes
    }
    return json.dumps(result, indent=2)

# 测试示例
proto_text = """
current_time: 2024-05-20 14:30:00
identified_boxes {
    x_min: 100.5
    y_min: 80.2
    x_max: 200.7
    y_max: 180.3
    label: car
    score: 0.95
}
identified_boxes {
    x_min: 300.1
    y_min: 150.6
    x_max: 400.4
    y_max: 250.8
    label: person
    score: 0.92
}
"""

print(proto_text_to_json(proto_text))
方案对比
  • Protobuf官方库:稳定、灵活,支持复杂嵌套结构,字段类型自动处理,适合长期维护的项目,唯一成本是需要定义proto文件并编译。
  • 手动字符串转换:无需额外依赖,适合快速调试,但对格式变化兼容性差,新增字段或调整结构时容易出错。

内容的提问来源于stack exchange,提问作者Sebastian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:20:45