| from docling_core.types.doc import DocItemLabel |
| from PIL import Image, ImageDraw, ImageFont |
| from PIL.ImageFont import FreeTypeFont |
|
|
| from docling.datamodel.base_models import Cluster |
|
|
|
|
| def draw_clusters( |
| image: Image.Image, clusters: list[Cluster], scale_x: float, scale_y: float |
| ) -> None: |
| """ |
| Draw clusters on an image |
| """ |
| draw = ImageDraw.Draw(image, "RGBA") |
| |
| font: ImageFont.ImageFont | FreeTypeFont |
| try: |
| font = ImageFont.truetype("arial.ttf", 12) |
| except OSError: |
| |
| font = ImageFont.load_default() |
| for c_tl in clusters: |
| all_clusters = [c_tl, *c_tl.children] |
| for c in all_clusters: |
| |
| cell_color = (0, 0, 0, 40) |
| for tc in c.cells: |
| cx0, cy0, cx1, cy1 = tc.bbox.as_tuple() |
| cx0 *= scale_x |
| cx1 *= scale_x |
| cy0 *= scale_x |
| cy1 *= scale_y |
|
|
| draw.rectangle( |
| [(cx0, cy0), (cx1, cy1)], |
| outline=None, |
| fill=cell_color, |
| ) |
| |
| x0, y0, x1, y1 = c.bbox.as_tuple() |
| x0 *= scale_x |
| x1 *= scale_x |
| y0 *= scale_x |
| y1 *= scale_y |
|
|
| cluster_fill_color = (*list(DocItemLabel.get_color(c.label)), 70) |
| cluster_outline_color = ( |
| *list(DocItemLabel.get_color(c.label)), |
| 255, |
| ) |
| draw.rectangle( |
| [(x0, y0), (x1, y1)], |
| outline=cluster_outline_color, |
| fill=cluster_fill_color, |
| ) |
| |
| label_text = f"{c.label.name} ({c.confidence:.2f})" |
| |
| text_bbox = draw.textbbox((x0, y0), label_text, font=font) |
| text_bg_padding = 2 |
| draw.rectangle( |
| [ |
| ( |
| text_bbox[0] - text_bg_padding, |
| text_bbox[1] - text_bg_padding, |
| ), |
| ( |
| text_bbox[2] + text_bg_padding, |
| text_bbox[3] + text_bg_padding, |
| ), |
| ], |
| fill=(255, 255, 255, 180), |
| ) |
| |
| draw.text( |
| (x0, y0), |
| label_text, |
| fill=(0, 0, 0, 255), |
| font=font, |
| ) |
|
|