json.md 8.2 KB

Floorplan JSON 数据格式说明

本文档详细描述了户型图处理流程生成的 JSON 文件的数据结构。


完整结构概览

{
  "image_path": "string",
  "image_size": { "width": number, "height": number },
  "connect_area": [ ... ],
  "source_mask_path": "string",
  "connect_area_stats": { ... },
  "block": [ ... ],
  "furniture": [ ... ],
  "format_version": "string",
  "total_segments": number
}

关键是三个字段connect_area,block和furniture

字段详解

1. image_path (string)

  • 说明: 原始 RGB 图片的路径
  • 示例: "temp_data/SG-n6nV8B2oW95/SG-n6nV8B2oW95.png"

2. image_size (object)

  • 说明: 图像的宽度和高度(像素)
  • 字段:
    • width (number): 图像宽度
    • height (number): 图像高度
  • 示例: json { "width": 838, "height": 735 }

3. connect_area (array)

  • 说明: 连接区域列表(门/过道),用于描述房间之间的连接关系
  • 每个元素结构: json { "id": 0, // 连接区域 ID(从 0 开始) "x": 507, // 矩形左上角 X 坐标 "y": 341, // 矩形左上角 Y 坐标 "w": 31, // 矩形宽度 "h": 13, // 矩形高度 "block_pair": [3, 4], // 连接的房间 ID 对 "label": "door" // 连接类型(固定为 "door") }
  • 示意图: 房间 3 [connect_area: x=507, y=341] 房间 4 ┌─────────────┐ │ door │ └─────────────┘

4. source_mask_path (string)

  • 说明: 使用的 refine mask 图片路径
  • 示例: "temp_data/SG-n6nV8B2oW95/refine_mask_SG-n6nV8B2oW95.png"

5. connect_area_stats (object)

  • 说明: 连接区域检测的统计信息
  • 字段:
    • mask1_blocks (number): 检测到的房间块数量
    • mask2_fragments (number): mask2 中的碎片总数
    • bridge_fragments (number): 连接 2 个房间的碎片数量
    • group_count (number): 聚类后的组数
    • connect_area_count (number): 最终生成的连接区域数量
  • 示例: json { "mask1_blocks": 6, "mask2_fragments": 9, "bridge_fragments": 6, "group_count": 6, "connect_area_count": 6 }

6. block (array)

  • 说明: 房间块列表,每个房间由一系列线段(segments)组成
  • 每个元素结构: json { "id": 0, // 房间 ID(从 0 开始) "points": [ // 线段列表(整流后的格式) [447, 98, 108, 98], // 格式:[x1, y1, x2, y2],(x1,y1)为第一个点,(x2,y2)为第二个点 [108, 98, 108, 181], ... ], "label": "other_room", // 房间类型标签 "center": [308, 380], // 房间中心点坐标 [cx, cy] "refined": true, // 是否经过整流处理 "format": "segments", // 点数据格式("segments" 表示线段格式) "segment_count": 23 // 线段数量 }

6.1 block.points 线段格式

  • 格式: [x1, y1, x2, y2]
    • x1, y1: 线段起点坐标
    • x2, y2: 线段终点坐标
  • 示例: json "points": [ [447, 98, 108, 98], // 从 (447,98) 到 (108,98) 的水平线段 [108, 98, 108, 181], // 从 (108,98) 到 (108,181) 的垂直线段 ... ]

6.2 block.label 房间类型

说明
living_room 客厅
bed_room 卧室
bath_room 卫生间
kitchen_room 厨房
other_room 其他房间
balcony 阳台

7. furniture (array)

  • 说明: 家具检测结果列表
  • 每个元素结构: json { "id": 0, // 家具 ID "label": "bed", // 家具类型 "center": [679, 486], // 家具中心点坐标 [cx, cy] "points": { // 家具边界框(矩形) "x1": 627, "y1": 439, // 左上角坐标 "x2": 731, "y2": 439, // 右上角坐标 "x3": 731, "y3": 534, // 右下角坐标 "x4": 627, "y4": 534 // 左下角坐标 } }

7.1 furniture.label 家具类型

说明
sofa 沙发
chair 椅子
desk 桌子
bed
window 窗户

8. format_version (string)

  • 说明: JSON 数据格式版本号
  • 当前值: "segments_v1"
  • 说明: 表示 block.points 使用线段格式(segments)

9. total_segments (number)

  • 说明: 所有房间的线段总数
  • 示例: 56

坐标系说明

  • 原点: 图像左上角 (0, 0)
  • X 轴: 向右为正方向
  • Y 轴: 向下为正方向
(0,0) ─────────────────────→ X
  │
  │
  │
  │
  ↓
  Y

可视化示例

房间线段格式

房间轮廓由线段首尾相连组成:

  (x1,y1) ─────────── (x2,y2)
      │                    │
      │                    │
      │                    │
  (x4,y4) ─────────── (x3,y3)

每条线段格式:[x1, y1, x2, y2]

连接区域(门)

房间 0                    房间 1
  ┌────────┐    ┌────────┐
  │        │    │        │
  │        │====│        │  ← connect_area (矩形区域)
  │        │    │        │
  └────────┘    └────────┘

connect_area: {
  "x": ..., "y": ..., "w": ..., "h": ...,
  "block_pair": [0, 1],
  "label": "door"
}

数据生成流程

原始 RGB 图片
    │
    ▼
extract_initial_mask.py → initial_mask_xxx.png (带红边的二值 mask)
    │
    ▼
inference_refine_mask.py → refine_mask_xxx.png (优化的 mask)
    │
    ▼
pipeline.py → xxx.json (最终输出)
    │
    ├─ connect_area: 从 mask 提取房间连接区域
    ├─ block: 房间轮廓检测 + YOLO 房间分类
    ├─ furniture: YOLO 家具检测
    └─ 线段整流 + 跨房间合并
    │
    ▼
vis.py → xxx_vis.png (可视化结果)

使用示例

Python 读取 JSON

import json

with open('temp_data/SG-n6nV8B2oW95/SG-n6nV8B2oW95.json', 'r') as f:
    data = json.load(f)

# 获取图片尺寸
width = data['image_size']['width']
height = data['image_size']['height']

# 遍历所有房间
for block in data['block']:
    print(f"房间 {block['id']}: {block['label']}")
    print(f"  中心点:{block['center']}")
    print(f"  线段数:{block['segment_count']}")
    
    # 遍历线段
    for seg in block['points']:
        x1, y1, x2, y2 = seg
        print(f"    线段:({x1},{y1}) -> ({x2},{y2})")

# 遍历所有连接区域
for area in data['connect_area']:
    print(f"连接区域 {area['id']}: 房间 {area['block_pair'][0]} <-> {area['block_pair'][1]}")
    print(f"  位置:({area['x']}, {area['y']}) 尺寸:{area['w']}x{area['h']}")

# 遍历所有家具
for item in data['furniture']:
    print(f"家具 {item['id']}: {item['label']}")
    print(f"  中心:{item['center']}")
    print(f"  边界框:{item['points']}")

JavaScript 读取 JSON

const data = require('./SG-n6nV8B2oW95.json');

// 获取房间数量
console.log(`房间数量:${data.block.length}`);

// 获取所有卧室
const bedRooms = data.block.filter(b => b.label === 'bed_room');
console.log(`卧室数量:${bedRooms.length}`);

// 获取所有连接关系
data.connect_area.forEach(area => {
    console.log(`房间 ${area.block_pair[0]} <-> ${area.block_pair[1]}`);
});

版本历史

版本 说明
segments_v1 使用线段格式存储房间轮廓,支持整流和跨房间合并

注意事项

  1. 线段格式: block.points 中的线段是经过整流处理的(水平/垂直),不是原始多边形顶点
  2. 房间 ID: 从 0 开始连续编号
  3. 连接区域: block_pair 中的 ID 对应房间的 id 字段
  4. 家具检测: 仅检测允许的类型(sofa, chair, desk, bed, window)
  5. 坐标系统: 所有坐标都是相对于原始图片的像素坐标