Repository: mindee/doctr

Issue:
[document] Check integrity of PDF --> img conversion with default DPI
The current PDF reading implies a conversion to an image. As we are using the default args for this conversion, the DPI value might be low. We need to check that the default parameter is not bringing about performance issues due to low resolution rendering.


Discussion:
As per https://github.com/mindee/doctr/pull/237#issuecomment-832585154, we should update the default transformation for pdf reading in https://github.com/mindee/doctr/blob/main/doctr/documents/reader.py#L108

The default transformation matrix (None) yields a low DPI for page rendering. Doubling this while preserving the aspect ratio by default, would yield potentially better results.

I'll open a PR to handle this!

Resolving patch:
diff --git a/doctr/documents/reader.py b/doctr/documents/reader.py
--- a/doctr/documents/reader.py
+++ b/doctr/documents/reader.py
@@ -10,7 +10,7 @@
 from weasyprint import HTML
 from typing import List, Tuple, Optional, Any, Union, Sequence
 
-__all__ = ['read_pdf', 'read_img', 'read_html', 'DocumentFile']
+__all__ = ['read_pdf', 'read_img', 'read_html', 'DocumentFile', 'PDF']
 
 
 AbstractPath = Union[str, Path]
@@ -92,6 +92,7 @@ def convert_page_to_numpy(
     page: fitz.fitz.Page,
     output_size: Optional[Tuple[int, int]] = None,
     rgb_output: bool = True,
+    default_scales: Tuple[float, float] = (2, 2),
 ) -> np.ndarray:
     """Convert a fitz page to a numpy-formatted image
 
@@ -100,17 +101,21 @@ def convert_page_to_numpy(
         output_size: the expected output size of each page in format H x W. Default goes to 840 x 595 for A4 pdf,
         if you want to increase the resolution while preserving the original A4 aspect ratio can pass (1024, 726)
         rgb_output: whether the output ndarray channel order should be RGB instead of BGR.
+        default_scales: spatial scaling to be applied when output_size is not specified where (1, 1)
+            corresponds to 72 dpi rendering.
 
     Returns:
         the rendered image in numpy format
     """
 
-    transform_matrix = None
-
     # If no output size is specified, keep the origin one
     if output_size is not None:
         scales = (output_size[1] / page.MediaBox[2], output_size[0] / page.MediaBox[3])
-        transform_matrix = fitz.Matrix(*scales)
+    else:
+        # Default 72 DPI (scales of (1, 1)) is unnecessarily low
+        scales = default_scales
+
+    transform_matrix = fitz.Matrix(*scales)
 
     # Generate the pixel map using the transformation matrix
     stream = page.getPixmap(matrix=transform_matrix).getImageData()


Test patch:
diff --git a/test/test_documents_reader.py b/test/test_documents_reader.py
--- a/test/test_documents_reader.py
+++ b/test/test_documents_reader.py
@@ -10,18 +10,23 @@
 def test_convert_page_to_numpy(mock_pdf):
     pdf = fitz.open(mock_pdf)
     # Check correct read
-    rgb_page = reader.convert_page_to_numpy(pdf[0])
+    rgb_page = reader.convert_page_to_numpy(pdf[0], default_scales=(1, 1))
     assert isinstance(rgb_page, np.ndarray)
     assert rgb_page.shape == (792, 612, 3)
 
     # Check channel order
-    bgr_page = reader.convert_page_to_numpy(pdf[0], rgb_output=False)
+    bgr_page = reader.convert_page_to_numpy(pdf[0], default_scales=(1, 1), rgb_output=False)
     assert np.all(bgr_page == rgb_page[..., ::-1])
 
-    # Check rescaling
+    # Check resizing
     resized_page = reader.convert_page_to_numpy(pdf[0], output_size=(396, 306))
     assert resized_page.shape == (396, 306, 3)
 
+    # Check rescaling
+    rgb_page = reader.convert_page_to_numpy(pdf[0])
+    assert isinstance(rgb_page, np.ndarray)
+    assert rgb_page.shape == (1584, 1224, 3)
+
 
 def _check_doc_content(doc_tensors, num_pages):
     # 1 doc of 8 pages