| | from abc import ABC, abstractmethod |
| | from typing import Any, Generic, Iterable, Optional |
| |
|
| | from docling_core.types.doc import BoundingBox, DocItem, DoclingDocument, NodeItem |
| | from typing_extensions import TypeVar |
| |
|
| | from docling.datamodel.base_models import ItemAndImageEnrichmentElement, Page |
| | from docling.datamodel.document import ConversionResult |
| | from docling.datamodel.settings import settings |
| |
|
| |
|
| | class BasePageModel(ABC): |
| | @abstractmethod |
| | def __call__( |
| | self, conv_res: ConversionResult, page_batch: Iterable[Page] |
| | ) -> Iterable[Page]: |
| | pass |
| |
|
| |
|
| | EnrichElementT = TypeVar("EnrichElementT", default=NodeItem) |
| |
|
| |
|
| | class GenericEnrichmentModel(ABC, Generic[EnrichElementT]): |
| |
|
| | elements_batch_size: int = settings.perf.elements_batch_size |
| |
|
| | @abstractmethod |
| | def is_processable(self, doc: DoclingDocument, element: NodeItem) -> bool: |
| | pass |
| |
|
| | @abstractmethod |
| | def prepare_element( |
| | self, conv_res: ConversionResult, element: NodeItem |
| | ) -> Optional[EnrichElementT]: |
| | pass |
| |
|
| | @abstractmethod |
| | def __call__( |
| | self, doc: DoclingDocument, element_batch: Iterable[EnrichElementT] |
| | ) -> Iterable[NodeItem]: |
| | pass |
| |
|
| |
|
| | class BaseEnrichmentModel(GenericEnrichmentModel[NodeItem]): |
| |
|
| | def prepare_element( |
| | self, conv_res: ConversionResult, element: NodeItem |
| | ) -> Optional[NodeItem]: |
| | if self.is_processable(doc=conv_res.document, element=element): |
| | return element |
| | return None |
| |
|
| |
|
| | class BaseItemAndImageEnrichmentModel( |
| | GenericEnrichmentModel[ItemAndImageEnrichmentElement] |
| | ): |
| |
|
| | images_scale: float |
| | expansion_factor: float = 0.0 |
| |
|
| | def prepare_element( |
| | self, conv_res: ConversionResult, element: NodeItem |
| | ) -> Optional[ItemAndImageEnrichmentElement]: |
| | if not self.is_processable(doc=conv_res.document, element=element): |
| | return None |
| |
|
| | assert isinstance(element, DocItem) |
| | element_prov = element.prov[0] |
| |
|
| | bbox = element_prov.bbox |
| | width = bbox.r - bbox.l |
| | height = bbox.t - bbox.b |
| |
|
| | |
| | expanded_bbox = BoundingBox( |
| | l=bbox.l - width * self.expansion_factor, |
| | t=bbox.t + height * self.expansion_factor, |
| | r=bbox.r + width * self.expansion_factor, |
| | b=bbox.b - height * self.expansion_factor, |
| | coord_origin=bbox.coord_origin, |
| | ) |
| |
|
| | page_ix = element_prov.page_no - 1 |
| | cropped_image = conv_res.pages[page_ix].get_image( |
| | scale=self.images_scale, cropbox=expanded_bbox |
| | ) |
| | return ItemAndImageEnrichmentElement(item=element, image=cropped_image) |
| |
|