diff --git a/.claude/skills/floorplan-recognizer/SKILL.md b/.claude/skills/floorplan-recognizer/SKILL.md new file mode 100644 index 0000000..2da9c9e --- /dev/null +++ b/.claude/skills/floorplan-recognizer/SKILL.md @@ -0,0 +1,74 @@ +--- +name: "floorplan-recognizer" +description: > + 户型图识别工具。当需要"识别户型图"、"解析户型"、"提取户型信息"、"看户型有哪些房间/窗户"、 + "floor plan recognition"、"户型图推导输入"时使用。用 qwen-vl-max 把链家等房产户型图解析成 + 结构化 JSON(房间/朝向/窗户形态),并生成「路径 B 文字钉死」片段,作为居民楼立面推导的可靠输入。 +--- + +# 户型图识别工具 (Floorplan Recognizer) + +> 户型图图片 → qwen-vl-max 解析 → 结构化 JSON + 「路径 B 文字钉死」片段 + +## 为什么需要它 + +AI 生图模型(GPT-Image-2)独立读户型图不可靠——会用"住宅常识"脑补(默认卧室大窗、阳台落地窗、漏房间), +导致路径 B「户型图推导」每张图都要**人工逐项校验窗户形态与比例**(见 `docs/art/美术风格指南.md` 路径 B 劣势)。 + +本工具先用专门的视觉大模型 qwen-vl-max 把户型图**解析成结构化清单**,把"人工逐项校验"降级为 +"AI 出清单 + 人工快速核对"。 + +> 评测结论(详见 `ai-art-research/生成结果/户型图识别评测/评测对比.md`):qwen-vl-max 在房间完整性、 +> 面积 OCR 精度、备注诚实度上领先 gpt-4o / qwen-vl-plus / gpt-4o-mini。 + +## 触发条件 + +- 用户说"识别/解析这张户型图"、"提取户型信息"、"看看这个户型有哪些房间/窗户" +- 路径 B 户型图推导前,需要可靠的「房间 + 窗户形态」清单作为"文字钉死"依据 +- 用户提供了一张链家/房产户型图要求分析 + +## 工具位置 + +``` +ai-art-research/tools/ + floorplan_parse.py # 生产版(固定 qwen-vl-max,生成文字钉死片段)⭐ 本技能用这个 + floorplan_eval.py # 评测版(可换模型对比) +``` + +依赖 `ai-art-research/.env` 的 `APIYI_API_KEY`(与 `image_gen.py` 共用)。 + +## 工作流 + +### 步骤 1:解析户型图 + +```bash +cd ai-art-research +python tools/floorplan_parse.py --image <户型图路径> +``` + +产出(存 `生成结果/户型图识别/`): +- `<时间戳>_apiyi_qwen-vl-max.json` — 结构化结果(房间/朝向/窗户/立面对应表) +- `<时间戳>_apiyi_qwen-vl-max.钉死.md` — 「路径 B 文字钉死」片段(可直接粘进生图 prompt) +- `.meta.json` — 调用元数据 + +### 步骤 2:人工快速核对 + +对照原图,重点核对「文字钉死」片段里的 ⚠️ 核对项(这些是评测发现的脑补重灾区): +- **卫生间朝向 / 是否暗卫**(模型间分歧最大) +- **阳台朝向**(皆南 vs 一南一北类分歧) +- **窗户类型 / 大小**(均为推测值) + +房间数量与单间面积经评测高度可信(qwen-vl-max 与 gpt-4o 面积 OCR 完全一致),一般无需核对。 + +### 步骤 3:喂给路径 B 生图 + +把核对后的「文字钉死」片段贴进 `ai-art-research/prompts/居民楼-*-户型图推导-v*.txt` 的窗户形态段落, +作为户型图推导立面的"文字钉死"依据,再走 `image_gen.py --fuse` 生图。 + +## 注意事项 + +- 走 API易 的 **vision chat 接口(按 token 计费)**,与生图通道(codex 按订阅 / apiyi 按张)独立,互不影响 +- 窗户类型/朝向/大小是模型**推测**,务必核对;房间结构与面积可信 +- 若某张图效果不稳,可用 `floorplan_eval.py --image <图> -m <模型>` 换模型对比(参考评测对比.md) +- 链家等彩色标准化户型图适配良好;纯手绘/模糊扫描图效果会下降 +- `ai-art-research/` 被项目 `.ignore` 屏蔽,操作需用显式路径(不进 Glob 检索) diff --git a/ai-art-research/tools/floorplan_eval.py b/ai-art-research/tools/floorplan_eval.py new file mode 100644 index 0000000..a014be2 --- /dev/null +++ b/ai-art-research/tools/floorplan_eval.py @@ -0,0 +1,364 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +ChildHood 户型图识别评测工具 +通过 vision 大模型把户型图解析成结构化 JSON(房间 / 朝向 / 窗户形态), +用于「路径 B — 户型图推导」的"文字钉死"环节,替代人工逐项校验。 + +配套:与 image_gen.py 同一工具链(共用 ai-art-research/.env、OpenAI 兼容客户端、 +生成结果/ 输出目录、.meta.json 元数据约定)。 + +Usage: + python floorplan_eval.py --image 户型图.png # 默认 provider + 默认模型 + python floorplan_eval.py --image 户型图.png -m qwen-vl-max # 指定模型 + python floorplan_eval.py --image 户型图.png --provider dashscope # 走阿里云百炼直连 + python floorplan_eval.py --image 户型图.png --prompt-file 自定义.txt # 自定义提取 prompt + +Requirements: + pip install openai python-dotenv +""" + +import argparse +import base64 +import io +import json +import os +import re +import sys +from datetime import datetime +from pathlib import Path + +# Windows 控制台 UTF-8 支持(用 reconfigure 幂等重配,避免被其他脚本 import 时 +# 产生双层 TextIOWrapper 包装、损坏输出流) +if sys.platform == "win32": + for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except Exception: + pass + +# --------------------------------------------------------------------------- +# 路径配置 +# --------------------------------------------------------------------------- +SCRIPT_DIR = Path(__file__).resolve().parent # ai-art-research/tools/ +RESEARCH_DIR = SCRIPT_DIR.parent # ai-art-research/ +DOTENV_PATH = RESEARCH_DIR / ".env" +OUTPUT_BASE = RESEARCH_DIR / "生成结果" / "户型图识别评测" + +# --------------------------------------------------------------------------- +# 加载 .env +# --------------------------------------------------------------------------- +if DOTENV_PATH.exists(): + from dotenv import load_dotenv + load_dotenv(DOTENV_PATH) + +# provider 配置 +APIYI_API_KEY = os.getenv("APIYI_API_KEY", "") +APIYI_BASE_URL = os.getenv("APIYI_BASE_URL", "https://api.apiyi.com/v1") +DASHSCOPE_API_KEY = os.getenv("DASHSCOPE_API_KEY", "") +DASHSCOPE_BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1" + +# 各 provider 的默认模型 +DEFAULT_MODEL = { + "apiyi": "qwen-vl-max", + "dashscope": "qwen-vl-max-latest", +} + +# --------------------------------------------------------------------------- +# 统一提取 prompt(核心:直接对接路径 B 的"文字钉死") +# --------------------------------------------------------------------------- +EXTRACT_PROMPT = """\ +你是一个专业的户型图解析助手。请仔细分析这张户型图,提取结构化信息。 + +【户型图符号约定】 +- 墙体:粗实线或双线 +- 门:弧线(表示开门方向) +- 窗:细的双平行线 +- 阳台:半开放区域,常带栏杆符号 +- 房间名:通常文字标注在房间内部(客厅/卧室/厨房/卫生间/阳台/餐厅/玄关等) +- 面积:常以 m² 数字标注在房间内或户型角落 +- 尺寸标尺:墙体旁的尺寸线(细线 + 两端短斜线/箭头)+ 数字,标注墙段长度 / 房间长宽,单位多为米(m)或毫米(mm) + +【严格规则】 +1. 只描述图上实际可见、或可明确推断的结构。禁止用"住宅常识"脑补—— + 不要默认卧室有大窗、阳台是落地窗、北面是厨房。 +2. 看不清或不确定的字段,一律填 "未知",绝不瞎猜。 +3. **重点提取尺寸标尺**:户型图外墙周边常有尺寸线(细线 + 数字)标注各开间/进深分段。请尽量读出南向开间分段、北向开间分段、进深分段的数字(多为米),填入"尺寸标注"——这是推导立面窗户水平比例的关键;看不清的分段填"未知"。 +4. 客餐厅若为一体空间(无明显实体隔断),合并为一个"客餐厅",不要拆成"客厅"+"餐厅"两个。 +5. 多个阳台若朝向不同,分别标注各自朝向(如一个朝南、一个朝北)。 +6. 输出必须是纯 JSON,不要任何解释文字、不要用 ```json 代码块包裹、不要前后缀。 + +【输出 JSON 结构】 +{ + "整体朝向": "主采光面朝向,如 南/北/东南;看不清填 未知", + "户型结构": "几室几厅几卫,如 三室两厅一卫", + "总面积": "图上标注的建筑面积,如 约 95 m²;无标注填 未知", + "房间": [ + { + "名称": "客厅/主卧/次卧/厨房/卫生间/阳台/餐厅/玄关...", + "朝向": "该房间主要采光朝向:南/北/东/西", + "面积估算": "图上有标注则填,否则 未知", + "长宽尺寸": "图上标尺标注的房间长与宽,如 3.6m×4.2m;无标尺填 未知", + "窗户": [ + {"所在立面": "南/北/东/西", "类型": "落地窗/普通窗/飘窗/无", "数量": 1, "推测大小": "大/中/小/未知"} + ], + "是否带阳台": "是/否/未知", + "备注": "其他可见特征,如 是否飘窗、是否暗卫(无窗)等" + } + ], + "尺寸标注": { + "说明": "图上外墙周边标尺的数字,用于推导立面窗户的水平开间比例", + "南向开间分段": ["如 3.6m", "4.2m"], + "北向开间分段": ["如 3.0m", "4.8m"], + "进深分段": ["如 5.1m", "3.2m"], + "总开间": "南立面总宽(有则填,无则未知)", + "总进深": "进深总长(有则填,无则未知)" + }, + "立面对应表": { + "说明": "哪些房间的窗户落在哪个外立面,用于推导正投影立面", + "南立面": ["客厅", "主卧"], + "北立面": ["厨房", "卫生间"] + }, + "识别备注": "图纸清晰度、符号可能误读之处、需要人工重点核对的项" +} + +现在请解析这张户型图,只输出 JSON。""" + + +# --------------------------------------------------------------------------- +# 工具函数 +# --------------------------------------------------------------------------- +def get_client(provider: str): + """根据 provider 创建 OpenAI 兼容客户端,返回 (client, default_model)""" + from openai import OpenAI + + if provider == "apiyi": + if not APIYI_API_KEY: + print("❌ 未找到 APIYI_API_KEY") + print(f" 请在 {DOTENV_PATH} 中设置: APIYI_API_KEY=sk-xxx") + sys.exit(1) + return OpenAI(api_key=APIYI_API_KEY, base_url=APIYI_BASE_URL) + elif provider == "dashscope": + if not DASHSCOPE_API_KEY: + print("❌ 未找到 DASHSCOPE_API_KEY") + print(" 阿里云百炼直连需要单独的 key:") + print(" 1. 前往 https://bailian.console.aliyun.com 申请 API Key") + print(f" 2. 在 {DOTENV_PATH} 中添加: DASHSCOPE_API_KEY=sk-xxx") + sys.exit(1) + return OpenAI(api_key=DASHSCOPE_API_KEY, base_url=DASHSCOPE_BASE_URL) + else: + print(f"❌ 未知 provider: {provider}(支持: apiyi / dashscope)") + sys.exit(1) + + +_EXT_MIME = { + ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", + ".webp": "image/webp", ".gif": "image/gif", +} + + +def encode_image(path: Path) -> str: + """读图为 base64 data URL""" + mime = _EXT_MIME.get(path.suffix.lower(), "image/png") + b64 = base64.b64encode(path.read_bytes()).decode() + return f"data:{mime};base64,{b64}" + + +def parse_floorplan(client, model: str, image_path: Path, prompt: str) -> str: + """调用 vision 模型,返回原始文本输出""" + data_url = encode_image(image_path) + response = client.chat.completions.create( + model=model, + messages=[{ + "role": "user", + "content": [ + {"type": "text", "text": prompt}, + {"type": "image_url", "image_url": {"url": data_url}}, + ], + }], + ) + return response.choices[0].message.content + + +def extract_json(text: str): + """从模型输出中尽量鲁棒地提取 JSON dict;失败返回 None""" + text = text.strip() + + # 1. 直接解析 + try: + return json.loads(text) + except json.JSONDecodeError: + pass + + # 2. 去掉 ```json ... ``` 代码块包裹 + fenced = re.search(r"```(?:json)?\s*(\{.*?\})\s*```", text, re.DOTALL) + if fenced: + try: + return json.loads(fenced.group(1)) + except json.JSONDecodeError: + pass + + # 3. 截取第一个 { 到最后一个 } + start, end = text.find("{"), text.rfind("}") + if start != -1 and end != -1 and end > start: + candidate = text[start:end + 1] + try: + return json.loads(candidate) + except json.JSONDecodeError: + # 4. 容错:清理常见问题(中文逗号、尾随逗号)后再试 + cleaned = (candidate + .replace(",", ",") + .replace(":", ":")) + cleaned = re.sub(r",(\s*[}\]])", r"\1", cleaned) # 去尾随逗号 + try: + return json.loads(cleaned) + except json.JSONDecodeError: + pass + return None + + +def save_result(result, metadata: dict, subdir: str = "") -> Path: + """保存解析结果 JSON + .meta.json,返回结果文件路径""" + ts = datetime.now().strftime("%y%m%d-%H%M%S") + model_slug = metadata.get("model", "unknown").replace("/", "-").replace(".", "-") + provider_slug = metadata.get("provider", "unknown") + base = f"{ts}_{provider_slug}_{model_slug}" + + out_dir = OUTPUT_BASE / subdir if subdir else OUTPUT_BASE + out_dir.mkdir(parents=True, exist_ok=True) + + json_path = out_dir / f"{base}.json" + json_path.write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8") + + meta_path = out_dir / f"{base}.meta.json" + meta_path.write_text(json.dumps(metadata, ensure_ascii=False, indent=2), encoding="utf-8") + + print(f"✅ 已保存: {json_path.name}") + return json_path + + +def summarize(parsed: dict) -> str: + """从解析结果里摘出要点用于控制台预览""" + if not isinstance(parsed, dict): + return "(非结构化结果)" + lines = [] + if parsed.get("户型结构"): + lines.append(f" 户型: {parsed['户型结构']}") + if parsed.get("整体朝向"): + lines.append(f" 朝向: {parsed['整体朝向']}") + if parsed.get("总面积"): + lines.append(f" 面积: {parsed['总面积']}") + rooms = parsed.get("房间", []) + if isinstance(rooms, list): + lines.append(f" 房间数: {len(rooms)}") + for r in rooms: + if isinstance(r, dict): + win_n = len(r.get("窗户", [])) if isinstance(r.get("窗户"), list) else 0 + lines.append(f" - {r.get('名称','?')} 朝向={r.get('朝向','?')} 窗={win_n} 阳台={r.get('是否带阳台','?')}") + return "\n".join(lines) + + +# --------------------------------------------------------------------------- +# CLI 入口 +# --------------------------------------------------------------------------- +def main(): + parser = argparse.ArgumentParser( + description="ChildHood 户型图识别评测工具 — vision 模型解析户型图为结构化 JSON", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog="""\ +示例: + python floorplan_eval.py --image 参考图/真实场景/户型图/QQ20260618-213247.png + python floorplan_eval.py --image 户型.png -m qwen-vl-max + python floorplan_eval.py --image 户型.png -m gemini-2.5-flash # baseline 对照 + python floorplan_eval.py --image 户型.png --provider dashscope # 百炼直连 + +环境变量 (ai-art-research/.env): + APIYI_API_KEY API易 令牌 (apiyi provider 用,复用 image_gen.py) + DASHSCOPE_API_KEY 阿里云百炼 key (dashscope provider 用) +""", + ) + + parser.add_argument("-i", "--image", type=str, required=True, help="户型图路径") + parser.add_argument("-m", "--model", type=str, help="vision 模型名(默认随 provider)") + parser.add_argument("--provider", type=str, default="apiyi", + choices=["apiyi", "dashscope"], help="API 来源(默认 apiyi 复用现有 key)") + parser.add_argument("--prompt-file", type=str, help="自定义提取 prompt 文件(默认用内置 EXTRACT_PROMPT)") + parser.add_argument("--out", type=str, help="自定义输出 JSON 路径(默认存 生成结果/户型图识别评测/)") + parser.add_argument("--raw", action="store_true", help="额外保存模型原始输出文本(便于排查解析失败)") + parser.add_argument("--subdir", type=str, default="", help="输出子目录名") + + args = parser.parse_args() + + image_path = Path(args.image).resolve() + if not image_path.exists(): + print(f"❌ 户型图不存在: {image_path}") + sys.exit(1) + + if args.prompt_file: + pf = Path(args.prompt_file).resolve() + if not pf.exists(): + print(f"❌ prompt 文件不存在: {pf}") + sys.exit(1) + prompt = pf.read_text(encoding="utf-8") + print(f"📄 从文件读取 prompt: {pf.name}") + else: + prompt = EXTRACT_PROMPT + + client = get_client(args.provider) + model = args.model or DEFAULT_MODEL[args.provider] + + print(f"🏠 户型图识别") + print(f" 图片: {image_path.name}") + print(f" Provider: {args.provider} 模型: {model}") + print() + + raw = parse_floorplan(client, model, image_path, prompt) + parsed = extract_json(raw) + + metadata = { + "provider": args.provider, + "model": model, + "image": str(image_path), + "prompt": prompt, + "parse_success": parsed is not None, + "timestamp": datetime.now().isoformat(), + } + + if parsed is None: + print("⚠️ 未能从模型输出中解析出 JSON(可能模型没遵守格式约束)。") + print(" 原始输出前 500 字:") + print(" " + raw[:500].replace("\n", "\n ")) + print() + print("💡 建议:换模型重试,或加 --raw 保留原文人工查看。") + + # 保存 + if args.out: + out_path = Path(args.out).resolve() + out_path.parent.mkdir(parents=True, exist_ok=True) + payload = parsed if parsed is not None else {"_raw": raw} + out_path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8") + meta_path = out_path.with_suffix(".meta.json") + meta_path.write_text(json.dumps(metadata, ensure_ascii=False, indent=2), encoding="utf-8") + print(f"✅ 已保存: {out_path.name}") + result_path = out_path + else: + payload = parsed if parsed is not None else {"_raw": raw} + result_path = save_result(payload, metadata, subdir=args.subdir) + + if args.raw: + raw_path = result_path.with_suffix(".raw.txt") + raw_path.write_text(raw, encoding="utf-8") + print(f"📝 原始输出: {raw_path.name}") + + print() + if parsed is not None: + print("📋 解析预览:") + print(summarize(parsed)) + print() + print(f"📍 完整结果: {result_path}") + print() + print("🔍 下一步:对照原图人工核对(重点看 房间是否漏识别、窗户数量/类型是否对)。") + + +if __name__ == "__main__": + main() diff --git a/ai-art-research/tools/floorplan_parse.py b/ai-art-research/tools/floorplan_parse.py new file mode 100644 index 0000000..e07ec00 --- /dev/null +++ b/ai-art-research/tools/floorplan_parse.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +ChildHood 户型图识别(生产版) +固定用 qwen-vl-max(经 API易)把户型图解析成结构化 JSON, +并额外生成「路径 B 文字钉死」Markdown 片段,可直接喂给居民楼立面推导 prompt。 + +与 floorplan_eval.py(评测版)共享解析逻辑;本脚本固定模型、聚焦产出可用文本。 +评测结论见:生成结果/户型图识别评测/评测对比.md(qwen-vl-max 领先)。 + +Usage: + python floorplan_parse.py --image 户型图.png + python floorplan_parse.py --image 户型图.png --out 结果.json + python floorplan_parse.py --image 户型图.png --no-pin # 不生成文字钉死片段 + +Requirements: + pip install openai python-dotenv +""" + +import argparse +import io +import json +import sys +from datetime import datetime +from pathlib import Path + +# Windows 控制台 UTF-8 支持(用 reconfigure 幂等重配,避免被其他脚本 import 时 +# 产生双层 TextIOWrapper 包装、损坏输出流) +if sys.platform == "win32": + for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except Exception: + pass + +# --------------------------------------------------------------------------- +# 路径配置 +# --------------------------------------------------------------------------- +SCRIPT_DIR = Path(__file__).resolve().parent # ai-art-research/tools/ +RESEARCH_DIR = SCRIPT_DIR.parent # ai-art-research/ +OUTPUT_BASE = RESEARCH_DIR / "生成结果" / "户型图识别" + +# 让同目录的 floorplan_eval 可被 import +sys.path.insert(0, str(SCRIPT_DIR)) + +# --------------------------------------------------------------------------- +# 生产配置(评测选出的最优组合,固定不变) +# --------------------------------------------------------------------------- +PROVIDER = "apiyi" +MODEL = "qwen-vl-max" + +from floorplan_eval import ( # noqa: E402 (import 在 sys.path 调整之后) + EXTRACT_PROMPT, + get_client, + encode_image, + parse_floorplan, + extract_json, + summarize, +) + + +# --------------------------------------------------------------------------- +# 增值:生成「路径 B 文字钉死」片段 +# --------------------------------------------------------------------------- +_FACES = ("南", "北", "东", "西") + + +def _face_key(orientation: str) -> str: + """把朝向归一到 南/北/东/西/未知""" + s = str(orientation or "") + for k in _FACES: + if k in s: + return k + return "未知" + + +def _window_desc(room: dict) -> str: + wins = room.get("窗户", []) + if not isinstance(wins, list) or not wins: + return "无窗" + parts = [] + for w in wins: + if isinstance(w, dict): + parts.append(f"{w.get('类型', '?')}×{w.get('数量', '?')}({w.get('推测大小', '?')})") + return "、".join(parts) if parts else "有窗" + + +def generate_pin_text(parsed: dict) -> str: + """把解析结果转成「路径 B 文字钉死」Markdown 片段,按立面组织窗户形态""" + if not isinstance(parsed, dict): + return "(解析结果非结构化,无法生成钉死片段)" + + lines = [] + lines.append("# 户型图解析 → 路径 B「文字钉死」片段") + lines.append("") + lines.append(f"> qwen-vl-max 解析 · 户型 {parsed.get('户型结构', '未知')} · 整体朝向 {parsed.get('整体朝向', '未知')}") + lines.append("> ⚠️ 窗户类型/朝向/大小均为模型推测,**须对照原图核对后再用于生图**。") + lines.append("") + + rooms = parsed.get("房间", []) + rooms = [r for r in rooms if isinstance(r, dict)] if isinstance(rooms, list) else [] + + # 按立面分组 + by_face = {k: [] for k in _FACES} + by_face["未知"] = [] + review_notes = [] + for r in rooms: + face = _face_key(r.get("朝向")) + area = r.get("面积估算", "未知") + size = str(r.get("长宽尺寸", "") or "") + size_str = f",{size}" if size and size != "未知" else "" + desc = (f"- {r.get('名称', '?')}({area}{size_str}):{_window_desc(r)};" + f"阳台={r.get('是否带阳台', '?')}") + by_face[face].append(desc) + + # 收集脑补重灾区(卫生间暗卫 / 疑似暗房) + name = str(r.get("名称", "")) + rmk = str(r.get("备注", "") or "") + if "卫" in name: + review_notes.append(f"卫生间「{name}」朝向={face},是否暗卫?备注={rmk}") + elif "暗" in rmk: + review_notes.append(f"「{name}」疑似暗房(无直接采光),核对是否有窗:备注={rmk}") + + lines.append("## 各立面窗户形态(直接钉死立面图的窗户)") + for face in _FACES: + items = by_face.get(face, []) + if items: + lines.append(f"\n### {face}立面") + lines.extend(items) + if by_face.get("未知"): + lines.append("\n### 朝向未知 / 内部空间") + lines.extend(by_face["未知"]) + + # 模型给出的立面对应表 + lmap = parsed.get("立面对应表", {}) + if isinstance(lmap, dict) and any(k != "说明" for k in lmap): + lines.append("") + lines.append("## 模型立面对应表(参考)") + for k, v in lmap.items(): + if k == "说明": + continue + lines.append(f"- {k}: {v}") + + # 外墙尺寸标尺(用于推导立面开间比例) + dim = parsed.get("尺寸标注", {}) + if isinstance(dim, dict) and any(k != "说明" for k in dim): + lines.append("") + lines.append("## 外墙尺寸标尺(推导立面开间比例用)") + for k, v in dim.items(): + if k == "说明": + continue + lines.append(f"- {k}: {v}") + + # 需核对项 + lines.append("") + lines.append("## ⚠️ 人工核对重点") + if review_notes: + for n in review_notes: + lines.append(f"- {n}") + lines.append("- 窗户「类型 / 大小」均为推测,对照原图逐间确认") + total = parsed.get("总面积", "") + if not total or total == "未知": + lines.append("- 总面积模型未识别,精确值看原图标注") + note = parsed.get("识别备注", "") + if note: + lines.append(f"- 模型自述:{note}") + return "\n".join(lines) + + +# --------------------------------------------------------------------------- +# CLI 入口 +# --------------------------------------------------------------------------- +def main(): + parser = argparse.ArgumentParser( + description="ChildHood 户型图识别(生产版)— qwen-vl-max 解析户型图 + 生成路径 B 文字钉死片段", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog="""\ +示例: + python floorplan_parse.py --image 参考图/真实场景/户型图/xxx.png + python floorplan_parse.py --image 户型.png --out 我的结果.json + python floorplan_parse.py --image 户型.png --no-pin # 只要 JSON,不要钉死片段 + +环境变量 (ai-art-research/.env): + APIYI_API_KEY API易 令牌(与 image_gen.py 共用) +""", + ) + parser.add_argument("-i", "--image", type=str, required=True, help="户型图路径") + parser.add_argument("--out", type=str, help="自定义输出 JSON 路径(默认存 生成结果/户型图识别/)") + parser.add_argument("--no-pin", action="store_true", help="不生成「路径 B 文字钉死」片段") + parser.add_argument("--subdir", type=str, default="", help="输出子目录名") + + args = parser.parse_args() + + image_path = Path(args.image).resolve() + if not image_path.exists(): + print(f"❌ 户型图不存在: {image_path}") + sys.exit(1) + + client = get_client(PROVIDER) + + print(f"🏠 户型图识别(生产版)") + print(f" 图片: {image_path.name}") + print(f" Provider: {PROVIDER} 模型: {MODEL}") + print() + + raw = parse_floorplan(client, MODEL, image_path, EXTRACT_PROMPT) + parsed = extract_json(raw) + + metadata = { + "provider": PROVIDER, + "model": MODEL, + "image": str(image_path), + "parse_success": parsed is not None, + "timestamp": datetime.now().isoformat(), + } + + if parsed is None: + print("⚠️ 未能从模型输出中解析出 JSON。原始输出前 500 字:") + print(" " + raw[:500].replace("\n", "\n ")) + + # 保存 + if args.out: + out_path = Path(args.out).resolve() + out_path.parent.mkdir(parents=True, exist_ok=True) + payload = parsed if parsed is not None else {"_raw": raw} + out_path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8") + meta_path = out_path.with_suffix(".meta.json") + meta_path.write_text(json.dumps(metadata, ensure_ascii=False, indent=2), encoding="utf-8") + print(f"✅ 已保存: {out_path.name}") + base_path = out_path + else: + ts = datetime.now().strftime("%y%m%d-%H%M%S") + model_slug = MODEL.replace("/", "-").replace(".", "-") + base = f"{ts}_{PROVIDER}_{model_slug}" + out_dir = OUTPUT_BASE / args.subdir if args.subdir else OUTPUT_BASE + out_dir.mkdir(parents=True, exist_ok=True) + payload = parsed if parsed is not None else {"_raw": raw} + json_path = out_dir / f"{base}.json" + json_path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8") + meta_path = out_dir / f"{base}.meta.json" + meta_path.write_text(json.dumps(metadata, ensure_ascii=False, indent=2), encoding="utf-8") + print(f"✅ 已保存: {json_path.name}") + base_path = json_path + + # 生成「路径 B 文字钉死」片段 + if parsed is not None and not args.no_pin: + pin_text = generate_pin_text(parsed) + pin_path = base_path.with_suffix(".钉死.md") + pin_path.write_text(pin_text, encoding="utf-8") + print(f"📝 文字钉死: {pin_path.name}") + + print() + if parsed is not None: + print("📋 解析预览:") + print(summarize(parsed)) + print() + print(f"📍 结果: {base_path}") + if parsed is not None and not args.no_pin: + print(f"📍 钉死片段: {base_path.with_suffix('.钉死.md')}") + print() + print("🔍 下一步:对照原图核对 ⚠️ 项(卫生间朝向/暗卫、阳台朝向、窗户大小),") + print(" 再把钉死片段贴进 prompts/居民楼-*-户型图推导-v*.txt 走路径 B 生图。") + + +if __name__ == "__main__": + main() diff --git a/ai-art-research/生成结果/户型图识别/260620-221147_apiyi_qwen-vl-max.json b/ai-art-research/生成结果/户型图识别/260620-221147_apiyi_qwen-vl-max.json new file mode 100644 index 0000000..eaccf4c --- /dev/null +++ b/ai-art-research/生成结果/户型图识别/260620-221147_apiyi_qwen-vl-max.json @@ -0,0 +1,172 @@ +{ + "整体朝向": "南", + "户型结构": "四室两厅两卫", + "总面积": "未知", + "房间": [ + { + "名称": "客厅", + "朝向": "南", + "面积估算": "38.46㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "是", + "备注": "与南侧阳台相连,阳台面积5.57㎡" + }, + { + "名称": "餐厅", + "朝向": "南", + "面积估算": "38.46㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "是", + "备注": "与客厅共用空间,无独立标注,共享南侧采光" + }, + { + "名称": "主卧", + "朝向": "南", + "面积估算": "17.02㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "位于南侧,有独立窗户" + }, + { + "名称": "次卧", + "朝向": "南", + "面积估算": "14.32㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "位于南侧,有独立窗户" + }, + { + "名称": "卧室", + "朝向": "北", + "面积估算": "9.33㎡", + "窗户": [ + { + "所在立面": "北", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于北侧,靠近走廊" + }, + { + "名称": "卧室", + "朝向": "北", + "面积估算": "9.24㎡", + "窗户": [ + { + "所在立面": "北", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于北侧,靠近走廊" + }, + { + "名称": "卫生间", + "朝向": "东", + "面积估算": "4.93㎡", + "窗户": [ + { + "所在立面": "东", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于客餐厅东侧,有窗" + }, + { + "名称": "卫生间", + "朝向": "东", + "面积估算": "5.74㎡", + "窗户": [ + { + "所在立面": "东", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于客餐厅东侧,有窗" + }, + { + "名称": "阳台", + "朝向": "南", + "面积估算": "5.57㎡", + "窗户": [], + "是否带阳台": "是", + "备注": "位于南侧,半开放区域" + }, + { + "名称": "阳台", + "朝向": "南", + "面积估算": "6.09㎡", + "窗户": [], + "是否带阳台": "是", + "备注": "位于南侧,半开放区域" + }, + { + "名称": "走廊", + "朝向": "未知", + "面积估算": "12.31㎡", + "窗户": [], + "是否带阳台": "否", + "备注": "连接各房间的通道,无直接采光" + } + ], + "立面对应表": { + "说明": "根据图示窗户位置及方位箭头判断外立面分布", + "南立面": [ + "客厅", + "餐厅", + "主卧", + "次卧", + "阳台", + "阳台" + ], + "北立面": [ + "卧室", + "卧室" + ], + "东立面": [ + "卫生间", + "卫生间" + ], + "西立面": [] + }, + "识别备注": "图纸清晰,符号规范;所有房间均有面积标注;南北向布局明确;阳台为半开放区域,未标明栏杆细节;两个卫生间均在东侧,有窗,非暗卫;客餐厅合并设计,未分隔;走廊无窗,为内部通道。" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别/260620-221147_apiyi_qwen-vl-max.meta.json b/ai-art-research/生成结果/户型图识别/260620-221147_apiyi_qwen-vl-max.meta.json new file mode 100644 index 0000000..c3504aa --- /dev/null +++ b/ai-art-research/生成结果/户型图识别/260620-221147_apiyi_qwen-vl-max.meta.json @@ -0,0 +1,7 @@ +{ + "provider": "apiyi", + "model": "qwen-vl-max", + "image": "E:\\MiceCola\\work\\ChildHood\\ai-art-research\\参考图\\真实场景\\户型图\\QQ20260618-213247.png", + "parse_success": true, + "timestamp": "2026-06-20T22:11:47.452574" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别/260620-221147_apiyi_qwen-vl-max.钉死.md b/ai-art-research/生成结果/户型图识别/260620-221147_apiyi_qwen-vl-max.钉死.md new file mode 100644 index 0000000..d917068 --- /dev/null +++ b/ai-art-research/生成结果/户型图识别/260620-221147_apiyi_qwen-vl-max.钉死.md @@ -0,0 +1,38 @@ +# 户型图解析 → 路径 B「文字钉死」片段 + +> qwen-vl-max 解析 · 户型 四室两厅两卫 · 整体朝向 南 +> ⚠️ 窗户类型/朝向/大小均为模型推测,**须对照原图核对后再用于生图**。 + +## 各立面窗户形态(直接钉死立面图的窗户) + +### 南立面 +- 客厅(38.46㎡):普通窗×1(大);阳台=是 +- 餐厅(38.46㎡):普通窗×1(大);阳台=是 +- 主卧(17.02㎡):普通窗×1(中);阳台=否 +- 次卧(14.32㎡):普通窗×1(中);阳台=否 +- 阳台(5.57㎡):无窗;阳台=是 +- 阳台(6.09㎡):无窗;阳台=是 + +### 北立面 +- 卧室(9.33㎡):普通窗×1(小);阳台=否 +- 卧室(9.24㎡):普通窗×1(小);阳台=否 + +### 东立面 +- 卫生间(4.93㎡):普通窗×1(小);阳台=否 +- 卫生间(5.74㎡):普通窗×1(小);阳台=否 + +### 朝向未知 / 内部空间 +- 走廊(12.31㎡):无窗;阳台=否 + +## 模型立面对应表(参考) +- 南立面: ['客厅', '餐厅', '主卧', '次卧', '阳台', '阳台'] +- 北立面: ['卧室', '卧室'] +- 东立面: ['卫生间', '卫生间'] +- 西立面: [] + +## ⚠️ 人工核对重点 +- 卫生间「卫生间」朝向=东,是否暗卫?备注=位于客餐厅东侧,有窗 +- 卫生间「卫生间」朝向=东,是否暗卫?备注=位于客餐厅东侧,有窗 +- 窗户「类型 / 大小」均为推测,对照原图逐间确认 +- 总面积模型未识别,精确值看原图标注 +- 模型自述:图纸清晰,符号规范;所有房间均有面积标注;南北向布局明确;阳台为半开放区域,未标明栏杆细节;两个卫生间均在东侧,有窗,非暗卫;客餐厅合并设计,未分隔;走廊无窗,为内部通道。 \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别/260620-222709_apiyi_qwen-vl-max.json b/ai-art-research/生成结果/户型图识别/260620-222709_apiyi_qwen-vl-max.json new file mode 100644 index 0000000..9f95fff --- /dev/null +++ b/ai-art-research/生成结果/户型图识别/260620-222709_apiyi_qwen-vl-max.json @@ -0,0 +1,171 @@ +{ + "整体朝向": "南", + "户型结构": "四室两厅两卫", + "总面积": "未知", + "房间": [ + { + "名称": "客厅", + "朝向": "南", + "面积估算": "38.46㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "是", + "备注": "与南侧阳台相连,阳台面积5.57㎡" + }, + { + "名称": "餐厅", + "朝向": "南", + "面积估算": "38.46㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "是", + "备注": "与客厅共用空间,共享南向采光和阳台" + }, + { + "名称": "主卧", + "朝向": "南", + "面积估算": "17.02㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "位于西南角,有独立窗户" + }, + { + "名称": "次卧", + "朝向": "南", + "面积估算": "14.32㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "位于东南角,有独立窗户" + }, + { + "名称": "卧室", + "朝向": "北", + "面积估算": "9.33㎡", + "窗户": [ + { + "所在立面": "北", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于西北角,无明显采光优势" + }, + { + "名称": "卧室", + "朝向": "北", + "面积估算": "9.24㎡", + "窗户": [ + { + "所在立面": "北", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于东北角,与前一卧室并列" + }, + { + "名称": "卫生间", + "朝向": "东", + "面积估算": "4.93㎡", + "窗户": [ + { + "所在立面": "东", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于客餐厅东侧,有窗户,非暗卫" + }, + { + "名称": "卫生间", + "朝向": "东", + "面积估算": "5.74㎡", + "窗户": [ + { + "所在立面": "东", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于客餐厅东侧下方,有窗户,非暗卫" + }, + { + "名称": "阳台", + "朝向": "南", + "面积估算": "5.57㎡", + "窗户": [], + "是否带阳台": "是", + "备注": "位于客餐厅南侧,为封闭式阳台" + }, + { + "名称": "阳台", + "朝向": "南", + "面积估算": "6.09㎡", + "窗户": [], + "是否带阳台": "是", + "备注": "位于客餐厅南侧下方,为封闭式阳台" + }, + { + "名称": "走廊", + "朝向": "未知", + "面积估算": "12.31㎡", + "窗户": [], + "是否带阳台": "否", + "备注": "连接各卧室与客餐厅的通道,无窗户" + } + ], + "立面对应表": { + "说明": "根据窗户分布推断各房间对应的外立面", + "南立面": [ + "客厅", + "餐厅", + "主卧", + "次卧", + "阳台", + "阳台" + ], + "北立面": [ + "卧室", + "卧室" + ], + "东立面": [ + "卫生间", + "卫生间" + ] + }, + "识别备注": "图纸清晰,标注完整;所有房间均有明确面积与名称;阳台为两个独立区域,分别标注面积;部分房间窗户位置需结合墙体判断,但未显示具体窗型(如飘窗);走廊无窗户,为内部空间;整体布局对称性较好。" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别/260620-222709_apiyi_qwen-vl-max.meta.json b/ai-art-research/生成结果/户型图识别/260620-222709_apiyi_qwen-vl-max.meta.json new file mode 100644 index 0000000..2b09815 --- /dev/null +++ b/ai-art-research/生成结果/户型图识别/260620-222709_apiyi_qwen-vl-max.meta.json @@ -0,0 +1,7 @@ +{ + "provider": "apiyi", + "model": "qwen-vl-max", + "image": "E:\\MiceCola\\work\\ChildHood\\ai-art-research\\参考图\\真实场景\\户型图\\QQ20260618-213247.png", + "parse_success": true, + "timestamp": "2026-06-20T22:27:09.984692" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别/260620-222709_apiyi_qwen-vl-max.钉死.md b/ai-art-research/生成结果/户型图识别/260620-222709_apiyi_qwen-vl-max.钉死.md new file mode 100644 index 0000000..f9d4d02 --- /dev/null +++ b/ai-art-research/生成结果/户型图识别/260620-222709_apiyi_qwen-vl-max.钉死.md @@ -0,0 +1,37 @@ +# 户型图解析 → 路径 B「文字钉死」片段 + +> qwen-vl-max 解析 · 户型 四室两厅两卫 · 整体朝向 南 +> ⚠️ 窗户类型/朝向/大小均为模型推测,**须对照原图核对后再用于生图**。 + +## 各立面窗户形态(直接钉死立面图的窗户) + +### 南立面 +- 客厅(38.46㎡):普通窗×1(大);阳台=是 +- 餐厅(38.46㎡):普通窗×1(大);阳台=是 +- 主卧(17.02㎡):普通窗×1(中);阳台=否 +- 次卧(14.32㎡):普通窗×1(中);阳台=否 +- 阳台(5.57㎡):无窗;阳台=是 +- 阳台(6.09㎡):无窗;阳台=是 + +### 北立面 +- 卧室(9.33㎡):普通窗×1(小);阳台=否 +- 卧室(9.24㎡):普通窗×1(小);阳台=否 + +### 东立面 +- 卫生间(4.93㎡):普通窗×1(小);阳台=否 +- 卫生间(5.74㎡):普通窗×1(小);阳台=否 + +### 朝向未知 / 内部空间 +- 走廊(12.31㎡):无窗;阳台=否 + +## 模型立面对应表(参考) +- 南立面: ['客厅', '餐厅', '主卧', '次卧', '阳台', '阳台'] +- 北立面: ['卧室', '卧室'] +- 东立面: ['卫生间', '卫生间'] + +## ⚠️ 人工核对重点 +- 卫生间「卫生间」朝向=东,是否暗卫?备注=位于客餐厅东侧,有窗户,非暗卫 +- 卫生间「卫生间」朝向=东,是否暗卫?备注=位于客餐厅东侧下方,有窗户,非暗卫 +- 窗户「类型 / 大小」均为推测,对照原图逐间确认 +- 总面积模型未识别,精确值看原图标注 +- 模型自述:图纸清晰,标注完整;所有房间均有明确面积与名称;阳台为两个独立区域,分别标注面积;部分房间窗户位置需结合墙体判断,但未显示具体窗型(如飘窗);走廊无窗户,为内部空间;整体布局对称性较好。 \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别/260620-223845_apiyi_qwen-vl-max.json b/ai-art-research/生成结果/户型图识别/260620-223845_apiyi_qwen-vl-max.json new file mode 100644 index 0000000..56403b7 --- /dev/null +++ b/ai-art-research/生成结果/户型图识别/260620-223845_apiyi_qwen-vl-max.json @@ -0,0 +1,165 @@ +{ + "整体朝向": "南", + "户型结构": "四室两厅两卫", + "总面积": "约 108.69 m²", + "房间": [ + { + "名称": "客餐厅", + "朝向": "南", + "面积估算": "38.46m²", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "未知" + } + ], + "是否带阳台": "是", + "备注": "南侧连接阳台,北侧与两个卫生间相邻" + }, + { + "名称": "卧室", + "朝向": "北", + "面积估算": "9.33m²", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "北", + "类型": "普通窗", + "数量": 1, + "推测大小": "未知" + } + ], + "是否带阳台": "否", + "备注": "位于北侧,无直接采光窗可见,可能为暗房" + }, + { + "名称": "卧室", + "朝向": "北", + "面积估算": "9.24m²", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "北", + "类型": "普通窗", + "数量": 1, + "推测大小": "未知" + } + ], + "是否带阳台": "否", + "备注": "位于北侧,无直接采光窗可见,可能为暗房" + }, + { + "名称": "卧室", + "朝向": "南", + "面积估算": "17.02m²", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "否", + "备注": "南向,有窗户,面积较大" + }, + { + "名称": "卧室", + "朝向": "南", + "面积估算": "14.32m²", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "南向,有窗户" + }, + { + "名称": "卫生间", + "朝向": "东", + "面积估算": "4.93m²", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "东", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于客餐厅东侧,有窗户" + }, + { + "名称": "卫生间", + "朝向": "东", + "面积估算": "5.74m²", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "东", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于客餐厅东侧,有窗户" + }, + { + "名称": "阳台", + "朝向": "南", + "面积估算": "5.57m²", + "长宽尺寸": "未知", + "窗户": [], + "是否带阳台": "是", + "备注": "位于客餐厅上方,南向" + }, + { + "名称": "阳台", + "朝向": "南", + "面积估算": "6.09m²", + "长宽尺寸": "未知", + "窗户": [], + "是否带阳台": "是", + "备注": "位于客餐厅下方,南向" + }, + { + "名称": "走廊", + "朝向": "未知", + "面积估算": "12.31m²", + "长宽尺寸": "未知", + "窗户": [], + "是否带阳台": "否", + "备注": "连接四个卧室的中央通道" + } + ], + "立面对应表": { + "说明": "根据窗户位置和朝向推断各房间在建筑外立面的分布", + "南立面": [ + "客餐厅", + "卧室", + "卧室", + "阳台", + "阳台" + ], + "北立面": [ + "卧室", + "卧室" + ], + "东立面": [ + "卫生间", + "卫生间" + ] + }, + "识别备注": "图纸清晰,尺寸标注完整,但部分房间窗户具体类型无法确定;南北向墙体长度可读取,但房间内部长宽未直接标注,需估算;两个阳台均朝南,且分别位于客餐厅上下方。" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别/260620-223845_apiyi_qwen-vl-max.meta.json b/ai-art-research/生成结果/户型图识别/260620-223845_apiyi_qwen-vl-max.meta.json new file mode 100644 index 0000000..e9f747f --- /dev/null +++ b/ai-art-research/生成结果/户型图识别/260620-223845_apiyi_qwen-vl-max.meta.json @@ -0,0 +1,7 @@ +{ + "provider": "apiyi", + "model": "qwen-vl-max", + "image": "E:\\MiceCola\\work\\ChildHood\\ai-art-research\\参考图\\真实场景\\户型图\\QQ20260618-213247.png", + "parse_success": true, + "timestamp": "2026-06-20T22:38:45.808641" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别/260620-223845_apiyi_qwen-vl-max.钉死.md b/ai-art-research/生成结果/户型图识别/260620-223845_apiyi_qwen-vl-max.钉死.md new file mode 100644 index 0000000..fd03809 --- /dev/null +++ b/ai-art-research/生成结果/户型图识别/260620-223845_apiyi_qwen-vl-max.钉死.md @@ -0,0 +1,37 @@ +# 户型图解析 → 路径 B「文字钉死」片段 + +> qwen-vl-max 解析 · 户型 四室两厅两卫 · 整体朝向 南 +> ⚠️ 窗户类型/朝向/大小均为模型推测,**须对照原图核对后再用于生图**。 + +## 各立面窗户形态(直接钉死立面图的窗户) + +### 南立面 +- 客餐厅(38.46m²):普通窗×1(未知);阳台=是 +- 卧室(17.02m²):普通窗×1(大);阳台=否 +- 卧室(14.32m²):普通窗×1(中);阳台=否 +- 阳台(5.57m²):无窗;阳台=是 +- 阳台(6.09m²):无窗;阳台=是 + +### 北立面 +- 卧室(9.33m²):普通窗×1(未知);阳台=否 +- 卧室(9.24m²):普通窗×1(未知);阳台=否 + +### 东立面 +- 卫生间(4.93m²):普通窗×1(小);阳台=否 +- 卫生间(5.74m²):普通窗×1(小);阳台=否 + +### 朝向未知 / 内部空间 +- 走廊(12.31m²):无窗;阳台=否 + +## 模型立面对应表(参考) +- 南立面: ['客餐厅', '卧室', '卧室', '阳台', '阳台'] +- 北立面: ['卧室', '卧室'] +- 东立面: ['卫生间', '卫生间'] + +## ⚠️ 人工核对重点 +- 卫生间「卧室」朝向=北,是否暗卫?备注=位于北侧,无直接采光窗可见,可能为暗房 +- 卫生间「卧室」朝向=北,是否暗卫?备注=位于北侧,无直接采光窗可见,可能为暗房 +- 卫生间「卫生间」朝向=东,是否暗卫?备注=位于客餐厅东侧,有窗户 +- 卫生间「卫生间」朝向=东,是否暗卫?备注=位于客餐厅东侧,有窗户 +- 窗户「类型 / 大小」均为推测,对照原图逐间确认 +- 模型自述:图纸清晰,尺寸标注完整,但部分房间窗户具体类型无法确定;南北向墙体长度可读取,但房间内部长宽未直接标注,需估算;两个阳台均朝南,且分别位于客餐厅上下方。 \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别/260620-224315_apiyi_qwen-vl-max.json b/ai-art-research/生成结果/户型图识别/260620-224315_apiyi_qwen-vl-max.json new file mode 100644 index 0000000..75f9bec --- /dev/null +++ b/ai-art-research/生成结果/户型图识别/260620-224315_apiyi_qwen-vl-max.json @@ -0,0 +1,186 @@ +{ + "整体朝向": "南", + "户型结构": "四室两厅两卫", + "总面积": "未知", + "房间": [ + { + "名称": "客餐厅", + "朝向": "南", + "面积估算": "38.46㎡", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "南", + "类型": "未知", + "数量": 1, + "推测大小": "未知" + } + ], + "是否带阳台": "是", + "备注": "南侧连接阳台,北侧连接两个卫生间" + }, + { + "名称": "卧室", + "朝向": "北", + "面积估算": "9.33㎡", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "北", + "类型": "未知", + "数量": 1, + "推测大小": "未知" + } + ], + "是否带阳台": "否", + "备注": "位于北侧,与走廊相邻" + }, + { + "名称": "卧室", + "朝向": "北", + "面积估算": "9.24㎡", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "北", + "类型": "未知", + "数量": 1, + "推测大小": "未知" + } + ], + "是否带阳台": "否", + "备注": "位于北侧,与走廊相邻" + }, + { + "名称": "卧室", + "朝向": "南", + "面积估算": "17.02㎡", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "南", + "类型": "未知", + "数量": 1, + "推测大小": "未知" + } + ], + "是否带阳台": "否", + "备注": "位于南侧,靠近走廊" + }, + { + "名称": "卧室", + "朝向": "南", + "面积估算": "14.32㎡", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "南", + "类型": "未知", + "数量": 1, + "推测大小": "未知" + } + ], + "是否带阳台": "否", + "备注": "位于南侧,靠近走廊" + }, + { + "名称": "卫生间", + "朝向": "北", + "面积估算": "4.93㎡", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "北", + "类型": "未知", + "数量": 1, + "推测大小": "未知" + } + ], + "是否带阳台": "否", + "备注": "位于客餐厅北侧,无窗可见" + }, + { + "名称": "卫生间", + "朝向": "北", + "面积估算": "5.74㎡", + "长宽尺寸": "未知", + "窗户": [ + { + "所在立面": "北", + "类型": "未知", + "数量": 1, + "推测大小": "未知" + } + ], + "是否带阳台": "否", + "备注": "位于客餐厅北侧,无窗可见" + }, + { + "名称": "阳台", + "朝向": "南", + "面积估算": "5.57㎡", + "长宽尺寸": "未知", + "窗户": [], + "是否带阳台": "是", + "备注": "位于客餐厅南侧,为半开放区域" + }, + { + "名称": "阳台", + "朝向": "南", + "面积估算": "6.09㎡", + "长宽尺寸": "未知", + "窗户": [], + "是否带阳台": "是", + "备注": "位于客餐厅南侧,为半开放区域" + }, + { + "名称": "走廊", + "朝向": "未知", + "面积估算": "12.31㎡", + "长宽尺寸": "未知", + "窗户": [], + "是否带阳台": "否", + "备注": "连接各卧室和客餐厅的公共通道" + } + ], + "尺寸标注": { + "说明": "图上外墙周边标尺的数字,用于推导立面窗户的水平开间比例", + "南向开间分段": [ + "3.581m", + "3.051m", + "4.695m" + ], + "北向开间分段": [ + "1.352m", + "2.649m", + "2.631m", + "4.768m" + ], + "进深分段": [ + "1.486m", + "4.571m", + "5.334m", + "1.335m", + "3.964m" + ], + "总开间": "11.327m", + "总进深": "11.327m" + }, + "立面对应表": { + "说明": "哪些房间的窗户落在哪个外立面,用于推导正投影立面", + "南立面": [ + "客餐厅", + "卧室", + "卧室", + "阳台", + "阳台" + ], + "北立面": [ + "卧室", + "卧室", + "卫生间", + "卫生间" + ] + }, + "识别备注": "图纸清晰度良好,尺寸标注完整。部分房间窗户类型无法明确判断,需结合实际建筑确认。阳台有两个,均朝南,但未标注具体栏杆或门窗形式。" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别/260620-224315_apiyi_qwen-vl-max.meta.json b/ai-art-research/生成结果/户型图识别/260620-224315_apiyi_qwen-vl-max.meta.json new file mode 100644 index 0000000..2f39d63 --- /dev/null +++ b/ai-art-research/生成结果/户型图识别/260620-224315_apiyi_qwen-vl-max.meta.json @@ -0,0 +1,7 @@ +{ + "provider": "apiyi", + "model": "qwen-vl-max", + "image": "E:\\MiceCola\\work\\ChildHood\\ai-art-research\\参考图\\真实场景\\户型图\\QQ20260618-213247.png", + "parse_success": true, + "timestamp": "2026-06-20T22:43:15.203475" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别/260620-224315_apiyi_qwen-vl-max.钉死.md b/ai-art-research/生成结果/户型图识别/260620-224315_apiyi_qwen-vl-max.钉死.md new file mode 100644 index 0000000..d958c4a --- /dev/null +++ b/ai-art-research/生成结果/户型图识别/260620-224315_apiyi_qwen-vl-max.钉死.md @@ -0,0 +1,40 @@ +# 户型图解析 → 路径 B「文字钉死」片段 + +> qwen-vl-max 解析 · 户型 四室两厅两卫 · 整体朝向 南 +> ⚠️ 窗户类型/朝向/大小均为模型推测,**须对照原图核对后再用于生图**。 + +## 各立面窗户形态(直接钉死立面图的窗户) + +### 南立面 +- 客餐厅(38.46㎡):未知×1(未知);阳台=是 +- 卧室(17.02㎡):未知×1(未知);阳台=否 +- 卧室(14.32㎡):未知×1(未知);阳台=否 +- 阳台(5.57㎡):无窗;阳台=是 +- 阳台(6.09㎡):无窗;阳台=是 + +### 北立面 +- 卧室(9.33㎡):未知×1(未知);阳台=否 +- 卧室(9.24㎡):未知×1(未知);阳台=否 +- 卫生间(4.93㎡):未知×1(未知);阳台=否 +- 卫生间(5.74㎡):未知×1(未知);阳台=否 + +### 朝向未知 / 内部空间 +- 走廊(12.31㎡):无窗;阳台=否 + +## 模型立面对应表(参考) +- 南立面: ['客餐厅', '卧室', '卧室', '阳台', '阳台'] +- 北立面: ['卧室', '卧室', '卫生间', '卫生间'] + +## 外墙尺寸标尺(推导立面开间比例用) +- 南向开间分段: ['3.581m', '3.051m', '4.695m'] +- 北向开间分段: ['1.352m', '2.649m', '2.631m', '4.768m'] +- 进深分段: ['1.486m', '4.571m', '5.334m', '1.335m', '3.964m'] +- 总开间: 11.327m +- 总进深: 11.327m + +## ⚠️ 人工核对重点 +- 卫生间「卫生间」朝向=北,是否暗卫?备注=位于客餐厅北侧,无窗可见 +- 卫生间「卫生间」朝向=北,是否暗卫?备注=位于客餐厅北侧,无窗可见 +- 窗户「类型 / 大小」均为推测,对照原图逐间确认 +- 总面积模型未识别,精确值看原图标注 +- 模型自述:图纸清晰度良好,尺寸标注完整。部分房间窗户类型无法明确判断,需结合实际建筑确认。阳台有两个,均朝南,但未标注具体栏杆或门窗形式。 \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别评测/260620-215036_apiyi_qwen-vl-max.json b/ai-art-research/生成结果/户型图识别评测/260620-215036_apiyi_qwen-vl-max.json new file mode 100644 index 0000000..7577f17 --- /dev/null +++ b/ai-art-research/生成结果/户型图识别评测/260620-215036_apiyi_qwen-vl-max.json @@ -0,0 +1,167 @@ +{ + "整体朝向": "南", + "户型结构": "四室两厅两卫", + "总面积": "未知", + "房间": [ + { + "名称": "客厅", + "朝向": "南", + "面积估算": "38.46㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "是", + "备注": "与南侧阳台相连,阳台面积5.57㎡" + }, + { + "名称": "餐厅", + "朝向": "南", + "面积估算": "38.46㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "是", + "备注": "与客厅共用空间,未单独标注面积" + }, + { + "名称": "主卧", + "朝向": "南", + "面积估算": "17.02㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "位于西南角,有门通向走廊" + }, + { + "名称": "次卧", + "朝向": "南", + "面积估算": "14.32㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "位于东南角,有门通向走廊" + }, + { + "名称": "卧室", + "朝向": "北", + "面积估算": "9.33㎡", + "窗户": [ + { + "所在立面": "北", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于西北角,无明确采光说明" + }, + { + "名称": "卧室", + "朝向": "北", + "面积估算": "9.24㎡", + "窗户": [ + { + "所在立面": "北", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于东北角,无明确采光说明" + }, + { + "名称": "卫生间", + "朝向": "南", + "面积估算": "4.93㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于客餐厅南侧,有窗" + }, + { + "名称": "卫生间", + "朝向": "南", + "面积估算": "5.74㎡", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于客餐厅南侧下方,有窗" + }, + { + "名称": "阳台", + "朝向": "南", + "面积估算": "5.57㎡", + "窗户": [], + "是否带阳台": "是", + "备注": "位于客餐厅上方,半开放区域" + }, + { + "名称": "阳台", + "朝向": "南", + "面积估算": "6.09㎡", + "窗户": [], + "是否带阳台": "是", + "备注": "位于客餐厅下方,半开放区域" + }, + { + "名称": "走廊", + "朝向": "未知", + "面积估算": "12.31㎡", + "窗户": [], + "是否带阳台": "否", + "备注": "连接各卧室与公共区域,无窗户" + } + ], + "立面对应表": { + "说明": "根据图示窗户位置推断各房间外立面分布", + "南立面": [ + "客厅", + "餐厅", + "卫生间", + "卫生间", + "阳台", + "阳台" + ], + "北立面": [ + "卧室", + "卧室" + ] + }, + "识别备注": "图纸清晰,方向标显示北方在上;所有房间均有面积标注,但总面积未标明;两个阳台分别位于客餐厅上下两侧,均与客餐厅相连;部分房间窗户仅以细双线示意,未标注具体类型;走廊无窗户,为暗走道;需人工核对阳台是否可直接进入或仅作通风用途。" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别评测/260620-215036_apiyi_qwen-vl-max.meta.json b/ai-art-research/生成结果/户型图识别评测/260620-215036_apiyi_qwen-vl-max.meta.json new file mode 100644 index 0000000..8a39e2d --- /dev/null +++ b/ai-art-research/生成结果/户型图识别评测/260620-215036_apiyi_qwen-vl-max.meta.json @@ -0,0 +1,8 @@ +{ + "provider": "apiyi", + "model": "qwen-vl-max", + "image": "E:\\MiceCola\\work\\ChildHood\\ai-art-research\\参考图\\真实场景\\户型图\\QQ20260618-213247.png", + "prompt": "你是一个专业的户型图解析助手。请仔细分析这张户型图,提取结构化信息。\n\n【户型图符号约定】\n- 墙体:粗实线或双线\n- 门:弧线(表示开门方向)\n- 窗:细的双平行线\n- 阳台:半开放区域,常带栏杆符号\n- 房间名:通常文字标注在房间内部(客厅/卧室/厨房/卫生间/阳台/餐厅/玄关等)\n- 面积:常以 m² 数字标注在房间内或户型角落\n\n【严格规则】\n1. 只描述图上实际可见、或可明确推断的结构。禁止用\"住宅常识\"脑补——\n 不要默认卧室有大窗、阳台是落地窗、北面是厨房。\n2. 看不清或不确定的字段,一律填 \"未知\",绝不瞎猜。\n3. 输出必须是纯 JSON,不要任何解释文字、不要用 ```json 代码块包裹、不要前后缀。\n\n【输出 JSON 结构】\n{\n \"整体朝向\": \"主采光面朝向,如 南/北/东南;看不清填 未知\",\n \"户型结构\": \"几室几厅几卫,如 三室两厅一卫\",\n \"总面积\": \"图上标注的建筑面积,如 约 95 m²;无标注填 未知\",\n \"房间\": [\n {\n \"名称\": \"客厅/主卧/次卧/厨房/卫生间/阳台/餐厅/玄关...\",\n \"朝向\": \"该房间主要采光朝向:南/北/东/西\",\n \"面积估算\": \"图上有标注则填,否则 未知\",\n \"窗户\": [\n {\"所在立面\": \"南/北/东/西\", \"类型\": \"落地窗/普通窗/飘窗/无\", \"数量\": 1, \"推测大小\": \"大/中/小/未知\"}\n ],\n \"是否带阳台\": \"是/否/未知\",\n \"备注\": \"其他可见特征,如 是否飘窗、是否暗卫(无窗)等\"\n }\n ],\n \"立面对应表\": {\n \"说明\": \"哪些房间的窗户落在哪个外立面,用于推导正投影立面\",\n \"南立面\": [\"客厅\", \"主卧\"],\n \"北立面\": [\"厨房\", \"卫生间\"]\n },\n \"识别备注\": \"图纸清晰度、符号可能误读之处、需要人工重点核对的项\"\n}\n\n现在请解析这张户型图,只输出 JSON。", + "parse_success": true, + "timestamp": "2026-06-20T21:50:36.094853" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别评测/260620-215110_apiyi_gpt-4o.json b/ai-art-research/生成结果/户型图识别评测/260620-215110_apiyi_gpt-4o.json new file mode 100644 index 0000000..3a1aeee --- /dev/null +++ b/ai-art-research/生成结果/户型图识别评测/260620-215110_apiyi_gpt-4o.json @@ -0,0 +1,156 @@ +{ + "整体朝向": "南", + "户型结构": "四室一厅两卫", + "总面积": "未知", + "房间": [ + { + "名称": "客厅", + "朝向": "南", + "面积估算": "38.46 m²", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "是", + "备注": "与南侧阳台相连" + }, + { + "名称": "卧室", + "朝向": "北", + "面积估算": "9.33 m²", + "窗户": [ + { + "所在立面": "北", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "无其他明显特征" + }, + { + "名称": "卧室", + "朝向": "北", + "面积估算": "9.24 m²", + "窗户": [ + { + "所在立面": "北", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "无其他明显特征" + }, + { + "名称": "卧室", + "朝向": "南", + "面积估算": "17.02 m²", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "否", + "备注": "无其他明显特征" + }, + { + "名称": "卧室", + "朝向": "南", + "面积估算": "14.32 m²", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "否", + "备注": "无其他明显特征" + }, + { + "名称": "卫生间", + "朝向": "东", + "面积估算": "4.93 m²", + "窗户": [ + { + "所在立面": "东", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "暗卫(面积小,采光不足)" + }, + { + "名称": "卫生间", + "朝向": "东", + "面积估算": "5.74 m²", + "窗户": [ + { + "所在立面": "东", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "无其他明显特征" + }, + { + "名称": "阳台", + "朝向": "南", + "面积估算": "6.09 m²", + "窗户": [], + "是否带阳台": "否", + "备注": "独立阳台" + }, + { + "名称": "阳台", + "朝向": "北", + "面积估算": "5.57 m²", + "窗户": [], + "是否带阳台": "否", + "备注": "独立阳台" + }, + { + "名称": "走廊", + "朝向": "未知", + "面积估算": "12.31 m²", + "窗户": [], + "是否带阳台": "否", + "备注": "连接多房间" + } + ], + "立面对应表": { + "说明": "哪些房间的窗户落在哪个外立面,用于推导正投影立面", + "南立面": [ + "客厅", + "卧室1", + "卧室2" + ], + "北立面": [ + "卧室3", + "卧室4" + ], + "东立面": [ + "卫生间1", + "卫生间2" + ], + "西立面": [ + "未知" + ] + }, + "识别备注": "图纸清晰度高,大部分房间特征明确;走廊无法判断采光方向" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别评测/260620-215110_apiyi_gpt-4o.meta.json b/ai-art-research/生成结果/户型图识别评测/260620-215110_apiyi_gpt-4o.meta.json new file mode 100644 index 0000000..823afe8 --- /dev/null +++ b/ai-art-research/生成结果/户型图识别评测/260620-215110_apiyi_gpt-4o.meta.json @@ -0,0 +1,8 @@ +{ + "provider": "apiyi", + "model": "gpt-4o", + "image": "E:\\MiceCola\\work\\ChildHood\\ai-art-research\\参考图\\真实场景\\户型图\\QQ20260618-213247.png", + "prompt": "你是一个专业的户型图解析助手。请仔细分析这张户型图,提取结构化信息。\n\n【户型图符号约定】\n- 墙体:粗实线或双线\n- 门:弧线(表示开门方向)\n- 窗:细的双平行线\n- 阳台:半开放区域,常带栏杆符号\n- 房间名:通常文字标注在房间内部(客厅/卧室/厨房/卫生间/阳台/餐厅/玄关等)\n- 面积:常以 m² 数字标注在房间内或户型角落\n\n【严格规则】\n1. 只描述图上实际可见、或可明确推断的结构。禁止用\"住宅常识\"脑补——\n 不要默认卧室有大窗、阳台是落地窗、北面是厨房。\n2. 看不清或不确定的字段,一律填 \"未知\",绝不瞎猜。\n3. 输出必须是纯 JSON,不要任何解释文字、不要用 ```json 代码块包裹、不要前后缀。\n\n【输出 JSON 结构】\n{\n \"整体朝向\": \"主采光面朝向,如 南/北/东南;看不清填 未知\",\n \"户型结构\": \"几室几厅几卫,如 三室两厅一卫\",\n \"总面积\": \"图上标注的建筑面积,如 约 95 m²;无标注填 未知\",\n \"房间\": [\n {\n \"名称\": \"客厅/主卧/次卧/厨房/卫生间/阳台/餐厅/玄关...\",\n \"朝向\": \"该房间主要采光朝向:南/北/东/西\",\n \"面积估算\": \"图上有标注则填,否则 未知\",\n \"窗户\": [\n {\"所在立面\": \"南/北/东/西\", \"类型\": \"落地窗/普通窗/飘窗/无\", \"数量\": 1, \"推测大小\": \"大/中/小/未知\"}\n ],\n \"是否带阳台\": \"是/否/未知\",\n \"备注\": \"其他可见特征,如 是否飘窗、是否暗卫(无窗)等\"\n }\n ],\n \"立面对应表\": {\n \"说明\": \"哪些房间的窗户落在哪个外立面,用于推导正投影立面\",\n \"南立面\": [\"客厅\", \"主卧\"],\n \"北立面\": [\"厨房\", \"卫生间\"]\n },\n \"识别备注\": \"图纸清晰度、符号可能误读之处、需要人工重点核对的项\"\n}\n\n现在请解析这张户型图,只输出 JSON。", + "parse_success": true, + "timestamp": "2026-06-20T21:51:10.745258" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别评测/260620-215257_apiyi_qwen-vl-plus.json b/ai-art-research/生成结果/户型图识别评测/260620-215257_apiyi_qwen-vl-plus.json new file mode 100644 index 0000000..010da6e --- /dev/null +++ b/ai-art-research/生成结果/户型图识别评测/260620-215257_apiyi_qwen-vl-plus.json @@ -0,0 +1,133 @@ +{ + "整体朝向": "南", + "户型结构": "三室两厅两卫", + "总面积": "约 195.8 m²", + "房间": [ + { + "名称": "主卧", + "朝向": "南", + "面积估算": "17.02 m²", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "否", + "备注": "位于户型左下角,主要采光面为南" + }, + { + "名称": "次卧1", + "朝向": "南", + "面积估算": "9.33 m²", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "位于户型左上角,主要采光面为南" + }, + { + "名称": "次卧2", + "朝向": "南", + "面积估算": "9.24 m²", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "位于户型左上角,与次卧1并排,主要采光面为南" + }, + { + "名称": "客餐厅", + "朝向": "南", + "面积估算": "38.46 m²", + "窗户": [ + { + "所在立面": "南", + "类型": "普通窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "是", + "备注": "位于户型中部,连接南北两侧,主要采光面为南" + }, + { + "名称": "卫生间1", + "朝向": "西", + "面积估算": "4.93 m²", + "窗户": [ + { + "所在立面": "西", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于户型右侧,北侧,无直接采光面" + }, + { + "名称": "卫生间2", + "朝向": "西", + "面积估算": "5.74 m²", + "窗户": [ + { + "所在立面": "西", + "类型": "普通窗", + "数量": 1, + "推测大小": "小" + } + ], + "是否带阳台": "否", + "备注": "位于户型右侧,南侧,紧邻卫生间1" + }, + { + "名称": "阳台1", + "朝向": "南", + "面积估算": "5.57 m²", + "窗户": [], + "是否带阳台": "否", + "备注": "位于户型右上角,与客餐厅相连" + }, + { + "名称": "阳台2", + "朝向": "南", + "面积估算": "6.09 m²", + "窗户": [], + "是否带阳台": "否", + "备注": "位于户型右下角,与主卧相邻" + } + ], + "立面对应表": { + "说明": "哪些房间的窗户落在哪个外立面,用于推导正投影立面", + "南立面": [ + "主卧", + "次卧1", + "次卧2", + "客餐厅", + "阳台1", + "阳台2" + ], + "北立面": [ + "客餐厅" + ], + "东立面": [], + "西立面": [ + "卫生间1", + "卫生间2" + ] + }, + "识别备注": "图纸清晰,符号约定明确。需人工核对各房间窗户的具体位置和朝向,特别是阳台与主卧、客餐厅的连接关系。" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别评测/260620-215257_apiyi_qwen-vl-plus.meta.json b/ai-art-research/生成结果/户型图识别评测/260620-215257_apiyi_qwen-vl-plus.meta.json new file mode 100644 index 0000000..372bb86 --- /dev/null +++ b/ai-art-research/生成结果/户型图识别评测/260620-215257_apiyi_qwen-vl-plus.meta.json @@ -0,0 +1,8 @@ +{ + "provider": "apiyi", + "model": "qwen-vl-plus", + "image": "E:\\MiceCola\\work\\ChildHood\\ai-art-research\\参考图\\真实场景\\户型图\\QQ20260618-213247.png", + "prompt": "你是一个专业的户型图解析助手。请仔细分析这张户型图,提取结构化信息。\n\n【户型图符号约定】\n- 墙体:粗实线或双线\n- 门:弧线(表示开门方向)\n- 窗:细的双平行线\n- 阳台:半开放区域,常带栏杆符号\n- 房间名:通常文字标注在房间内部(客厅/卧室/厨房/卫生间/阳台/餐厅/玄关等)\n- 面积:常以 m² 数字标注在房间内或户型角落\n\n【严格规则】\n1. 只描述图上实际可见、或可明确推断的结构。禁止用\"住宅常识\"脑补——\n 不要默认卧室有大窗、阳台是落地窗、北面是厨房。\n2. 看不清或不确定的字段,一律填 \"未知\",绝不瞎猜。\n3. 输出必须是纯 JSON,不要任何解释文字、不要用 ```json 代码块包裹、不要前后缀。\n\n【输出 JSON 结构】\n{\n \"整体朝向\": \"主采光面朝向,如 南/北/东南;看不清填 未知\",\n \"户型结构\": \"几室几厅几卫,如 三室两厅一卫\",\n \"总面积\": \"图上标注的建筑面积,如 约 95 m²;无标注填 未知\",\n \"房间\": [\n {\n \"名称\": \"客厅/主卧/次卧/厨房/卫生间/阳台/餐厅/玄关...\",\n \"朝向\": \"该房间主要采光朝向:南/北/东/西\",\n \"面积估算\": \"图上有标注则填,否则 未知\",\n \"窗户\": [\n {\"所在立面\": \"南/北/东/西\", \"类型\": \"落地窗/普通窗/飘窗/无\", \"数量\": 1, \"推测大小\": \"大/中/小/未知\"}\n ],\n \"是否带阳台\": \"是/否/未知\",\n \"备注\": \"其他可见特征,如 是否飘窗、是否暗卫(无窗)等\"\n }\n ],\n \"立面对应表\": {\n \"说明\": \"哪些房间的窗户落在哪个外立面,用于推导正投影立面\",\n \"南立面\": [\"客厅\", \"主卧\"],\n \"北立面\": [\"厨房\", \"卫生间\"]\n },\n \"识别备注\": \"图纸清晰度、符号可能误读之处、需要人工重点核对的项\"\n}\n\n现在请解析这张户型图,只输出 JSON。", + "parse_success": true, + "timestamp": "2026-06-20T21:52:57.654663" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别评测/260620-215311_apiyi_gpt-4o-mini.json b/ai-art-research/生成结果/户型图识别评测/260620-215311_apiyi_gpt-4o-mini.json new file mode 100644 index 0000000..1492b88 --- /dev/null +++ b/ai-art-research/生成结果/户型图识别评测/260620-215311_apiyi_gpt-4o-mini.json @@ -0,0 +1,126 @@ +{ + "整体朝向": "南", + "户型结构": "三室一厅两卫", + "总面积": "约 95 m²", + "房间": [ + { + "名称": "客厅", + "朝向": "南", + "面积估算": "38.46 m²", + "窗户": [ + { + "所在立面": "南", + "类型": "落地窗", + "数量": 1, + "推测大小": "大" + } + ], + "是否带阳台": "是", + "备注": "无" + }, + { + "名称": "主卧", + "朝向": "北", + "面积估算": "17.02 m²", + "窗户": [ + { + "所在立面": "北", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "无" + }, + { + "名称": "次卧", + "朝向": "北", + "面积估算": "14.32 m²", + "窗户": [ + { + "所在立面": "北", + "类型": "普通窗", + "数量": 1, + "推测大小": "中" + } + ], + "是否带阳台": "否", + "备注": "无" + }, + { + "名称": "卫生间", + "朝向": "北", + "面积估算": "4.93 m²", + "窗户": [ + { + "所在立面": "北", + "类型": "无", + "数量": 0, + "推测大小": "无" + } + ], + "是否带阳台": "否", + "备注": "无" + }, + { + "名称": "卫生间", + "朝向": "北", + "面积估算": "5.74 m²", + "窗户": [ + { + "所在立面": "北", + "类型": "无", + "数量": 0, + "推测大小": "无" + } + ], + "是否带阳台": "否", + "备注": "无" + }, + { + "名称": "走廊", + "朝向": "未知", + "面积估算": "12.31 m²", + "窗户": [ + { + "所在立面": "未知", + "类型": "无", + "数量": 0, + "推测大小": "无" + } + ], + "是否带阳台": "否", + "备注": "无" + }, + { + "名称": "阳台", + "朝向": "南", + "面积估算": "5.57 m²", + "窗户": [ + { + "所在立面": "南", + "类型": "无", + "数量": 0, + "推测大小": "无" + } + ], + "是否带阳台": "无", + "备注": "半开放区域" + } + ], + "立面对应表": { + "说明": "哪些房间的窗户落在哪个外立面,用于推导正投影立面", + "南立面": [ + "客厅", + "阳台" + ], + "北立面": [ + "主卧", + "次卧", + "卫生间", + "卫生间" + ] + }, + "识别备注": "符号清晰,所见各房间名称与朝向准确" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别评测/260620-215311_apiyi_gpt-4o-mini.meta.json b/ai-art-research/生成结果/户型图识别评测/260620-215311_apiyi_gpt-4o-mini.meta.json new file mode 100644 index 0000000..3368016 --- /dev/null +++ b/ai-art-research/生成结果/户型图识别评测/260620-215311_apiyi_gpt-4o-mini.meta.json @@ -0,0 +1,8 @@ +{ + "provider": "apiyi", + "model": "gpt-4o-mini", + "image": "E:\\MiceCola\\work\\ChildHood\\ai-art-research\\参考图\\真实场景\\户型图\\QQ20260618-213247.png", + "prompt": "你是一个专业的户型图解析助手。请仔细分析这张户型图,提取结构化信息。\n\n【户型图符号约定】\n- 墙体:粗实线或双线\n- 门:弧线(表示开门方向)\n- 窗:细的双平行线\n- 阳台:半开放区域,常带栏杆符号\n- 房间名:通常文字标注在房间内部(客厅/卧室/厨房/卫生间/阳台/餐厅/玄关等)\n- 面积:常以 m² 数字标注在房间内或户型角落\n\n【严格规则】\n1. 只描述图上实际可见、或可明确推断的结构。禁止用\"住宅常识\"脑补——\n 不要默认卧室有大窗、阳台是落地窗、北面是厨房。\n2. 看不清或不确定的字段,一律填 \"未知\",绝不瞎猜。\n3. 输出必须是纯 JSON,不要任何解释文字、不要用 ```json 代码块包裹、不要前后缀。\n\n【输出 JSON 结构】\n{\n \"整体朝向\": \"主采光面朝向,如 南/北/东南;看不清填 未知\",\n \"户型结构\": \"几室几厅几卫,如 三室两厅一卫\",\n \"总面积\": \"图上标注的建筑面积,如 约 95 m²;无标注填 未知\",\n \"房间\": [\n {\n \"名称\": \"客厅/主卧/次卧/厨房/卫生间/阳台/餐厅/玄关...\",\n \"朝向\": \"该房间主要采光朝向:南/北/东/西\",\n \"面积估算\": \"图上有标注则填,否则 未知\",\n \"窗户\": [\n {\"所在立面\": \"南/北/东/西\", \"类型\": \"落地窗/普通窗/飘窗/无\", \"数量\": 1, \"推测大小\": \"大/中/小/未知\"}\n ],\n \"是否带阳台\": \"是/否/未知\",\n \"备注\": \"其他可见特征,如 是否飘窗、是否暗卫(无窗)等\"\n }\n ],\n \"立面对应表\": {\n \"说明\": \"哪些房间的窗户落在哪个外立面,用于推导正投影立面\",\n \"南立面\": [\"客厅\", \"主卧\"],\n \"北立面\": [\"厨房\", \"卫生间\"]\n },\n \"识别备注\": \"图纸清晰度、符号可能误读之处、需要人工重点核对的项\"\n}\n\n现在请解析这张户型图,只输出 JSON。", + "parse_success": true, + "timestamp": "2026-06-20T21:53:11.318976" +} \ No newline at end of file diff --git a/ai-art-research/生成结果/户型图识别评测/评测对比.md b/ai-art-research/生成结果/户型图识别评测/评测对比.md new file mode 100644 index 0000000..bb6fa8a --- /dev/null +++ b/ai-art-research/生成结果/户型图识别评测/评测对比.md @@ -0,0 +1,73 @@ +# 户型图识别评测对比 + +- **测试图**:`参考图/真实场景/户型图/QQ20260618-213247.png`(链家风格彩色户型图) +- **测试时间**:2026-06-20 +- **Provider**:API易(复用现有 `APIYI_API_KEY`,零额外配置) +- **脚本**:`tools/floorplan_eval.py`(统一提取 prompt,要求输出结构化 JSON) + +--- + +## 一、四路结果总览 + +| 维度 | qwen-vl-max ⭐ | gpt-4o | qwen-vl-plus | gpt-4o-mini | +|---|---|---|---|---| +| 户型结构 | 四室两厅两卫 | 四室一厅两卫 | 三室两厅两卫 | 三室一厅两卫 | +| 识别房间数 | 11 | 10 | 8 | 7 | +| 整体朝向 | 南 | 南 | 南 | 南 | +| 总面积 | **未知(诚实)** | **未知(诚实)** | 约195.8㎡(疑似瞎猜) | 约95㎡(疑似瞎猜,光客厅就38㎡) | +| 单房间面积 OCR | ✅ 全房间精确 | ✅ 全房间精确 | ❌ 无 | ❌ 无 | +| 立面对应表 | ✅ 南/北 | ✅ 东南西北更全 | ✅ | ✅ | +| 识别备注详尽/诚实度 | ✅ 最详尽,主动标注"需人工核对"项 | 中(卫生间自相矛盾) | 中 | 弱 | +| 链家彩色图适应性 | ✅ 好 | ✅ 好 | 中 | 中 | +| JSON 输出稳定性 | ✅ 一次成型 | ✅ 一次成型 | ✅ | ✅ | + +--- + +## 二、两强一致项(高可信,基本无需核对) + +qwen-vl-max 与 gpt-4o 对**每个房间的面积数字完全一致** → 都准确 OCR 了图上标注,说明下面这个结构是可信的: + +> **4 卧室 + 2 卫生间 + 1 客厅(38.46㎡) + 1 走廊(12.31㎡) + 2 阳台** +> +> 面积明细:客厅 38.46 / 主卧 17.02 / 次卧 14.32 / 北卧 9.33 / 北卧 9.24 / 卫 4.93 / 卫 5.74 / 走廊 12.31 / 阳台 5.57 / 阳台 6.09 + +两个弱模型(plus/mini)房间数明显偏少、面积瞎猜 → **排除**。 + +--- + +## 三、关键分歧项(⚠️ 需对照原图核对,正是"脑补重灾区") + +| 分歧点 | qwen-vl-max | gpt-4o | 说明 | +|---|---|---|---| +| 客厅/餐厅 | 分成「客厅+餐厅」(共用 38.46㎡) | 只算「客厅」 | 同一区域是否算两厅 | +| **卫生间朝向** | 2 个都朝**南**、有窗 | 2 个朝**东**,且备注其一"暗卫"(自相矛盾:又说有窗又说暗卫) | **最需核对**:卫生间是否暗卫(无窗)?朝哪? | +| 阳台朝向 | 2 个皆**南** | 一**南**一**北** | 核对阳台朝向 | +| 窗户大小 | 北卧 9.33㎡→小 | 同房→中 | 主观判断分歧 | + +> 这里的分歧正好印证项目痛点:**窗户/朝向细节是 AI 最容易"用住宅常识脑补"的地方**。但 qwen-vl-max 主动在备注里标注了"部分窗户仅以细双线示意,未标注具体类型,需人工核对"——这种"知道自己不确定"的诚实性,对"AI 出清单 + 人工核对"模式非常有利。 + +--- + +## 四、初步推荐 + +**qwen-vl-max**: +- 房间识别最全(11 个,含餐厅/走廊/2 阳台) +- 单房间面积 OCR 精确,与 gpt-4o 完全吻合 +- 识别备注最详尽且诚实(主动标注不确定项) +- 对链家彩色图适应好,JSON 一次成型 +- 唯一短板:窗户类型/朝向细节仍可能脑补——但这正是"AI 出清单 + 人工核对"模式要解决的,且它主动标注了不确定项 + +> 注:当前仅测 1 张图,qwen-vl-max 的领先是初步结论。建议后续再用 2–3 张不同户型(小户型/一梯两户/带飘窗)验证稳定性。 + +--- + +## 五、六维度评分表(请对照原图填写,1–5 分) + +| 维度 | qwen-vl-max | gpt-4o | 备注 | +|---|---|---|---| +| 房间完整性 | | | 有无漏房间 | +| 房间属性准确性 | | | 名称/面积/朝向 | +| 窗户识别(重点) | | | 数量/类型/朝向 | +| 结构关系 | | | 动静分区/立面对应 | +| 链家彩色图适应性 | | | | +| 输出稳定性 | | | JSON 可解析 | diff --git a/docs/art/美术风格指南.md b/docs/art/美术风格指南.md index ef9b33c..35f31a5 100644 --- a/docs/art/美术风格指南.md +++ b/docs/art/美术风格指南.md @@ -104,6 +104,7 @@ - 适用:有户型图、需精确控制窗户对应房间;需由同一户型推导多个立面(南/北/山墙)供建模 - 优势:理论上限高,窗户由房间精确决定;同一户型可推出多立面,利于后续建模 - 劣势:AI 独立读户型图不可靠(会用住宅常识填补,如默认卧室大窗、阳台落地窗、漏房间),**需人工逐项校验窗户形态与比例**;稳定性待多户型验证 +- **读图辅助**(2026-06):户型图可先用 `floorplan-recognizer` 技能(qwen-vl-max)解析成「房间 + 朝向 + 各立面窗户形态」结构化清单,并生成「文字钉死」片段,将"逐项校验"降级为"出清单 + 快速核对"(重点核对卫生间朝向/暗卫、阳台朝向、窗户大小这三类脑补重灾区;房间数与面积经评测可信);用法见 `.claude/skills/floorplan-recognizer/SKILL.md`,评测见 `ai-art-research/生成结果/户型图识别评测/评测对比.md` **何时用哪条** - 有户型图、要精确控窗 / 要多立面 → 路径 B