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)
坐标系说明
- 原点: 图像左上角
(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 |
使用线段格式存储房间轮廓,支持整流和跨房间合并 |
注意事项
- 线段格式:
block.points 中的线段是经过整流处理的(水平/垂直),不是原始多边形顶点
- 房间 ID: 从 0 开始连续编号
- 连接区域:
block_pair 中的 ID 对应房间的 id 字段
- 家具检测: 仅检测允许的类型(sofa, chair, desk, bed, window)
- 坐标系统: 所有坐标都是相对于原始图片的像素坐标