feat: New document picture classifier (#805)
* figure classifier Signed-off-by: Matteo Omenetti <omenetti.matteo@gmail.com> * gt for e2e tests Signed-off-by: Matteo Omenetti <omenetti.matteo@gmail.com> * tests Signed-off-by: Matteo Omenetti <omenetti.matteo@gmail.com> --------- Signed-off-by: Matteo Omenetti <omenetti.matteo@gmail.com>
This commit is contained in:
parent
88a0e66adc
commit
16a218d871
@ -221,6 +221,7 @@ class PdfPipelineOptions(PipelineOptions):
|
|||||||
do_ocr: bool = True # True: perform OCR, replace programmatic PDF text
|
do_ocr: bool = True # True: perform OCR, replace programmatic PDF text
|
||||||
do_code_enrichment: bool = False # True: perform code OCR
|
do_code_enrichment: bool = False # True: perform code OCR
|
||||||
do_formula_enrichment: bool = False # True: perform formula OCR, return Latex code
|
do_formula_enrichment: bool = False # True: perform formula OCR, return Latex code
|
||||||
|
do_picture_classification: bool = False # True: classify pictures in documents
|
||||||
|
|
||||||
table_structure_options: TableStructureOptions = TableStructureOptions()
|
table_structure_options: TableStructureOptions = TableStructureOptions()
|
||||||
ocr_options: Union[
|
ocr_options: Union[
|
||||||
|
187
docling/models/document_picture_classifier.py
Normal file
187
docling/models/document_picture_classifier.py
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
from typing import Iterable, List, Literal, Optional, Tuple, Union
|
||||||
|
|
||||||
|
from docling_core.types.doc import (
|
||||||
|
DoclingDocument,
|
||||||
|
NodeItem,
|
||||||
|
PictureClassificationClass,
|
||||||
|
PictureClassificationData,
|
||||||
|
PictureItem,
|
||||||
|
)
|
||||||
|
from PIL import Image
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from docling.datamodel.pipeline_options import AcceleratorOptions
|
||||||
|
from docling.models.base_model import BaseEnrichmentModel
|
||||||
|
from docling.utils.accelerator_utils import decide_device
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentPictureClassifierOptions(BaseModel):
|
||||||
|
"""
|
||||||
|
Options for configuring the DocumentPictureClassifier.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
kind : Literal["document_picture_classifier"]
|
||||||
|
Identifier for the type of classifier.
|
||||||
|
"""
|
||||||
|
|
||||||
|
kind: Literal["document_picture_classifier"] = "document_picture_classifier"
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentPictureClassifier(BaseEnrichmentModel):
|
||||||
|
"""
|
||||||
|
A model for classifying pictures in documents.
|
||||||
|
|
||||||
|
This class enriches document pictures with predicted classifications
|
||||||
|
based on a predefined set of classes.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
enabled : bool
|
||||||
|
Whether the classifier is enabled for use.
|
||||||
|
options : DocumentPictureClassifierOptions
|
||||||
|
Configuration options for the classifier.
|
||||||
|
document_picture_classifier : DocumentPictureClassifierPredictor
|
||||||
|
The underlying prediction model, loaded if the classifier is enabled.
|
||||||
|
|
||||||
|
Methods
|
||||||
|
-------
|
||||||
|
__init__(enabled, artifacts_path, options, accelerator_options)
|
||||||
|
Initializes the classifier with specified configurations.
|
||||||
|
is_processable(doc, element)
|
||||||
|
Checks if the given element can be processed by the classifier.
|
||||||
|
__call__(doc, element_batch)
|
||||||
|
Processes a batch of elements and adds classification annotations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
images_scale = 2
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
enabled: bool,
|
||||||
|
artifacts_path: Optional[Union[Path, str]],
|
||||||
|
options: DocumentPictureClassifierOptions,
|
||||||
|
accelerator_options: AcceleratorOptions,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Initializes the DocumentPictureClassifier.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
enabled : bool
|
||||||
|
Indicates whether the classifier is enabled.
|
||||||
|
artifacts_path : Optional[Union[Path, str]],
|
||||||
|
Path to the directory containing model artifacts.
|
||||||
|
options : DocumentPictureClassifierOptions
|
||||||
|
Configuration options for the classifier.
|
||||||
|
accelerator_options : AcceleratorOptions
|
||||||
|
Options for configuring the device and parallelism.
|
||||||
|
"""
|
||||||
|
self.enabled = enabled
|
||||||
|
self.options = options
|
||||||
|
|
||||||
|
if self.enabled:
|
||||||
|
device = decide_device(accelerator_options.device)
|
||||||
|
from docling_ibm_models.document_figure_classifier_model.document_figure_classifier_predictor import (
|
||||||
|
DocumentFigureClassifierPredictor,
|
||||||
|
)
|
||||||
|
|
||||||
|
if artifacts_path is None:
|
||||||
|
artifacts_path = self.download_models_hf()
|
||||||
|
else:
|
||||||
|
artifacts_path = Path(artifacts_path)
|
||||||
|
|
||||||
|
self.document_picture_classifier = DocumentFigureClassifierPredictor(
|
||||||
|
artifacts_path=artifacts_path,
|
||||||
|
device=device,
|
||||||
|
num_threads=accelerator_options.num_threads,
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def download_models_hf(
|
||||||
|
local_dir: Optional[Path] = None, force: bool = False
|
||||||
|
) -> Path:
|
||||||
|
from huggingface_hub import snapshot_download
|
||||||
|
from huggingface_hub.utils import disable_progress_bars
|
||||||
|
|
||||||
|
disable_progress_bars()
|
||||||
|
download_path = snapshot_download(
|
||||||
|
repo_id="ds4sd/DocumentFigureClassifier",
|
||||||
|
force_download=force,
|
||||||
|
local_dir=local_dir,
|
||||||
|
revision="v1.0.0",
|
||||||
|
)
|
||||||
|
|
||||||
|
return Path(download_path)
|
||||||
|
|
||||||
|
def is_processable(self, doc: DoclingDocument, element: NodeItem) -> bool:
|
||||||
|
"""
|
||||||
|
Determines if the given element can be processed by the classifier.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
doc : DoclingDocument
|
||||||
|
The document containing the element.
|
||||||
|
element : NodeItem
|
||||||
|
The element to be checked.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
bool
|
||||||
|
True if the element is a PictureItem and processing is enabled; False otherwise.
|
||||||
|
"""
|
||||||
|
return self.enabled and isinstance(element, PictureItem)
|
||||||
|
|
||||||
|
def __call__(
|
||||||
|
self,
|
||||||
|
doc: DoclingDocument,
|
||||||
|
element_batch: Iterable[NodeItem],
|
||||||
|
) -> Iterable[NodeItem]:
|
||||||
|
"""
|
||||||
|
Processes a batch of elements and enriches them with classification predictions.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
doc : DoclingDocument
|
||||||
|
The document containing the elements to be processed.
|
||||||
|
element_batch : Iterable[NodeItem]
|
||||||
|
A batch of pictures to classify.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Iterable[NodeItem]
|
||||||
|
An iterable of NodeItem objects after processing. The field
|
||||||
|
'data.classification' is added containing the classification for each picture.
|
||||||
|
"""
|
||||||
|
if not self.enabled:
|
||||||
|
for element in element_batch:
|
||||||
|
yield element
|
||||||
|
return
|
||||||
|
|
||||||
|
images: List[Image.Image] = []
|
||||||
|
elements: List[PictureItem] = []
|
||||||
|
for el in element_batch:
|
||||||
|
assert isinstance(el, PictureItem)
|
||||||
|
elements.append(el)
|
||||||
|
img = el.get_image(doc)
|
||||||
|
assert img is not None
|
||||||
|
images.append(img)
|
||||||
|
|
||||||
|
outputs = self.document_picture_classifier.predict(images)
|
||||||
|
|
||||||
|
for element, output in zip(elements, outputs):
|
||||||
|
element.annotations.append(
|
||||||
|
PictureClassificationData(
|
||||||
|
provenance="DocumentPictureClassifier",
|
||||||
|
predicted_classes=[
|
||||||
|
PictureClassificationClass(
|
||||||
|
class_name=pred[0],
|
||||||
|
confidence=pred[1],
|
||||||
|
)
|
||||||
|
for pred in output
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
yield element
|
@ -19,6 +19,10 @@ from docling.datamodel.pipeline_options import (
|
|||||||
)
|
)
|
||||||
from docling.models.base_ocr_model import BaseOcrModel
|
from docling.models.base_ocr_model import BaseOcrModel
|
||||||
from docling.models.code_formula_model import CodeFormulaModel, CodeFormulaModelOptions
|
from docling.models.code_formula_model import CodeFormulaModel, CodeFormulaModelOptions
|
||||||
|
from docling.models.document_picture_classifier import (
|
||||||
|
DocumentPictureClassifier,
|
||||||
|
DocumentPictureClassifierOptions,
|
||||||
|
)
|
||||||
from docling.models.ds_glm_model import GlmModel, GlmOptions
|
from docling.models.ds_glm_model import GlmModel, GlmOptions
|
||||||
from docling.models.easyocr_model import EasyOcrModel
|
from docling.models.easyocr_model import EasyOcrModel
|
||||||
from docling.models.layout_model import LayoutModel
|
from docling.models.layout_model import LayoutModel
|
||||||
@ -104,6 +108,13 @@ class StandardPdfPipeline(PaginatedPipeline):
|
|||||||
),
|
),
|
||||||
accelerator_options=pipeline_options.accelerator_options,
|
accelerator_options=pipeline_options.accelerator_options,
|
||||||
),
|
),
|
||||||
|
# Document Picture Classifier
|
||||||
|
DocumentPictureClassifier(
|
||||||
|
enabled=pipeline_options.do_picture_classification,
|
||||||
|
artifacts_path=pipeline_options.artifacts_path,
|
||||||
|
options=DocumentPictureClassifierOptions(),
|
||||||
|
accelerator_options=pipeline_options.accelerator_options,
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
40
poetry.lock
generated
40
poetry.lock
generated
@ -888,13 +888,13 @@ chunking = ["semchunk (>=2.2.0,<3.0.0)", "transformers (>=4.34.0,<5.0.0)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "docling-ibm-models"
|
name = "docling-ibm-models"
|
||||||
version = "3.2.1"
|
version = "3.3.0"
|
||||||
description = "This package contains the AI models used by the Docling PDF conversion package"
|
description = "This package contains the AI models used by the Docling PDF conversion package"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "<4.0,>=3.9"
|
python-versions = "<4.0,>=3.9"
|
||||||
files = [
|
files = [
|
||||||
{file = "docling_ibm_models-3.2.1-py3-none-any.whl", hash = "sha256:55bca5673381cc5862f4de584345020d071414c46bc1b9f6436d674e3610ec97"},
|
{file = "docling_ibm_models-3.3.0-py3-none-any.whl", hash = "sha256:f1c99d345cb524239c7a2090969920e4311fd2fe22dad9bd609bc38039ec56eb"},
|
||||||
{file = "docling_ibm_models-3.2.1.tar.gz", hash = "sha256:abd1bdc58f00600065eedbfbd34876704d5004cd20884a2c0a61ca2ee5a927dd"},
|
{file = "docling_ibm_models-3.3.0.tar.gz", hash = "sha256:5a7497053871179d59870c830945aa8664a34aac48b7e68edf602720ee7f6c49"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@ -1046,13 +1046,13 @@ testing = ["hatch", "pre-commit", "pytest", "tox"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "executing"
|
name = "executing"
|
||||||
version = "2.1.0"
|
version = "2.2.0"
|
||||||
description = "Get the currently executing AST node of a frame, and other information"
|
description = "Get the currently executing AST node of a frame, and other information"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf"},
|
{file = "executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa"},
|
||||||
{file = "executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab"},
|
{file = "executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@ -3674,14 +3674,14 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nvidia-nvjitlink-cu12"
|
name = "nvidia-nvjitlink-cu12"
|
||||||
version = "12.6.85"
|
version = "12.8.61"
|
||||||
description = "Nvidia JIT LTO Library"
|
description = "Nvidia JIT LTO Library"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3"
|
python-versions = ">=3"
|
||||||
files = [
|
files = [
|
||||||
{file = "nvidia_nvjitlink_cu12-12.6.85-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:eedc36df9e88b682efe4309aa16b5b4e78c2407eac59e8c10a6a47535164369a"},
|
{file = "nvidia_nvjitlink_cu12-12.8.61-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:45fd79f2ae20bd67e8bc411055939049873bfd8fac70ff13bd4865e0b9bdab17"},
|
||||||
{file = "nvidia_nvjitlink_cu12-12.6.85-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cf4eaa7d4b6b543ffd69d6abfb11efdeb2db48270d94dfd3a452c24150829e41"},
|
{file = "nvidia_nvjitlink_cu12-12.8.61-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9b80ecab31085dda3ce3b41d043be0ec739216c3fc633b8abe212d5a30026df0"},
|
||||||
{file = "nvidia_nvjitlink_cu12-12.6.85-py3-none-win_amd64.whl", hash = "sha256:e61120e52ed675747825cdd16febc6a0730537451d867ee58bee3853b1b13d1c"},
|
{file = "nvidia_nvjitlink_cu12-12.8.61-py3-none-win_amd64.whl", hash = "sha256:1166a964d25fdc0eae497574d38824305195a5283324a21ccb0ce0c802cbf41c"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4612,13 +4612,13 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pydantic"
|
name = "pydantic"
|
||||||
version = "2.10.5"
|
version = "2.10.6"
|
||||||
description = "Data validation using Python type hints"
|
description = "Data validation using Python type hints"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53"},
|
{file = "pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584"},
|
||||||
{file = "pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff"},
|
{file = "pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@ -6124,13 +6124,13 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sentence-transformers"
|
name = "sentence-transformers"
|
||||||
version = "3.3.1"
|
version = "3.4.0"
|
||||||
description = "State-of-the-Art Text Embeddings"
|
description = "State-of-the-Art Text Embeddings"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
files = [
|
files = [
|
||||||
{file = "sentence_transformers-3.3.1-py3-none-any.whl", hash = "sha256:abffcc79dab37b7d18d21a26d5914223dd42239cfe18cb5e111c66c54b658ae7"},
|
{file = "sentence_transformers-3.4.0-py3-none-any.whl", hash = "sha256:f7d4ad81260149172a98108a3481d8e82c11d31f40d41885f43d481149237743"},
|
||||||
{file = "sentence_transformers-3.3.1.tar.gz", hash = "sha256:9635dbfb11c6b01d036b9cfcee29f7716ab64cf2407ad9f403a2e607da2ac48b"},
|
{file = "sentence_transformers-3.4.0.tar.gz", hash = "sha256:334288062d4b888cdd7b75913fead46b1e42bfe836f8343d23478d17f799e650"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@ -7487,13 +7487,13 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xlsxwriter"
|
name = "xlsxwriter"
|
||||||
version = "3.2.0"
|
version = "3.2.1"
|
||||||
description = "A Python module for creating Excel XLSX files."
|
description = "A Python module for creating Excel XLSX files."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
files = [
|
files = [
|
||||||
{file = "XlsxWriter-3.2.0-py3-none-any.whl", hash = "sha256:ecfd5405b3e0e228219bcaf24c2ca0915e012ca9464a14048021d21a995d490e"},
|
{file = "XlsxWriter-3.2.1-py3-none-any.whl", hash = "sha256:7e8f7c60b7a1660ef791d46ab5de78469cb978b991ca841af61f5832d2f9f4fe"},
|
||||||
{file = "XlsxWriter-3.2.0.tar.gz", hash = "sha256:9977d0c661a72866a61f9f7a809e25ebbb0fb7036baa3b9fe74afcfca6b3cb8c"},
|
{file = "XlsxWriter-3.2.1.tar.gz", hash = "sha256:97618759cb264fb6a93397f660cca156ffa9561743b1823dafb60dc4474e1902"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -7751,4 +7751,4 @@ tesserocr = ["tesserocr"]
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.9"
|
python-versions = "^3.9"
|
||||||
content-hash = "8bb0b67294a50c0340c5cc02ce60d3608ef4d1968ae50f7e0b8b4c8a26c34734"
|
content-hash = "7fcfc061454f229745d6f305e1fa593468a684059717195c6ae4174bec13d362"
|
||||||
|
@ -27,7 +27,7 @@ packages = [{include = "docling"}]
|
|||||||
python = "^3.9"
|
python = "^3.9"
|
||||||
pydantic = "^2.0.0"
|
pydantic = "^2.0.0"
|
||||||
docling-core = { version = "^2.15.1", extras = ["chunking"] }
|
docling-core = { version = "^2.15.1", extras = ["chunking"] }
|
||||||
docling-ibm-models = "^3.2.1"
|
docling-ibm-models = "^3.3.0"
|
||||||
deepsearch-glm = "^1.0.0"
|
deepsearch-glm = "^1.0.0"
|
||||||
docling-parse = "^3.1.0"
|
docling-parse = "^3.1.0"
|
||||||
filetype = "^1.2.0"
|
filetype = "^1.2.0"
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
<document>
|
||||||
|
<subtitle-level-1><location><page_1><loc_22><loc_83><loc_41><loc_84></location>Figures Example</subtitle-level-1>
|
||||||
|
<paragraph><location><page_1><loc_22><loc_63><loc_78><loc_81></location>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</paragraph>
|
||||||
|
<caption><location><page_1><loc_37><loc_32><loc_63><loc_33></location>Figure 1: This is an example image.</caption>
|
||||||
|
<figure>
|
||||||
|
<location><page_1><loc_22><loc_36><loc_78><loc_62></location>
|
||||||
|
<caption>Figure 1: This is an example image.</caption>
|
||||||
|
</figure>
|
||||||
|
<paragraph><location><page_1><loc_22><loc_15><loc_78><loc_30></location>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</paragraph>
|
||||||
|
<paragraph><location><page_2><loc_22><loc_66><loc_78><loc_84></location>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</paragraph>
|
||||||
|
<caption><location><page_2><loc_37><loc_33><loc_63><loc_34></location>Figure 2: This is an example image.</caption>
|
||||||
|
<figure>
|
||||||
|
<location><page_2><loc_36><loc_36><loc_64><loc_65></location>
|
||||||
|
<caption>Figure 2: This is an example image.</caption>
|
||||||
|
</figure>
|
||||||
|
<paragraph><location><page_2><loc_22><loc_15><loc_78><loc_31></location>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.</paragraph>
|
||||||
|
</document>
|
File diff suppressed because one or more lines are too long
15
tests/data/groundtruth/docling_v1/picture_classification.md
Normal file
15
tests/data/groundtruth/docling_v1/picture_classification.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
## Figures Example
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||||
|
|
||||||
|
Figure 1: This is an example image.
|
||||||
|
<!-- image -->
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||||
|
|
||||||
|
Figure 2: This is an example image.
|
||||||
|
<!-- image -->
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,15 @@
|
|||||||
|
<document>
|
||||||
|
<section_header_level_1><location><page_1><loc_22><loc_83><loc_41><loc_84></location>Figures Example</section_header_level_1>
|
||||||
|
<text><location><page_1><loc_22><loc_63><loc_78><loc_81></location>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</text>
|
||||||
|
<figure>
|
||||||
|
<location><page_1><loc_22><loc_36><loc_78><loc_62></location>
|
||||||
|
<caption>Figure 1: This is an example image.</caption>
|
||||||
|
</figure>
|
||||||
|
<text><location><page_1><loc_22><loc_15><loc_78><loc_30></location>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</text>
|
||||||
|
<text><location><page_2><loc_22><loc_66><loc_78><loc_84></location>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</text>
|
||||||
|
<figure>
|
||||||
|
<location><page_2><loc_36><loc_36><loc_64><loc_65></location>
|
||||||
|
<caption>Figure 2: This is an example image.</caption>
|
||||||
|
</figure>
|
||||||
|
<text><location><page_2><loc_22><loc_15><loc_78><loc_31></location>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.</text>
|
||||||
|
</document>
|
File diff suppressed because one or more lines are too long
17
tests/data/groundtruth/docling_v2/picture_classification.md
Normal file
17
tests/data/groundtruth/docling_v2/picture_classification.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
## Figures Example
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||||
|
|
||||||
|
Figure 1: This is an example image.
|
||||||
|
|
||||||
|
<!-- image -->
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||||
|
|
||||||
|
Figure 2: This is an example image.
|
||||||
|
|
||||||
|
<!-- image -->
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
|
File diff suppressed because one or more lines are too long
BIN
tests/data/picture_classification.pdf
Normal file
BIN
tests/data/picture_classification.pdf
Normal file
Binary file not shown.
81
tests/test_document_picture_classifier.py
Normal file
81
tests/test_document_picture_classifier.py
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from docling_core.types.doc import PictureClassificationData
|
||||||
|
|
||||||
|
from docling.backend.docling_parse_v2_backend import DoclingParseV2DocumentBackend
|
||||||
|
from docling.datamodel.base_models import InputFormat
|
||||||
|
from docling.datamodel.document import ConversionResult
|
||||||
|
from docling.datamodel.pipeline_options import PdfPipelineOptions
|
||||||
|
from docling.document_converter import DocumentConverter, PdfFormatOption
|
||||||
|
from docling.pipeline.standard_pdf_pipeline import StandardPdfPipeline
|
||||||
|
|
||||||
|
|
||||||
|
def get_converter():
|
||||||
|
|
||||||
|
pipeline_options = PdfPipelineOptions()
|
||||||
|
pipeline_options.generate_page_images = True
|
||||||
|
|
||||||
|
pipeline_options.do_ocr = False
|
||||||
|
pipeline_options.do_table_structure = False
|
||||||
|
pipeline_options.do_code_enrichment = False
|
||||||
|
pipeline_options.do_formula_enrichment = False
|
||||||
|
pipeline_options.do_picture_classification = True
|
||||||
|
pipeline_options.generate_picture_images = True
|
||||||
|
pipeline_options.images_scale = 2
|
||||||
|
|
||||||
|
converter = DocumentConverter(
|
||||||
|
format_options={
|
||||||
|
InputFormat.PDF: PdfFormatOption(
|
||||||
|
backend=DoclingParseV2DocumentBackend,
|
||||||
|
pipeline_cls=StandardPdfPipeline,
|
||||||
|
pipeline_options=pipeline_options,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return converter
|
||||||
|
|
||||||
|
|
||||||
|
def test_picture_classifier():
|
||||||
|
pdf_path = Path("tests/data/picture_classification.pdf")
|
||||||
|
converter = get_converter()
|
||||||
|
|
||||||
|
print(f"converting {pdf_path}")
|
||||||
|
|
||||||
|
doc_result: ConversionResult = converter.convert(pdf_path)
|
||||||
|
|
||||||
|
results = doc_result.document.pictures
|
||||||
|
|
||||||
|
assert len(results) == 2
|
||||||
|
|
||||||
|
res = results[0]
|
||||||
|
assert len(res.annotations) == 1
|
||||||
|
assert type(res.annotations[0]) == PictureClassificationData
|
||||||
|
classification_data = res.annotations[0]
|
||||||
|
assert classification_data.provenance == "DocumentPictureClassifier"
|
||||||
|
assert (
|
||||||
|
len(classification_data.predicted_classes) == 16
|
||||||
|
), "Number of predicted classes is not equal to 16"
|
||||||
|
confidences = [pred.confidence for pred in classification_data.predicted_classes]
|
||||||
|
assert confidences == sorted(
|
||||||
|
confidences, reverse=True
|
||||||
|
), "Predictions are not sorted in descending order of confidence"
|
||||||
|
assert (
|
||||||
|
classification_data.predicted_classes[0].class_name == "bar_chart"
|
||||||
|
), "The prediction is wrong for the bar chart image."
|
||||||
|
|
||||||
|
res = results[1]
|
||||||
|
assert len(res.annotations) == 1
|
||||||
|
assert type(res.annotations[0]) == PictureClassificationData
|
||||||
|
classification_data = res.annotations[0]
|
||||||
|
assert classification_data.provenance == "DocumentPictureClassifier"
|
||||||
|
assert (
|
||||||
|
len(classification_data.predicted_classes) == 16
|
||||||
|
), "Number of predicted classes is not equal to 16"
|
||||||
|
confidences = [pred.confidence for pred in classification_data.predicted_classes]
|
||||||
|
assert confidences == sorted(
|
||||||
|
confidences, reverse=True
|
||||||
|
), "Predictions are not sorted in descending order of confidence"
|
||||||
|
assert (
|
||||||
|
classification_data.predicted_classes[0].class_name == "map"
|
||||||
|
), "The prediction is wrong for the bar chart image."
|
Loading…
Reference in New Issue
Block a user