MCPcopy Create free account
hub / github.com/917Dhj/DeepPaperNote / _classify_visual_quality

Function _classify_visual_quality

scripts/extract_pdf_assets.py:136–212  ·  view source on GitHub ↗

Classify whether a caption-matched crop is visually usable. This is intentionally conservative. A label/caption match proves identity, but not that the rendered crop contains the figure or table body.

(
    *,
    kind: str,
    page_coverage_ratio: float,
    visual_rect_count: int,
    visual_body_ratio: float,
    paragraph_text_chars: int,
    table_body_rows: int,
    caption_text_chars: int,
    other_caption_labels: list[str] | None = None,
)

Source from the content-addressed store, hash-verified

134
135
136def _classify_visual_quality(
137 *,
138 kind: str,
139 page_coverage_ratio: float,
140 visual_rect_count: int,
141 visual_body_ratio: float,
142 paragraph_text_chars: int,
143 table_body_rows: int,
144 caption_text_chars: int,
145 other_caption_labels: list[str] | None = None,
146) -> dict:
147 """Classify whether a caption-matched crop is visually usable.
148
149 This is intentionally conservative. A label/caption match proves identity,
150 but not that the rendered crop contains the figure or table body.
151 """
152 normalized_kind = kind.strip().lower()
153 other_caption_labels = list(other_caption_labels or [])
154 reasons: list[str] = []
155
156 if normalized_kind == "table":
157 text_per_table_row = paragraph_text_chars / max(1, table_body_rows)
158 if table_body_rows <= 0:
159 reasons.append("table_body_missing")
160 if table_body_rows <= 1 and visual_body_ratio < 0.03 and caption_text_chars >= 40:
161 reasons.append("caption_only_suspected")
162 # Dense tables naturally contain many text spans. Treat prose-like text
163 # as contamination when table structure is weak or the text density is
164 # far higher than the detected table body can explain.
165 if paragraph_text_chars >= 450 and (
166 table_body_rows <= 2
167 or (paragraph_text_chars >= 900 and visual_body_ratio <= 0.03 and text_per_table_row > 90)
168 or text_per_table_row > 140
169 ):
170 reasons.append("table_text_contamination_suspected")
171 if other_caption_labels:
172 reasons.append("multiple_caption_regions_suspected")
173 status = "reject" if reasons else "usable"
174 else:
175 if other_caption_labels:
176 reasons.append("multiple_caption_regions_suspected")
177 visual_dominant = visual_rect_count >= 3 and visual_body_ratio >= 0.18
178 if paragraph_text_chars >= 450 and not visual_dominant:
179 reasons.append("large_text_block_suspected")
180 if page_coverage_ratio >= 0.70 and paragraph_text_chars >= 250:
181 reasons.append("oversized_page_crop")
182 if visual_rect_count <= 1 and visual_body_ratio < 0.03:
183 reasons.append("low_visual_body_ratio")
184 if any(
185 code in reasons
186 for code in (
187 "multiple_caption_regions_suspected",
188 "large_text_block_suspected",
189 "oversized_page_crop",
190 "low_visual_body_ratio",
191 )
192 ):
193 status = "reject"

Calls

no outgoing calls