第三阶段改进
This commit is contained in:
+21
-5
@@ -145,6 +145,9 @@ def merge_candidate(folder, candidate_file, output_file, size_policy='strict'):
|
||||
raise ValueError('Unknown candidate size policy')
|
||||
folder = Path(folder)
|
||||
task = read_json(folder/'task.json')
|
||||
if task.get('profile') == 'adaptive':
|
||||
from completion_planning import merge_adaptive
|
||||
return merge_adaptive(folder, candidate_file, output_file, size_policy)
|
||||
original = np.array(Image.open(folder/'visible.png').convert('RGBA'))
|
||||
allowed = np.array(Image.open(folder/'allowed-mask.png').convert('L')) > 0
|
||||
candidate = Image.open(candidate_file).convert('RGBA')
|
||||
@@ -228,6 +231,9 @@ def finalize(directory):
|
||||
meta = read_json(out/'tasks'/name/'task.json')
|
||||
ox, oy = meta['origin_xy']
|
||||
task.update(image=f'parts/{name}.png', crop_xyxy=[bbox[0]+ox, bbox[1]+oy, bbox[2]+ox, bbox[3]+oy])
|
||||
if meta.get('preservation'):
|
||||
task['preservation'] = meta['preservation']
|
||||
task['transform'] = meta['transform']
|
||||
view = f'<img src="{task["image"]}">' if task.get('image') else ''
|
||||
for index, item in enumerate(task.get('candidates', []), 1):
|
||||
view += f'<p><a href="{html.escape(item["file"], quote=True)}">原候选 {index}</a> · <a href="tasks/{name}/qa-{index}.json">QA</a>'
|
||||
@@ -235,11 +241,14 @@ def finalize(directory):
|
||||
view += f' · <a href="tasks/{name}/merged-{index}-normalized.png">缩放后候选</a>'
|
||||
view += '</p>'
|
||||
warnings = html.escape(', '.join(task.get('upstream_warnings', [])))
|
||||
rows.append(f'<tr><td>{html.escape(name)}<p>{warnings}</p><a href="tasks/{name}/task.json">任务参数</a> · <a href="tasks/{name}/prompt.txt">提示词</a></td><td>{html.escape(task["status"])}</td><td><a href="tasks/{name}/visible.png"><img src="tasks/{name}/visible.png"></a></td><td><a href="tasks/{name}/allowed-mask.png"><img src="tasks/{name}/allowed-mask.png"></a><p><a href="tasks/{name}/context.png">原图局部参考</a></p></td><td>{view}</td><td><pre>{html.escape(json.dumps(qa, ensure_ascii=False, indent=2))}</pre></td></tr>')
|
||||
reference = f'<p><a href="tasks/{name}/input.png">实际请求主图</a> · <a href="tasks/{name}/request-plan.json">发送计划</a></p>'
|
||||
if (out/'tasks'/name/'reference.png').exists():
|
||||
reference += f'<a href="tasks/{name}/reference.png">完整角色参考</a>'
|
||||
rows.append(f'<tr><td>{html.escape(name)}<p>{warnings}</p><a href="tasks/{name}/task.json">任务参数</a> · <a href="tasks/{name}/prompt.txt">提示词</a>{reference}</td><td>{html.escape(task["status"])}</td><td><a href="tasks/{name}/visible.png"><img src="tasks/{name}/visible.png"></a></td><td><a href="tasks/{name}/allowed-mask.png"><img src="tasks/{name}/allowed-mask.png"></a><p><a href="tasks/{name}/context.png">原图局部参考</a></p></td><td>{view}</td><td><pre>{html.escape(json.dumps(qa, ensure_ascii=False, indent=2))}</pre></td></tr>')
|
||||
write_json(out/'completion-result.json', result)
|
||||
(out/'report.html').write_text('''<!doctype html><html lang="zh-CN"><meta charset="utf-8"><title>部件补全</title>
|
||||
<style>body{font:16px system-ui;margin:24px}td,th{border:1px solid #ccc;padding:8px}img{max-width:260px;max-height:300px;background:#eee}pre{white-space:pre-wrap}table{border-collapse:collapse}</style>
|
||||
<h1>第三阶段:部件补全</h1><p>新增区域受允许掩码限制,原图可见像素逐像素恢复。几何通过仅表示候选可供复核,不代表遮挡和关节纹理已正确补全。上游 SAM 错分仍需修正。</p>
|
||||
<h1>第三阶段:部件补全</h1><p>输出受允许掩码限制,保留区域逐像素恢复;adaptive 允许明确规划的附件清理、替换和移除,原始 SAM 始终保留。几何通过仅表示候选可供复核,不代表遮挡和关节纹理已正确补全。</p>
|
||||
<table><tr><th>部件 / 上游告警</th><th>状态</th><th>原可见区域</th><th>允许新增区域(白色)</th><th>补全候选</th><th>几何检查</th></tr>'''+''.join(rows)+'</table><h2>跳过</h2><pre>'+html.escape(json.dumps(result['skipped'], ensure_ascii=False, indent=2))+'</pre></html>', encoding='utf-8')
|
||||
|
||||
|
||||
@@ -249,16 +258,23 @@ def main():
|
||||
parser.add_argument('--out', required=True)
|
||||
parser.add_argument('--part', action='append', default=[])
|
||||
parser.add_argument('--size', type=int, default=1024)
|
||||
parser.add_argument('--radius', type=int, default=32)
|
||||
parser.add_argument('--radius', type=int)
|
||||
parser.add_argument('--profile', choices=['legacy', 'adaptive'], default='legacy')
|
||||
parser.add_argument('--reference-mode', choices=['none', 'local', 'full', 'both', 'board'], default='board')
|
||||
parser.add_argument('--review-file')
|
||||
parser.add_argument('--candidate')
|
||||
parser.add_argument('--merged')
|
||||
parser.add_argument('--qa')
|
||||
parser.add_argument('--candidate-size-policy', choices=['strict', 'uniform'], default='strict')
|
||||
args = parser.parse_args()
|
||||
if args.action == 'prepare':
|
||||
if not 128 <= args.size <= 4096 or not 1 <= args.radius <= 256:
|
||||
if not 128 <= args.size <= 4096 or (args.radius is not None and not 1 <= args.radius <= 256):
|
||||
parser.error('size must be 128..4096 and radius 1..256')
|
||||
prepare(args.out, args.part, args.size, args.radius)
|
||||
if args.profile == 'adaptive':
|
||||
from completion_planning import prepare_adaptive
|
||||
prepare_adaptive(args.out, args.part, args.size, args.radius, args.reference_mode, args.review_file)
|
||||
else:
|
||||
prepare(args.out, args.part, args.size, args.radius or 32)
|
||||
elif args.action == 'merge':
|
||||
write_json(args.qa, merge_candidate(args.out, args.candidate, args.merged, args.candidate_size_policy))
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user