From 282095f921c9e8c94b43e9442ef88c099d457102 Mon Sep 17 00:00:00 2001 From: Robert Sachunsky Date: Mon, 20 Jul 2026 02:06:48 +0200 Subject: [PATCH] =?UTF-8?q?layout:=20refactor=20into=20new=20function=20`d?= =?UTF-8?q?o=5Forder=5Fof=5Fregions=5Fheuristic`=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - calls `run_boxes_order()` and `do_order_of_regions()` - gets called w/ original or deskewed contours/masks - heading contours as empty list instead of `None` --- src/eynollah/eynollah.py | 54 +++++++++++++++++++++++----------- src/eynollah/utils/__init__.py | 8 ++--- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/eynollah/eynollah.py b/src/eynollah/eynollah.py index 6c579c8..eea3b6e 100644 --- a/src/eynollah/eynollah.py +++ b/src/eynollah/eynollah.py @@ -1617,7 +1617,7 @@ class Eynollah: num_col_classifier, erosion_hurts, regions_without_separators, - contours_h=None, + contours_h=[], label_seps_fl=6, ): if not erosion_hurts: @@ -1822,6 +1822,29 @@ class Eynollah: else: return ordered + def do_order_of_regions_heuristic( + self, + textregions_cont, + textregions_h_cont, + drop_caps_cont, + text_regions_p, + regions_without_separators, + num_col_classifier, + erosion_hurts, + ): + boxes = self.run_boxes_order(text_regions_p, + num_col_classifier, + erosion_hurts, + regions_without_separators, + contours_h=textregions_h_cont) + order_text = self.do_order_of_regions( + textregions_cont, + textregions_h_cont, + drop_caps_cont, + boxes, + regions_without_separators) #textline_mask_tot_ea) + return order_text + def filter_small_regions(self, textregions: List[Region], textregions_d: List[Region], area_factor: float, marginals: List[Region]) -> Tuple[List[Region], List[Region]]: """ Split list of contours (and optionally deskewed contours) into @@ -2342,31 +2365,28 @@ class Eynollah: self.logger.info("Using machine-based detection") order_text = self.do_order_of_regions_with_model( contours(textregions), - contours(textregions_h), + contours(textregions_h) if not self.headers_off else [], contours(drop_caps), text_regions_p) else: if np.abs(slope_deskew) < SLOPE_THRESHOLD: - boxes = self.run_boxes_order(text_regions_p, num_col_classifier, erosion_hurts, - regions_without_separators, - contours_h=(None if self.headers_off or not self.full_layout - else contours(textregions_h))) - order_text = self.do_order_of_regions( + order_text = self.do_order_of_regions_heuristic( contours(textregions), - contours(textregions_h), + contours(textregions_h) if not self.headers_off else [], contours(drop_caps), - boxes, regions_without_separators) #textline_mask_tot_ea) + text_regions_p, + regions_without_separators, + num_col_classifier, + erosion_hurts) else: - boxes_d = self.run_boxes_order(text_regions_p_d, num_col_classifier, erosion_hurts, - regions_without_separators_d, - contours_h=(None if self.headers_off or not self.full_layout - else contours(textregions_h_d))) - - order_text = self.do_order_of_regions( + order_text = self.do_order_of_regions_heuristic( contours(textregions_d), - contours(textregions_h_d), + contours(textregions_h_d) if not self.headers_off else [], contours(drop_caps), - boxes_d, regions_without_separators_d) #textline_mask_tot_ea_d) + text_regions_p_d, + regions_without_separators_d, + num_col_classifier, + erosion_hurts) self.logger.info(f"Detection of reading order took {time.time() - t_order:.1f}s") self.logger.info("Step 5/5: Output Generation") diff --git a/src/eynollah/utils/__init__.py b/src/eynollah/utils/__init__.py index 68691a3..cdf0a47 100644 --- a/src/eynollah/utils/__init__.py +++ b/src/eynollah/utils/__init__.py @@ -1219,7 +1219,7 @@ def find_number_of_columns_in_document( separator_mask: np.ndarray, num_col_classifier: int, tables: bool, - contours_h: List[np.ndarray] = None, + contours_h: List[np.ndarray] = [], logger=None ) -> Tuple[int, List[int], np.ndarray, List[int], np.ndarray]: """ @@ -1230,7 +1230,7 @@ def find_number_of_columns_in_document( * separator_mask: mask of (separator-only) region labels * num_col_classifier: predicted (expected) number of columns of the page * tables: whether tables may be present - * contours_h: polygons of potential headings (serving as additional horizontal separators) + * contours_h: contours of potential headings (serving as additional horizontal separators) * logger Returns: a tuple of @@ -1353,7 +1353,7 @@ def find_number_of_columns_in_document( matrix_of_seps_ch[len(cy_seps_hor):,8]=dist_y_ver matrix_of_seps_ch[len(cy_seps_hor):,9]=1 - if contours_h is not None: + if len(contours_h): _, dist_x_head, x_min_head, x_max_head, cy_head, _, y_min_head, y_max_head, _ = \ find_features_of_lines(contours_h) matrix_l_n = np.zeros((len(cy_head), matrix_of_seps_ch.shape[1]), dtype=int) @@ -1382,7 +1382,7 @@ def find_number_of_columns_in_document( (x_max_seps_hor >= .84 * width)] cy_seps_splitters = np.append(cy_seps_splitters, special_separators) - if contours_h is not None: + if len(contours_h): y_min_splitters_head = y_min_head[(x_min_head <= .16 * width) & (x_max_head >= .84 * width)] y_max_splitters_head = y_max_head[(x_min_head <= .16 * width) &