diff --git a/tests/data/webp/20250422-155738.webp b/tests/data/webp/20250422-155738.webp deleted file mode 100644 index 29cded51..00000000 Binary files a/tests/data/webp/20250422-155738.webp and /dev/null differ diff --git a/tests/data/webp/groundtruth/docling_v2/test.doctags.txt b/tests/data/webp/groundtruth/docling_v2/test.doctags.txt new file mode 100644 index 00000000..99ea5520 --- /dev/null +++ b/tests/data/webp/groundtruth/docling_v2/test.doctags.txt @@ -0,0 +1,2 @@ +Docling bundles PDF document conversion to JSON and Markdown in an easy self contained package + \ No newline at end of file diff --git a/tests/data/webp/groundtruth/docling_v2/test.json b/tests/data/webp/groundtruth/docling_v2/test.json new file mode 100644 index 00000000..789cc58d --- /dev/null +++ b/tests/data/webp/groundtruth/docling_v2/test.json @@ -0,0 +1 @@ +{"schema_name": "DoclingDocument", "version": "1.3.0", "name": "ocr_test", "origin": {"mimetype": "application/pdf", "binary_hash": 14853448746796404529, "filename": "ocr_test.pdf", "uri": null}, "furniture": {"self_ref": "#/furniture", "parent": null, "children": [], "content_layer": "furniture", "name": "_root_", "label": "unspecified"}, "body": {"self_ref": "#/body", "parent": null, "children": [{"cref": "#/texts/0"}], "content_layer": "body", "name": "_root_", "label": "unspecified"}, "groups": [], "texts": [{"self_ref": "#/texts/0", "parent": {"cref": "#/body"}, "children": [], "content_layer": "body", "label": "text", "prov": [{"page_no": 1, "bbox": {"l": 69.0, "t": 767.2550252278646, "r": 506.6666666666667, "b": 688.5883585611979, "coord_origin": "BOTTOMLEFT"}, "charspan": [0, 94]}], "orig": "Docling bundles PDF document conversion to JSON and Markdown in an easy self contained package", "text": "Docling bundles PDF document conversion to JSON and Markdown in an easy self contained package", "formatting": null, "hyperlink": null}], "pictures": [], "tables": [], "key_value_items": [], "form_items": [], "pages": {"1": {"size": {"width": 595.201171875, "height": 841.9216918945312}, "image": null, "page_no": 1}}} \ No newline at end of file diff --git a/tests/data/webp/groundtruth/docling_v2/test.md b/tests/data/webp/groundtruth/docling_v2/test.md new file mode 100644 index 00000000..42896546 --- /dev/null +++ b/tests/data/webp/groundtruth/docling_v2/test.md @@ -0,0 +1 @@ +Docling bundles PDF document conversion to JSON and Markdown in an easy self contained package \ No newline at end of file diff --git a/tests/data/webp/groundtruth/docling_v2/test.pages.json b/tests/data/webp/groundtruth/docling_v2/test.pages.json new file mode 100644 index 00000000..60fc6991 --- /dev/null +++ b/tests/data/webp/groundtruth/docling_v2/test.pages.json @@ -0,0 +1 @@ +[{"page_no": 0, "size": {"width": 595.201171875, "height": 841.9216918945312}, "cells": [{"index": 0, "rgba": {"r": 0, "g": 0, "b": 0, "a": 255}, "rect": {"r_x0": 71.33333333333333, "r_y0": 99.33333333333333, "r_x1": 506.6666666666667, "r_y1": 99.33333333333333, "r_x2": 506.6666666666667, "r_y2": 74.66666666666667, "r_x3": 71.33333333333333, "r_y3": 74.66666666666667, "coord_origin": "TOPLEFT"}, "text": "Docling bundles PDF document conversion to", "orig": "Docling bundles PDF document conversion to", "text_direction": "left_to_right", "confidence": 0.9555703127793324, "from_ocr": true}, {"index": 1, "rgba": {"r": 0, "g": 0, "b": 0, "a": 255}, "rect": {"r_x0": 69.0, "r_y0": 126.66666666666667, "r_x1": 506.6666666666667, "r_y1": 126.66666666666667, "r_x2": 506.6666666666667, "r_y2": 100.66666666666667, "r_x3": 69.0, "r_y3": 100.66666666666667, "coord_origin": "TOPLEFT"}, "text": "JSON and Markdown in an easy self contained", "orig": "JSON and Markdown in an easy self contained", "text_direction": "left_to_right", "confidence": 0.9741098171752292, "from_ocr": true}, {"index": 2, "rgba": {"r": 0, "g": 0, "b": 0, "a": 255}, "rect": {"r_x0": 70.66666666666667, "r_y0": 153.33333333333334, "r_x1": 154.0, "r_y1": 153.33333333333334, "r_x2": 154.0, "r_y2": 128.66666666666666, "r_x3": 70.66666666666667, "r_y3": 128.66666666666666, "coord_origin": "TOPLEFT"}, "text": "package", "orig": "package", "text_direction": "left_to_right", "confidence": 0.6702765056141881, "from_ocr": true}], "parsed_page": null, "predictions": {"layout": {"clusters": [{"id": 0, "label": "text", "bbox": {"l": 69.0, "t": 74.66666666666667, "r": 506.6666666666667, "b": 153.33333333333334, "coord_origin": "TOPLEFT"}, "confidence": 0.9715733528137207, "cells": [{"index": 0, "rgba": {"r": 0, "g": 0, "b": 0, "a": 255}, "rect": {"r_x0": 71.33333333333333, "r_y0": 99.33333333333333, "r_x1": 506.6666666666667, "r_y1": 99.33333333333333, "r_x2": 506.6666666666667, "r_y2": 74.66666666666667, "r_x3": 71.33333333333333, "r_y3": 74.66666666666667, "coord_origin": "TOPLEFT"}, "text": "Docling bundles PDF document conversion to", "orig": "Docling bundles PDF document conversion to", "text_direction": "left_to_right", "confidence": 0.9555703127793324, "from_ocr": true}, {"index": 1, "rgba": {"r": 0, "g": 0, "b": 0, "a": 255}, "rect": {"r_x0": 69.0, "r_y0": 126.66666666666667, "r_x1": 506.6666666666667, "r_y1": 126.66666666666667, "r_x2": 506.6666666666667, "r_y2": 100.66666666666667, "r_x3": 69.0, "r_y3": 100.66666666666667, "coord_origin": "TOPLEFT"}, "text": "JSON and Markdown in an easy self contained", "orig": "JSON and Markdown in an easy self contained", "text_direction": "left_to_right", "confidence": 0.9741098171752292, "from_ocr": true}, {"index": 2, "rgba": {"r": 0, "g": 0, "b": 0, "a": 255}, "rect": {"r_x0": 70.66666666666667, "r_y0": 153.33333333333334, "r_x1": 154.0, "r_y1": 153.33333333333334, "r_x2": 154.0, "r_y2": 128.66666666666666, "r_x3": 70.66666666666667, "r_y3": 128.66666666666666, "coord_origin": "TOPLEFT"}, "text": "package", "orig": "package", "text_direction": "left_to_right", "confidence": 0.6702765056141881, "from_ocr": true}], "children": []}]}, "tablestructure": {"table_map": {}}, "figures_classification": null, "equations_prediction": null, "vlm_response": null}, "assembled": {"elements": [{"label": "text", "id": 0, "page_no": 0, "cluster": {"id": 0, "label": "text", "bbox": {"l": 69.0, "t": 74.66666666666667, "r": 506.6666666666667, "b": 153.33333333333334, "coord_origin": "TOPLEFT"}, "confidence": 0.9715733528137207, "cells": [{"index": 0, "rgba": {"r": 0, "g": 0, "b": 0, "a": 255}, "rect": {"r_x0": 71.33333333333333, "r_y0": 99.33333333333333, "r_x1": 506.6666666666667, "r_y1": 99.33333333333333, "r_x2": 506.6666666666667, "r_y2": 74.66666666666667, "r_x3": 71.33333333333333, "r_y3": 74.66666666666667, "coord_origin": "TOPLEFT"}, "text": "Docling bundles PDF document conversion to", "orig": "Docling bundles PDF document conversion to", "text_direction": "left_to_right", "confidence": 0.9555703127793324, "from_ocr": true}, {"index": 1, "rgba": {"r": 0, "g": 0, "b": 0, "a": 255}, "rect": {"r_x0": 69.0, "r_y0": 126.66666666666667, "r_x1": 506.6666666666667, "r_y1": 126.66666666666667, "r_x2": 506.6666666666667, "r_y2": 100.66666666666667, "r_x3": 69.0, "r_y3": 100.66666666666667, "coord_origin": "TOPLEFT"}, "text": "JSON and Markdown in an easy self contained", "orig": "JSON and Markdown in an easy self contained", "text_direction": "left_to_right", "confidence": 0.9741098171752292, "from_ocr": true}, {"index": 2, "rgba": {"r": 0, "g": 0, "b": 0, "a": 255}, "rect": {"r_x0": 70.66666666666667, "r_y0": 153.33333333333334, "r_x1": 154.0, "r_y1": 153.33333333333334, "r_x2": 154.0, "r_y2": 128.66666666666666, "r_x3": 70.66666666666667, "r_y3": 128.66666666666666, "coord_origin": "TOPLEFT"}, "text": "package", "orig": "package", "text_direction": "left_to_right", "confidence": 0.6702765056141881, "from_ocr": true}], "children": []}, "text": "Docling bundles PDF document conversion to JSON and Markdown in an easy self contained package"}], "body": [{"label": "text", "id": 0, "page_no": 0, "cluster": {"id": 0, "label": "text", "bbox": {"l": 69.0, "t": 74.66666666666667, "r": 506.6666666666667, "b": 153.33333333333334, "coord_origin": "TOPLEFT"}, "confidence": 0.9715733528137207, "cells": [{"index": 0, "rgba": {"r": 0, "g": 0, "b": 0, "a": 255}, "rect": {"r_x0": 71.33333333333333, "r_y0": 99.33333333333333, "r_x1": 506.6666666666667, "r_y1": 99.33333333333333, "r_x2": 506.6666666666667, "r_y2": 74.66666666666667, "r_x3": 71.33333333333333, "r_y3": 74.66666666666667, "coord_origin": "TOPLEFT"}, "text": "Docling bundles PDF document conversion to", "orig": "Docling bundles PDF document conversion to", "text_direction": "left_to_right", "confidence": 0.9555703127793324, "from_ocr": true}, {"index": 1, "rgba": {"r": 0, "g": 0, "b": 0, "a": 255}, "rect": {"r_x0": 69.0, "r_y0": 126.66666666666667, "r_x1": 506.6666666666667, "r_y1": 126.66666666666667, "r_x2": 506.6666666666667, "r_y2": 100.66666666666667, "r_x3": 69.0, "r_y3": 100.66666666666667, "coord_origin": "TOPLEFT"}, "text": "JSON and Markdown in an easy self contained", "orig": "JSON and Markdown in an easy self contained", "text_direction": "left_to_right", "confidence": 0.9741098171752292, "from_ocr": true}, {"index": 2, "rgba": {"r": 0, "g": 0, "b": 0, "a": 255}, "rect": {"r_x0": 70.66666666666667, "r_y0": 153.33333333333334, "r_x1": 154.0, "r_y1": 153.33333333333334, "r_x2": 154.0, "r_y2": 128.66666666666666, "r_x3": 70.66666666666667, "r_y3": 128.66666666666666, "coord_origin": "TOPLEFT"}, "text": "package", "orig": "package", "text_direction": "left_to_right", "confidence": 0.6702765056141881, "from_ocr": true}], "children": []}, "text": "Docling bundles PDF document conversion to JSON and Markdown in an easy self contained package"}], "headers": []}}] \ No newline at end of file diff --git a/tests/data/webp/test.webp b/tests/data/webp/test.webp new file mode 100644 index 00000000..45bc1bcd Binary files /dev/null and b/tests/data/webp/test.webp differ diff --git a/tests/test_backend_webp.py b/tests/test_backend_webp.py index 50bb2574..071b3c5c 100644 --- a/tests/test_backend_webp.py +++ b/tests/test_backend_webp.py @@ -1,12 +1,16 @@ +import sys from pathlib import Path +from typing import List + +from tests.verify_utils import verify_conversion_result_v2 from docling.datamodel.base_models import InputFormat from docling.datamodel.document import ConversionResult, DoclingDocument -from docling.datamodel.pipeline_options import RapidOcrOptions +from docling.datamodel.pipeline_options import RapidOcrOptions, OcrOptions, EasyOcrOptions, TesseractOcrOptions, \ + TesseractCliOcrOptions, OcrMacOptions from docling.document_converter import DocumentConverter, ImageFormatOption from .test_data_gen_flag import GEN_TEST_DATA -from .verify_utils import verify_document, verify_export GENERATE = GEN_TEST_DATA @@ -20,9 +24,10 @@ def get_webp_paths(): return webp_files -def get_converter(): +def get_converter(ocr_options: OcrOptions): image_format_option = ImageFormatOption() - image_format_option.pipeline_options.ocr_options = RapidOcrOptions() + image_format_option.pipeline_options.ocr_options = ocr_options + converter = DocumentConverter( format_options={InputFormat.IMAGE: image_format_option}, allowed_formats=[InputFormat.IMAGE], @@ -33,29 +38,40 @@ def get_converter(): def test_e2e_webp_conversions(): webp_paths = get_webp_paths() - converter = get_converter() - for webp_path in webp_paths: - print(f"converting {webp_path}") + engines: List[OcrOptions] = [ + EasyOcrOptions(), + TesseractOcrOptions(), + TesseractCliOcrOptions(), + EasyOcrOptions(force_full_page_ocr=True), + TesseractOcrOptions(force_full_page_ocr=True), + TesseractOcrOptions(force_full_page_ocr=True, lang=["auto"]), + TesseractCliOcrOptions(force_full_page_ocr=True), + TesseractCliOcrOptions(force_full_page_ocr=True, lang=["auto"]), + ] - gt_path = ( - webp_path.parent.parent / "groundtruth" / "docling_v2" / webp_path.name + # rapidocr is only available for Python >=3.6,<3.13 + if sys.version_info < (3, 13): + engines.append(RapidOcrOptions()) + engines.append(RapidOcrOptions(force_full_page_ocr=True)) + + # only works on mac + if "darwin" == sys.platform: + engines.append(OcrMacOptions()) + engines.append(OcrMacOptions(force_full_page_ocr=True)) + for ocr_options in engines: + print( + f"Converting with ocr_engine: {ocr_options.kind}, language: {ocr_options.lang}" ) + converter = get_converter(ocr_options=ocr_options) + for webp_path in webp_paths: + print(f"converting {webp_path}") - conv_result: ConversionResult = converter.convert(webp_path) + doc_result: ConversionResult = converter.convert(webp_path) - doc: DoclingDocument = conv_result.document - - pred_md: str = doc.export_to_markdown() - assert verify_export(pred_md, str(gt_path) + ".md"), "export to md" - - pred_itxt: str = doc._export_to_indented_text( - max_text_len=70, explicit_tables=False - ) - assert verify_export(pred_itxt, str(gt_path) + ".itxt"), ( - "export to indented-text" - ) - - assert verify_document(doc, str(gt_path) + ".json", GENERATE), ( - "document document" - ) + verify_conversion_result_v2( + input_path=webp_path, + doc_result=doc_result, + generate=GENERATE, + fuzzy=True, + )