mirror of
https://github.com/lllin000/PaperForge.git
synced 2026-07-22 06:50:53 +00:00
fix: expand crop bbox to include figure_inner_text (figures show their own labels)
figure_inner_text role means the text IS part of the figure content (forest plot y-axis labels, nomogram variable names, panel markers). The earlier fix listed the text as a separate below the image — that was wrong: the text already lives inside the cropped image when the crop bbox covers it. Now extract_and_write_objects expands the crop bbox to include all figure_inner_text blocks owned by the figure (via _object_owner_id, same page). The cropped jpg contains the labels; render only emits image + Legend. Verified: M84CTEM9 figure_a001 (forest plot) now crops to 787x363 (previously 444x358 — missed the y-axis labels); figure_a002 (nomogram) still includes its variable labels. 105 focused tests pass.
This commit is contained in:
parent
34827f2af0
commit
c42da204bb
1 changed files with 37 additions and 23 deletions
|
|
@ -32,10 +32,6 @@ def render_figure_object_markdown(figure: dict[str, Any]) -> str:
|
|||
if caption:
|
||||
parts.append("## Legend")
|
||||
parts.append(normalize_ocr_math_text(caption))
|
||||
note_text = figure.get("note_text", "")
|
||||
if note_text:
|
||||
parts.append("")
|
||||
parts.append(note_text)
|
||||
if figure.get("page"):
|
||||
parts.append("")
|
||||
parts.append(f"*Page {figure['page']}*")
|
||||
|
|
@ -274,13 +270,47 @@ def extract_and_write_objects(
|
|||
|
||||
rotation_deg = int(match.get("rotation_correction_deg", 0) or 0)
|
||||
|
||||
# Build crop bbox: cluster_bbox, else union of matched_assets,
|
||||
# expanded to include owned figure_inner_text blocks (same page)
|
||||
crop_bbox = match.get("cluster_bbox") or [0, 0, 0, 0]
|
||||
if not (len(crop_bbox) == 4 and all(v > 0 for v in crop_bbox)):
|
||||
asset_bboxes = [
|
||||
a.get("bbox", [0, 0, 0, 0])
|
||||
for a in match.get("matched_assets", [])
|
||||
if len(a.get("bbox") or []) >= 4 and all(v > 0 for v in a.get("bbox", [0, 0, 0, 0]))
|
||||
]
|
||||
if asset_bboxes:
|
||||
crop_bbox = [
|
||||
min(b[0] for b in asset_bboxes),
|
||||
min(b[1] for b in asset_bboxes),
|
||||
max(b[2] for b in asset_bboxes),
|
||||
max(b[3] for b in asset_bboxes),
|
||||
]
|
||||
|
||||
if structured_blocks and len(crop_bbox) == 4 and all(v > 0 for v in crop_bbox):
|
||||
for blk in structured_blocks:
|
||||
if blk.get("role") != "figure_inner_text":
|
||||
continue
|
||||
if str(blk.get("_object_owner_id", "")) != str(fig_id):
|
||||
continue
|
||||
if int(blk.get("page", 0) or 0) != int(page or 0):
|
||||
continue
|
||||
bb = blk.get("bbox") or [0, 0, 0, 0]
|
||||
if len(bb) < 4 or not all(v > 0 for v in bb):
|
||||
continue
|
||||
crop_bbox = [
|
||||
min(crop_bbox[0], bb[0]),
|
||||
min(crop_bbox[1], bb[1]),
|
||||
max(crop_bbox[2], bb[2]),
|
||||
max(crop_bbox[3], bb[3]),
|
||||
]
|
||||
|
||||
was_cropped = False
|
||||
cluster_bbox = match.get("cluster_bbox")
|
||||
if cluster_bbox and all(v > 0 for v in cluster_bbox):
|
||||
if len(crop_bbox) == 4 and all(v > 0 for v in crop_bbox):
|
||||
was_cropped = _crop_asset_from_pdf(
|
||||
pdf_path,
|
||||
page,
|
||||
cluster_bbox,
|
||||
crop_bbox,
|
||||
asset_path_abs,
|
||||
page_width=page_width,
|
||||
page_height=page_height,
|
||||
|
|
@ -310,21 +340,6 @@ def extract_and_write_objects(
|
|||
was_cropped = True
|
||||
break
|
||||
|
||||
# Collect figure_inner_text blocks owned by this figure (side-adjacent + contained)
|
||||
note_text = ""
|
||||
if structured_blocks:
|
||||
note_lines = []
|
||||
for blk in structured_blocks:
|
||||
if blk.get("role") != "figure_inner_text":
|
||||
continue
|
||||
if str(blk.get("_object_owner_id", "")) != str(fig_id):
|
||||
continue
|
||||
t = str(blk.get("text", "")).strip()
|
||||
if t:
|
||||
note_lines.append(t)
|
||||
if note_lines:
|
||||
note_text = "\n".join(f"- {line}" for line in note_lines)
|
||||
|
||||
md = render_figure_object_markdown(
|
||||
{
|
||||
"figure_id": fig_id,
|
||||
|
|
@ -333,7 +348,6 @@ def extract_and_write_objects(
|
|||
"image_relpath": asset_path_rel,
|
||||
"confidence": match.get("confidence", 0.5),
|
||||
"was_cropped": was_cropped,
|
||||
"note_text": note_text,
|
||||
}
|
||||
)
|
||||
_write_object_markdown(md, figures_render_dir / f"{fig_id}.md")
|
||||
|
|
|
|||
Loading…
Reference in a new issue