From ae0f19424119fe28677c89bd4476270c769a9d68 Mon Sep 17 00:00:00 2001 From: Robert Sachunsky Date: Fri, 13 Mar 2026 02:38:40 +0100 Subject: [PATCH] =?UTF-8?q?drop=20ProcessPoolExecutor=20for=20intra-page?= =?UTF-8?q?=20parallel=20subprocessing=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (interferes with inter-page parallelism, not as useful) --- src/eynollah/eynollah.py | 39 ++++++++++------------------ src/eynollah/utils/separate_lines.py | 32 ++++++++--------------- 2 files changed, 25 insertions(+), 46 deletions(-) diff --git a/src/eynollah/eynollah.py b/src/eynollah/eynollah.py index d15c111..24a3cf0 100644 --- a/src/eynollah/eynollah.py +++ b/src/eynollah/eynollah.py @@ -26,10 +26,8 @@ import time from typing import Optional from functools import partial from pathlib import Path -from multiprocessing import cpu_count import gc -from concurrent.futures import ProcessPoolExecutor import cv2 import numpy as np import shapely.affinity @@ -147,9 +145,6 @@ class Eynollah: else: self.num_col_lower = num_col_lower - # for parallelization of CPU-intensive tasks: - self.executor = ProcessPoolExecutor(max_workers=cpu_count()) - if threshold_art_class_layout: self.threshold_art_class_layout = float(threshold_art_class_layout) else: @@ -195,9 +190,6 @@ class Eynollah: self.model_zoo.get(model).output_shape) def __del__(self): - if executor := getattr(self, 'executor', None): - executor.shutdown() - del self.executor if model_zoo := getattr(self, 'model_zoo', None): if shutdown := getattr(model_zoo, 'shutdown', None): shutdown() @@ -1039,22 +1031,19 @@ class Eynollah: if not len(contours_par): return [], [], [] self.logger.debug("enter get_slopes_and_deskew_new_curved") - with share_ndarray(textline_mask_tot) as textline_mask_tot_shared: - with share_ndarray(mask_texts_only) as mask_texts_only_shared: - assert self.executor - results = self.executor.map(partial(do_work_of_slopes_new_curved, - textline_mask_tot_ea=textline_mask_tot_shared, - mask_texts_only=mask_texts_only_shared, - num_col=num_col, - scale_par=scale_par, - slope_deskew=slope_deskew, - MAX_SLOPE=MAX_SLOPE, - KERNEL=KERNEL, - logger=self.logger, - plotter=self.plotter, - name=name), - boxes, contours_par) - results = list(results) # exhaust prior to release + results = map(partial(do_work_of_slopes_new_curved, + textline_mask_tot_ea=textline_mask_tot, + mask_texts_only=mask_texts_only, + num_col=num_col, + scale_par=scale_par, + slope_deskew=slope_deskew, + MAX_SLOPE=MAX_SLOPE, + KERNEL=KERNEL, + logger=self.logger, + plotter=self.plotter, + name=name), + boxes, contours_par) + results = list(results) # exhaust prior to release #textline_polygons, box_coord, slopes = zip(*results) self.logger.debug("exit get_slopes_and_deskew_new_curved") return tuple(zip(*results)) @@ -1628,7 +1617,7 @@ class Eynollah: def run_deskew(self, textline_mask_tot_ea): #print(textline_mask_tot_ea.shape, 'textline_mask_tot_ea deskew') slope_deskew = return_deskew_slop(cv2.erode(textline_mask_tot_ea, KERNEL, iterations=2), 2, 30, True, - map=self.executor.map, logger=self.logger, plotter=self.plotter) + logger=self.logger, plotter=self.plotter) self.logger.info("slope_deskew: %.2f°", slope_deskew) return slope_deskew diff --git a/src/eynollah/utils/separate_lines.py b/src/eynollah/utils/separate_lines.py index 4051d42..9a74ade 100644 --- a/src/eynollah/utils/separate_lines.py +++ b/src/eynollah/utils/separate_lines.py @@ -15,7 +15,6 @@ from .contour import ( return_contours_of_interested_textline, find_contours_mean_y_diff, ) -from .shm import share_ndarray, wrap_ndarray_shared from . import ( find_num_col_deskew, box2rect, @@ -1493,7 +1492,6 @@ def separate_lines_new2(img_crop, thetha, num_col, slope_region, logger=None, pl return img_patch_interest_revised -@wrap_ndarray_shared(kw='img') def do_image_rotation(angle, img=None, sigma_des=1.0, logger=None): if logger is None: logger = getLogger(__package__) @@ -1507,7 +1505,7 @@ def do_image_rotation(angle, img=None, sigma_des=1.0, logger=None): return var def return_deskew_slop(img_patch_org, sigma_des,n_tot_angles=100, - main_page=False, logger=None, plotter=None, name=None, map=None): + main_page=False, logger=None, plotter=None, name=None): if main_page and plotter: plotter.save_plot_of_textline_density(img_patch_org, name) @@ -1527,16 +1525,16 @@ def return_deskew_slop(img_patch_org, sigma_des,n_tot_angles=100, if main_page and img_patch_org.shape[1] > img_patch_org.shape[0]: angles = np.array([-45, 0, 45, 90,]) - angle, _ = get_smallest_skew(img_resized, sigma_des, angles, map=map, logger=logger, name=name, plotter=plotter) + angle, _ = get_smallest_skew(img_resized, sigma_des, angles, logger=logger, name=name, plotter=plotter) angles = np.linspace(angle - 22.5, angle + 22.5, n_tot_angles) - angle, _ = get_smallest_skew(img_resized, sigma_des, angles, map=map, logger=logger, name=name, plotter=plotter) + angle, _ = get_smallest_skew(img_resized, sigma_des, angles, logger=logger, name=name, plotter=plotter) elif main_page: #angles = np.linspace(-12, 12, n_tot_angles)#np.array([0 , 45 , 90 , -45]) angles = np.concatenate((np.linspace(-12, -7, n_tot_angles // 4), np.linspace(-6, 6, n_tot_angles // 2), np.linspace(7, 12, n_tot_angles // 4))) - angle, var = get_smallest_skew(img_resized, sigma_des, angles, map=map, logger=logger, name=name, plotter=plotter) + angle, var = get_smallest_skew(img_resized, sigma_des, angles, logger=logger, name=name, plotter=plotter) early_slope_edge=11 if abs(angle) > early_slope_edge: @@ -1544,12 +1542,12 @@ def return_deskew_slop(img_patch_org, sigma_des,n_tot_angles=100, angles2 = np.linspace(-90, -12, n_tot_angles) else: angles2 = np.linspace(90, 12, n_tot_angles) - angle2, var2 = get_smallest_skew(img_resized, sigma_des, angles2, map=map, logger=logger, name=name, plotter=plotter) + angle2, var2 = get_smallest_skew(img_resized, sigma_des, angles2, logger=logger, name=name, plotter=plotter) if var2 > var: angle = angle2 else: angles = np.linspace(-25, 25, int(0.5 * n_tot_angles) + 10) - angle, var = get_smallest_skew(img_resized, sigma_des, angles, map=map, logger=logger, name=name, plotter=plotter) + angle, var = get_smallest_skew(img_resized, sigma_des, angles, logger=logger, name=name, plotter=plotter) early_slope_edge=22 if abs(angle) > early_slope_edge: @@ -1557,24 +1555,19 @@ def return_deskew_slop(img_patch_org, sigma_des,n_tot_angles=100, angles2 = np.linspace(-90, -25, int(0.5 * n_tot_angles) + 10) else: angles2 = np.linspace(90, 25, int(0.5 * n_tot_angles) + 10) - angle2, var2 = get_smallest_skew(img_resized, sigma_des, angles2, map=map, logger=logger, name=name, plotter=plotter) + angle2, var2 = get_smallest_skew(img_resized, sigma_des, angles2, logger=logger, name=name, plotter=plotter) if var2 > var: angle = angle2 # precision stage: angles = np.linspace(angle - 2.5, angle + 2.5, n_tot_angles // 2) - angle, _ = get_smallest_skew(img_resized, sigma_des, angles, map=map, logger=logger, name=name, plotter=plotter) + angle, _ = get_smallest_skew(img_resized, sigma_des, angles, logger=logger, name=name, plotter=plotter) return angle -def get_smallest_skew(img, sigma_des, angles, logger=None, plotter=None, name=None, map=map): +def get_smallest_skew(img, sigma_des, angles, logger=None, plotter=None, name=None): if logger is None: logger = getLogger(__package__) - if map is None: - results = [do_image_rotation.__wrapped__(angle, img=img, sigma_des=sigma_des, logger=logger) - for angle in angles] - else: - with share_ndarray(img) as img_shared: - results = list(map(partial(do_image_rotation, img=img_shared, sigma_des=sigma_des, logger=None), - angles)) + results = [do_image_rotation(angle, img=img, sigma_des=sigma_des, logger=logger) + for angle in angles] if plotter: plotter.save_plot_of_rotation_angle(angles, results, name) try: @@ -1589,8 +1582,6 @@ def get_smallest_skew(img, sigma_des, angles, logger=None, plotter=None, name=No var = 0 return angle, var -@wrap_ndarray_shared(kw='textline_mask_tot_ea') -@wrap_ndarray_shared(kw='mask_texts_only') def do_work_of_slopes_new_curved( box_text, contour_par, textline_mask_tot_ea=None, mask_texts_only=None, @@ -1685,7 +1676,6 @@ def do_work_of_slopes_new_curved( return textlines_cnt_per_region[::-1], crop_coor, slope -@wrap_ndarray_shared(kw='textline_mask_tot_ea') def do_work_of_slopes_new_light( box_text, contour, contour_par, textline_mask_tot_ea=None, slope_deskew=0,