pep8: whitespaces around operators

code-suggestions
cneud 2 weeks ago
parent fa7bb63481
commit 87ae6d11a9

@ -17,21 +17,18 @@ def main():
help="directory of GT page-xml files",
type=click.Path(exists=True, file_okay=False),
)
@click.option(
"--dir_out_modal_image",
"-domi",
help="directory where ground truth images would be written",
type=click.Path(exists=True, file_okay=False),
)
@click.option(
"--dir_out_classes",
"-docl",
help="directory where ground truth classes would be written",
type=click.Path(exists=True, file_okay=False),
)
@click.option(
"--input_height",
"-ih",
@ -47,18 +44,17 @@ def main():
"-min",
help="min area size of regions considered for reading order training.",
)
def machine_based_reading_order(dir_xml, dir_out_modal_image, dir_out_classes, input_height, input_width, min_area_size):
def machine_based_reading_order(dir_xml, dir_out_modal_image, dir_out_classes, input_height, input_width,
min_area_size):
xml_files_ind = os.listdir(dir_xml)
@main.command()
@click.option('--patches/--no-patches', default=True, help='by enabling this parameter you let the model to see the image in patches.')
@click.option('--model_dir', '-m', type=click.Path(exists=True, file_okay=False), required=True, help='directory containing models for prediction')
@click.option('--patches/--no-patches', default=True,
help='by enabling this parameter you let the model to see the image in patches.')
@click.option('--model_dir', '-m', type=click.Path(exists=True, file_okay=False), required=True,
help='directory containing models for prediction')
@click.argument('input_image')
@click.argument('output_image')
@click.option(
"--dir_in",
@ -72,7 +68,6 @@ def machine_based_reading_order(dir_xml, dir_out_modal_image, dir_out_classes, i
help="directory where the binarized images will be written",
type=click.Path(exists=True, file_okay=False),
)
def binarization(patches, model_dir, input_image, output_image, dir_in, dir_out):
if not dir_out and dir_in:
print("Error: You used -di but did not set -do")
@ -80,9 +75,8 @@ def binarization(patches, model_dir, input_image, output_image, dir_in, dir_out)
elif dir_out and not dir_in:
print("Error: You used -do to write out binarized images but have not set -di")
sys.exit(1)
SbbBinarizer(model_dir).run(image_path=input_image, use_patches=patches, save=output_image, dir_in=dir_in, dir_out=dir_out)
SbbBinarizer(model_dir).run(image_path=input_image, use_patches=patches, save=output_image, dir_in=dir_in,
dir_out=dir_out)
@main.command()
@ -92,7 +86,6 @@ def binarization(patches, model_dir, input_image, output_image, dir_in, dir_out)
help="image filename",
type=click.Path(exists=True, dir_okay=False),
)
@click.option(
"--out",
"-o",
@ -261,15 +254,19 @@ def binarization(patches, model_dir, input_image, output_image, dir_in, dir_out)
type=click.Choice(['OFF', 'DEBUG', 'INFO', 'WARN', 'ERROR']),
help="Override log level globally to this",
)
def layout(image, out, overwrite, dir_in, model, save_images, save_layout, save_deskewed, save_all, extract_only_images, save_page, enable_plotting, allow_enhancement, curved_line, textline_light, full_layout, tables, right2left, input_binary, allow_scaling, headers_off, light_version, reading_order_machine_based, do_ocr, num_col_upper, num_col_lower, skip_layout_and_reading_order, ignore_page_extraction, log_level):
def layout(image, out, overwrite, dir_in, model, save_images, save_layout, save_deskewed, save_all, extract_only_images,
save_page, enable_plotting, allow_enhancement, curved_line, textline_light, full_layout, tables, right2left,
input_binary, allow_scaling, headers_off, light_version, reading_order_machine_based, do_ocr, num_col_upper,
num_col_lower, skip_layout_and_reading_order, ignore_page_extraction, log_level):
initLogging()
if log_level:
getLogger('eynollah').setLevel(getLevelName(log_level))
if not enable_plotting and (save_layout or save_deskewed or save_all or save_page or save_images or allow_enhancement):
if not enable_plotting and (
save_layout or save_deskewed or save_all or save_page or save_images or allow_enhancement):
print("Error: You used one of -sl, -sd, -sa, -sp, -si or -ae but did not enable plotting with -ep")
sys.exit(1)
elif enable_plotting and not (save_layout or save_deskewed or save_all or save_page or save_images or allow_enhancement):
elif enable_plotting and not (
save_layout or save_deskewed or save_all or save_page or save_images or allow_enhancement):
print("Error: You used -ep to enable plotting but set none of -sl, -sd, -sa, -sp, -si or -ae")
sys.exit(1)
if textline_light and not light_version:
@ -277,8 +274,10 @@ def layout(image, out, overwrite, dir_in, model, save_images, save_layout, save_
sys.exit(1)
if light_version and not textline_light:
print('Error: You used -light without -tll. Light version need light textline to be enabled.')
if extract_only_images and (allow_enhancement or allow_scaling or light_version or curved_line or textline_light or full_layout or tables or right2left or headers_off) :
print('Error: You used -eoi which can not be enabled alongside light_version -light or allow_scaling -as or allow_enhancement -ae or curved_line -cl or textline_light -tll or full_layout -fl or tables -tab or right2left -r2l or headers_off -ho')
if extract_only_images and (
allow_enhancement or allow_scaling or light_version or curved_line or textline_light or full_layout or tables or right2left or headers_off):
print(
'Error: You used -eoi which can not be enabled alongside light_version -light or allow_scaling -as or allow_enhancement -ae or curved_line -cl or textline_light -tll or full_layout -fl or tables -tab or right2left -r2l or headers_off -ho')
sys.exit(1)
eynollah = Eynollah(
image_filename=image,
@ -368,8 +367,8 @@ def layout(image, out, overwrite, dir_in, model, save_images, save_layout, save_
type=click.Choice(['OFF', 'DEBUG', 'INFO', 'WARN', 'ERROR']),
help="Override log level globally to this",
)
def ocr(dir_in, out, dir_xmls, model, tr_ocr, export_textline_images_and_text, do_not_mask_with_textline_contour, log_level):
def ocr(dir_in, out, dir_xmls, model, tr_ocr, export_textline_images_and_text, do_not_mask_with_textline_contour,
log_level):
if log_level:
setOverrideLogLevel(log_level)
initLogging()

@ -38,6 +38,7 @@ sys.stderr = open(os.devnull, "w")
import tensorflow as tf
from tensorflow.python.keras import backend as K
from tensorflow.keras.models import load_model
sys.stderr = stderr
tf.get_logger().setLevel("ERROR")
warnings.filterwarnings("ignore")
@ -131,8 +132,8 @@ class Patches(layers.Layer):
patch_dims = patches.shape[-1]
patches = tf.reshape(patches, [batch_size, -1, patch_dims])
return patches
def get_config(self):
def get_config(self):
config = super().get_config().copy()
config.update({
'patch_size': self.patch_size,
@ -153,8 +154,8 @@ class PatchEncoder(layers.Layer):
positions = tf.range(start=0, limit=self.num_patches, delta=1)
encoded = self.projection(patch) + self.position_embedding(positions)
return encoded
def get_config(self):
def get_config(self):
config = super().get_config().copy()
config.update({
'num_patches': self.num_patches,
@ -1037,7 +1038,6 @@ class Eynollah:
np.newaxis]
indexer_inside_batch += 1
list_i_s = []
list_j_s = []
list_x_u = []
@ -1493,7 +1493,8 @@ class Eynollah:
else:
img = resize_image(img, int(img_height_h * 2500 / float(img_width_h)), 2500).astype(np.uint8)
prediction_regions = self.do_prediction(patches, img, model_region, marginal_of_patch_percent=0.1, n_batch_inference=3)
prediction_regions = self.do_prediction(patches, img, model_region, marginal_of_patch_percent=0.1,
n_batch_inference=3)
prediction_regions = resize_image(prediction_regions, img_height_h, img_width_h)
self.logger.debug("exit extract_text_regions")
return prediction_regions, prediction_regions
@ -1556,7 +1557,8 @@ class Eynollah:
self.logger.debug("exit extract_text_regions")
return prediction_regions, prediction_regions2
def get_slopes_and_deskew_new_light2(self, contours, contours_par, textline_mask_tot, image_page_rotated, boxes, slope_deskew):
def get_slopes_and_deskew_new_light2(self, contours, contours_par, textline_mask_tot, image_page_rotated, boxes,
slope_deskew):
polygons_of_textlines = return_contours_of_interested_region(textline_mask_tot, 1, 0.00001)
M_main_tot = [cv2.moments(polygons_of_textlines[j])
@ -1582,9 +1584,11 @@ class Eynollah:
_, crop_coor = crop_image_inside_box(boxes[index], image_page_rotated)
all_box_coord.append(crop_coor)
return all_found_textline_polygons, boxes, contours, contours_par, all_box_coord, np.array(range(len(contours_par))), slopes
return all_found_textline_polygons, boxes, contours, contours_par, all_box_coord, np.array(
range(len(contours_par))), slopes
def get_slopes_and_deskew_new_light(self, contours, contours_par, textline_mask_tot, image_page_rotated, boxes, slope_deskew):
def get_slopes_and_deskew_new_light(self, contours, contours_par, textline_mask_tot, image_page_rotated, boxes,
slope_deskew):
if not len(contours):
return [], [], [], [], [], [], []
self.logger.debug("enter get_slopes_and_deskew_new_light")
@ -1598,7 +1602,8 @@ class Eynollah:
self.logger.debug("exit get_slopes_and_deskew_new_light")
return tuple(zip(*results))
def get_slopes_and_deskew_new(self, contours, contours_par, textline_mask_tot, image_page_rotated, boxes, slope_deskew):
def get_slopes_and_deskew_new(self, contours, contours_par, textline_mask_tot, image_page_rotated, boxes,
slope_deskew):
if not len(contours):
return [], [], [], [], [], [], []
self.logger.debug("enter get_slopes_and_deskew_new")
@ -1615,7 +1620,8 @@ class Eynollah:
self.logger.debug("exit get_slopes_and_deskew_new")
return tuple(zip(*results))
def get_slopes_and_deskew_new_curved(self, contours, contours_par, textline_mask_tot, image_page_rotated, boxes, mask_texts_only, num_col, scale_par, slope_deskew):
def get_slopes_and_deskew_new_curved(self, contours, contours_par, textline_mask_tot, image_page_rotated, boxes,
mask_texts_only, num_col, scale_par, slope_deskew):
if not len(contours):
return [], [], [], [], [], [], []
self.logger.debug("enter get_slopes_and_deskew_new_curved")
@ -1680,7 +1686,6 @@ class Eynollah:
return ((prediction_textline[:, :, 0] == 1).astype(np.uint8),
(prediction_textline_longshot_true_size[:, :, 0] == 1).astype(np.uint8))
def do_work_of_slopes(self, q, poly, box_sub, boxes_per_process, textline_mask_tot, contours_per_process):
self.logger.debug('enter do_work_of_slopes')
slope_biggest = 0
@ -1688,17 +1693,20 @@ class Eynollah:
boxes_sub_new = []
poly_sub = []
for mv in range(len(boxes_per_process)):
crop_img, _ = crop_image_inside_box(boxes_per_process[mv], np.repeat(textline_mask_tot[:, :, np.newaxis], 3, axis=2))
crop_img, _ = crop_image_inside_box(boxes_per_process[mv],
np.repeat(textline_mask_tot[:, :, np.newaxis], 3, axis=2))
crop_img = crop_img[:, :, 0]
crop_img = cv2.erode(crop_img, KERNEL, iterations=2)
try:
textline_con, hierarchy = return_contours_of_image(crop_img)
textline_con_fil = filter_contours_area_of_image(crop_img, textline_con, hierarchy, max_area=1, min_area=0.0008)
textline_con_fil = filter_contours_area_of_image(crop_img, textline_con, hierarchy, max_area=1,
min_area=0.0008)
y_diff_mean = find_contours_mean_y_diff(textline_con_fil)
sigma_des = max(1, int(y_diff_mean * (4.0 / 40.0)))
crop_img[crop_img > 0] = 1
slope_corresponding_textregion = return_deskew_slop(crop_img, sigma_des,
map=self.executor.map, logger=self.logger, plotter=self.plotter)
map=self.executor.map, logger=self.logger,
plotter=self.plotter)
except Exception as why:
self.logger.error(why)
slope_corresponding_textregion = MAX_SLOPE
@ -1741,7 +1749,8 @@ class Eynollah:
img_resized = resize_image(img, img_h_new, img_w_new)
if not self.dir_in:
self.model_region, _ = self.start_new_session_and_model(self.model_region_dir_p_ens_light_only_images_extraction)
self.model_region, _ = self.start_new_session_and_model(
self.model_region_dir_p_ens_light_only_images_extraction)
prediction_regions_org = self.do_prediction_new_concept(True, img_resized, self.model_region)
@ -1884,7 +1893,8 @@ class Eynollah:
#print("inside 1 ", time.time()-t_in)
###textline_mask_tot_ea = self.run_textline(img_bin)
self.logger.debug("detecting textlines on %s with %d colors", str(img_resized.shape), len(np.unique(img_resized)))
self.logger.debug("detecting textlines on %s with %d colors", str(img_resized.shape),
len(np.unique(img_resized)))
textline_mask_tot_ea = self.run_textline(img_resized, num_col_classifier)
textline_mask_tot_ea = resize_image(textline_mask_tot_ea, img_height_h, img_width_h)
@ -2019,7 +2029,8 @@ class Eynollah:
try:
img_only_regions = cv2.erode(img_only_regions_with_sep[:, :], KERNEL, iterations=20)
_, _ = find_num_col(img_only_regions, num_col_classifier, self.tables, multiplier=6.0)
img = resize_image(img_org, int(img_org.shape[0]), int(img_org.shape[1]*(1.2 if is_image_enhanced else 1)))
img = resize_image(img_org, int(img_org.shape[0]),
int(img_org.shape[1] * (1.2 if is_image_enhanced else 1)))
prediction_regions_org = self.do_prediction(True, img, self.model_region)
prediction_regions_org = resize_image(prediction_regions_org, img_height_h, img_width_h)
@ -2113,7 +2124,6 @@ class Eynollah:
ratio_y = 1
ratio_x = 1
img = resize_image(prediction_bin, int(img_org.shape[0] * ratio_y), int(img_org.shape[1] * ratio_x))
prediction_regions_org = self.do_prediction(True, img, self.model_region)
prediction_regions_org = resize_image(prediction_regions_org, img_height_h, img_width_h)
@ -2130,7 +2140,6 @@ class Eynollah:
#prediction_regions_org[(prediction_regions_org[:,:] == 1) & (mask_zeros_y[:,:] == 1)]=0
mask_lines_only = (prediction_regions_org == 3) * 1
mask_texts_only = (prediction_regions_org == 1) * 1
mask_images_only = (prediction_regions_org == 2) * 1
@ -2537,7 +2546,8 @@ class Eynollah:
contours_new.append(contours_sep[ji])
if num_col_classifier >= 2:
only_recent_contour_image = np.zeros((layout.shape[0], layout.shape[1]))
only_recent_contour_image= cv2.fillPoly(only_recent_contour_image, pts=[contours_sep[ji]], color=(1,1,1))
only_recent_contour_image = cv2.fillPoly(only_recent_contour_image, pts=[contours_sep[ji]],
color=(1, 1, 1))
table_pixels_masked_from_early_pre = only_recent_contour_image * table_prediction_early
iou_in = 100. * table_pixels_masked_from_early_pre.sum() / only_recent_contour_image.sum()
#print(iou_in,'iou_in_in1')
@ -2552,7 +2562,8 @@ class Eynollah:
contours_new.append(contours[i])
if num_col_classifier >= 2:
only_recent_contour_image = np.zeros((layout.shape[0], layout.shape[1]))
only_recent_contour_image= cv2.fillPoly(only_recent_contour_image,pts=[contours[i]] ,color=(1,1,1))
only_recent_contour_image = cv2.fillPoly(only_recent_contour_image, pts=[contours[i]],
color=(1, 1, 1))
table_pixels_masked_from_early_pre = only_recent_contour_image * table_prediction_early
iou_in = 100. * table_pixels_masked_from_early_pre.sum() / only_recent_contour_image.sum()
@ -2622,9 +2633,11 @@ class Eynollah:
contours, hirarchy = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
if indiv == pixel_table:
main_contours = filter_contours_area_of_image_tables(thresh, contours, hirarchy, max_area = 1, min_area = 0.001)
main_contours = filter_contours_area_of_image_tables(thresh, contours, hirarchy, max_area=1,
min_area=0.001)
else:
main_contours = filter_contours_area_of_image_tables(thresh, contours, hirarchy, max_area = 1, min_area = min_area)
main_contours = filter_contours_area_of_image_tables(thresh, contours, hirarchy, max_area=1,
min_area=min_area)
img_comm = cv2.fillPoly(img_comm, pts=main_contours, color=(indiv, indiv, indiv))
img_comm = img_comm.astype(np.uint8)
@ -2659,8 +2672,10 @@ class Eynollah:
y_min_main_line, y_max_main_line = find_features_of_contours(contours_line)
y_min_main_tab, y_max_main_tab = find_features_of_contours(contours_tab)
cx_tab_m_text,cy_tab_m_text ,x_min_tab_m_text , x_max_tab_m_text, y_min_tab_m_text ,y_max_tab_m_text, _= find_new_features_of_contours(contours_table_m_text)
cx_tabl,cy_tabl ,x_min_tabl , x_max_tabl, y_min_tabl ,y_max_tabl,_= find_new_features_of_contours(contours_tab)
cx_tab_m_text, cy_tab_m_text, x_min_tab_m_text, x_max_tab_m_text, y_min_tab_m_text, y_max_tab_m_text, _ = find_new_features_of_contours(
contours_table_m_text)
cx_tabl, cy_tabl, x_min_tabl, x_max_tabl, y_min_tabl, y_max_tabl, _ = find_new_features_of_contours(
contours_tab)
if len(y_min_main_tab) > 0:
y_down_tabs = []
@ -2670,9 +2685,13 @@ class Eynollah:
y_down_tab = []
y_up_tab = []
for i_l in range(len(y_min_main_line)):
if y_min_main_tab[i_t]>y_min_main_line[i_l] and y_max_main_tab[i_t]>y_min_main_line[i_l] and y_min_main_tab[i_t]>y_max_main_line[i_l] and y_max_main_tab[i_t]>y_min_main_line[i_l]:
if y_min_main_tab[i_t] > y_min_main_line[i_l] and y_max_main_tab[i_t] > y_min_main_line[
i_l] and y_min_main_tab[i_t] > y_max_main_line[i_l] and y_max_main_tab[i_t] > \
y_min_main_line[i_l]:
pass
elif y_min_main_tab[i_t]<y_max_main_line[i_l] and y_max_main_tab[i_t]<y_max_main_line[i_l] and y_max_main_tab[i_t]<y_min_main_line[i_l] and y_min_main_tab[i_t]<y_min_main_line[i_l]:
elif y_min_main_tab[i_t] < y_max_main_line[i_l] and y_max_main_tab[i_t] < \
y_max_main_line[i_l] and y_max_main_tab[i_t] < y_min_main_line[i_l] and \
y_min_main_tab[i_t] < y_min_main_line[i_l]:
pass
elif np.abs(y_max_main_line[i_l] - y_min_main_line[i_l]) < 100:
pass
@ -2801,7 +2820,8 @@ class Eynollah:
prediction_table_full_erode = cv2.dilate(prediction_table_full_erode, KERNEL, iterations=4)
prediction_table_full_updown_erode = cv2.erode(pre_updown[:, :, 0], KERNEL, iterations=4)
prediction_table_full_updown_erode = cv2.dilate(prediction_table_full_updown_erode, KERNEL, iterations=4)
prediction_table_full_updown_erode = cv2.dilate(prediction_table_full_updown_erode, KERNEL,
iterations=4)
prediction_table[:, 0:img_w_half, :] = pre1[:, :, :]
prediction_table[:, img_w_half:, :] = pre2[:, :, :]
@ -2964,7 +2984,8 @@ class Eynollah:
else:
self.get_image_and_scales(img_org, img_res, scale)
if self.allow_scaling:
img_org, img_res, is_image_enhanced = self.resize_image_with_column_classifier(is_image_enhanced, img_bin)
img_org, img_res, is_image_enhanced = self.resize_image_with_column_classifier(is_image_enhanced,
img_bin)
self.get_image_and_scales_after_enhancing(img_org, img_res)
#print("enhancement in ", time.time()-t_in)
return img_res, is_image_enhanced, num_col_classifier, num_column_is_classified
@ -2973,7 +2994,8 @@ class Eynollah:
scaler_h_textline = 1 #1.3 # 1.2#1.2
scaler_w_textline = 1 #1.3 # 0.9#1
#print(image_page.shape)
textline_mask_tot_ea, _ = self.textline_contours(image_page, True, scaler_h_textline, scaler_w_textline, num_col_classifier)
textline_mask_tot_ea, _ = self.textline_contours(image_page, True, scaler_h_textline, scaler_w_textline,
num_col_classifier)
if self.textline_light:
textline_mask_tot_ea = textline_mask_tot_ea.astype(np.int16)
@ -3035,7 +3057,8 @@ class Eynollah:
regions_without_separators_d = (text_regions_p_1_n[:, :] == 1) * 1
if self.tables:
regions_without_separators_d[table_prediction_n[:, :] == 1] = 1
regions_without_separators = (text_regions_p[:, :] == 1) * 1 # ( (text_regions_p[:,:]==1) | (text_regions_p[:,:]==2) )*1 #self.return_regions_without_separators_new(text_regions_p[:,:,0],img_only_regions)
regions_without_separators = (text_regions_p[:,
:] == 1) * 1 # ( (text_regions_p[:,:]==1) | (text_regions_p[:,:]==2) )*1 #self.return_regions_without_separators_new(text_regions_p[:,:,0],img_only_regions)
#print(time.time()-t_0_box,'time box in 1')
if self.tables:
regions_without_separators[table_prediction == 1] = 1
@ -3100,11 +3123,13 @@ class Eynollah:
else:
text_regions_p_tables = np.copy(text_regions_p_1_n)
text_regions_p_tables = np.round(text_regions_p_tables)
text_regions_p_tables[:,:][(text_regions_p_tables[:,:] != 3) & (table_prediction_n[:,:] == 1)] = 10
text_regions_p_tables[:, :][
(text_regions_p_tables[:, :] != 3) & (table_prediction_n[:, :] == 1)] = 10
pixel_line = 3
img_revised_tab2 = self.add_tables_heuristic_to_layout(
text_regions_p_tables, boxes_d, 0, splitter_y_new_d, peaks_neg_tot_tables_d, text_regions_p_tables,
text_regions_p_tables, boxes_d, 0, splitter_y_new_d, peaks_neg_tot_tables_d,
text_regions_p_tables,
num_col_classifier, 0.000005, pixel_line)
img_revised_tab2_d, _ = self.check_iou_of_bounding_box_and_contour_for_tables(
img_revised_tab2, table_prediction_n, 10, num_col_classifier)
@ -3112,7 +3137,8 @@ class Eynollah:
img_revised_tab2_d_rotated = rotate_image(img_revised_tab2_d, -slope_deskew)
img_revised_tab2_d_rotated = np.round(img_revised_tab2_d_rotated)
img_revised_tab2_d_rotated = img_revised_tab2_d_rotated.astype(np.int8)
img_revised_tab2_d_rotated = resize_image(img_revised_tab2_d_rotated, text_regions_p.shape[0], text_regions_p.shape[1])
img_revised_tab2_d_rotated = resize_image(img_revised_tab2_d_rotated, text_regions_p.shape[0],
text_regions_p.shape[1])
#print(time.time()-t_0_box,'time box in 4')
self.logger.info("detecting boxes took %.1fs", time.time() - t1)
@ -3171,11 +3197,15 @@ class Eynollah:
img_revised_tab = text_regions_p[:, :]
if np.abs(slope_deskew) >= SLOPE_THRESHOLD:
image_page_rotated_n, textline_mask_tot_d, text_regions_p_1_n, table_prediction_n = \
rotation_not_90_func(image_page, textline_mask_tot, text_regions_p, table_prediction, slope_deskew)
rotation_not_90_func(image_page, textline_mask_tot, text_regions_p, table_prediction,
slope_deskew)
text_regions_p_1_n = resize_image(text_regions_p_1_n,text_regions_p.shape[0],text_regions_p.shape[1])
textline_mask_tot_d = resize_image(textline_mask_tot_d,text_regions_p.shape[0],text_regions_p.shape[1])
table_prediction_n = resize_image(table_prediction_n,text_regions_p.shape[0],text_regions_p.shape[1])
text_regions_p_1_n = resize_image(text_regions_p_1_n, text_regions_p.shape[0],
text_regions_p.shape[1])
textline_mask_tot_d = resize_image(textline_mask_tot_d, text_regions_p.shape[0],
text_regions_p.shape[1])
table_prediction_n = resize_image(table_prediction_n, text_regions_p.shape[0],
text_regions_p.shape[1])
regions_without_separators_d = (text_regions_p_1_n[:, :] == 1) * 1
regions_without_separators_d[table_prediction_n[:, :] == 1] = 1
@ -3191,11 +3221,15 @@ class Eynollah:
else:
if np.abs(slope_deskew) >= SLOPE_THRESHOLD:
image_page_rotated_n, textline_mask_tot_d, text_regions_p_1_n, table_prediction_n = \
rotation_not_90_func(image_page, textline_mask_tot, text_regions_p, table_prediction, slope_deskew)
rotation_not_90_func(image_page, textline_mask_tot, text_regions_p, table_prediction,
slope_deskew)
text_regions_p_1_n = resize_image(text_regions_p_1_n,text_regions_p.shape[0],text_regions_p.shape[1])
textline_mask_tot_d = resize_image(textline_mask_tot_d,text_regions_p.shape[0],text_regions_p.shape[1])
table_prediction_n = resize_image(table_prediction_n,text_regions_p.shape[0],text_regions_p.shape[1])
text_regions_p_1_n = resize_image(text_regions_p_1_n, text_regions_p.shape[0],
text_regions_p.shape[1])
textline_mask_tot_d = resize_image(textline_mask_tot_d, text_regions_p.shape[0],
text_regions_p.shape[1])
table_prediction_n = resize_image(table_prediction_n, text_regions_p.shape[0],
text_regions_p.shape[1])
regions_without_separators_d = (text_regions_p_1_n[:, :] == 1) * 1
regions_without_separators_d[table_prediction_n[:, :] == 1] = 1
@ -3227,7 +3261,8 @@ class Eynollah:
if np.abs(slope_deskew) >= SLOPE_THRESHOLD:
regions_without_separators_d = regions_without_separators_d.astype(np.uint8)
regions_without_separators_d = cv2.erode(regions_without_separators_d[:,:], KERNEL, iterations=6)
regions_without_separators_d = cv2.erode(regions_without_separators_d[:, :], KERNEL,
iterations=6)
else:
pass
@ -3250,11 +3285,13 @@ class Eynollah:
num_col_classifier, erosion_hurts, self.tables, self.right2left)
text_regions_p_tables = np.copy(text_regions_p_1_n)
text_regions_p_tables = np.round(text_regions_p_tables)
text_regions_p_tables[:,:][(text_regions_p_tables[:,:]!=3) & (table_prediction_n[:,:]==1)] = 10
text_regions_p_tables[:, :][
(text_regions_p_tables[:, :] != 3) & (table_prediction_n[:, :] == 1)] = 10
pixel_line = 3
img_revised_tab2 = self.add_tables_heuristic_to_layout(
text_regions_p_tables, boxes_d, 0, splitter_y_new_d, peaks_neg_tot_tables_d, text_regions_p_tables,
text_regions_p_tables, boxes_d, 0, splitter_y_new_d, peaks_neg_tot_tables_d,
text_regions_p_tables,
num_col_classifier, 0.000005, pixel_line)
img_revised_tab2_d, _ = self.check_iou_of_bounding_box_and_contour_for_tables(
@ -3264,7 +3301,8 @@ class Eynollah:
img_revised_tab2_d_rotated = np.round(img_revised_tab2_d_rotated)
img_revised_tab2_d_rotated = img_revised_tab2_d_rotated.astype(np.int8)
img_revised_tab2_d_rotated = resize_image(img_revised_tab2_d_rotated, text_regions_p.shape[0], text_regions_p.shape[1])
img_revised_tab2_d_rotated = resize_image(img_revised_tab2_d_rotated, text_regions_p.shape[0],
text_regions_p.shape[1])
if np.abs(slope_deskew) < 0.13:
img_revised_tab = np.copy(img_revised_tab2[:, :, 0])
@ -3758,9 +3796,11 @@ class Eynollah:
if abs_diff[i] == 0:
inc_x[i + 1] = dilation_m2 * (-1 * y_differential_mask_nonzeros[i])
inc_y[i + 1] = dilation_m2 * (x_differential_mask_nonzeros[i])
elif abs_diff[i]!=0 and x_differential_mask_nonzeros[i]==0 and y_differential_mask_nonzeros[i]!=0:
elif abs_diff[i] != 0 and x_differential_mask_nonzeros[i] == 0 and y_differential_mask_nonzeros[
i] != 0:
inc_x[i + 1] = dilation_m1 * (-1 * y_differential_mask_nonzeros[i])
elif abs_diff[i]!=0 and x_differential_mask_nonzeros[i]!=0 and y_differential_mask_nonzeros[i]==0:
elif abs_diff[i] != 0 and x_differential_mask_nonzeros[i] != 0 and y_differential_mask_nonzeros[
i] == 0:
inc_y[i + 1] = dilation_m1 * (x_differential_mask_nonzeros[i])
elif abs_diff[i] != 0 and abs_diff[i] >= 3:
@ -3964,9 +4004,11 @@ class Eynollah:
if abs_diff[i] == 0:
inc_x[i + 1] = dilation_m2 * (-1 * y_differential_mask_nonzeros[i])
inc_y[i + 1] = dilation_m2 * (x_differential_mask_nonzeros[i])
elif abs_diff[i]!=0 and x_differential_mask_nonzeros[i]==0 and y_differential_mask_nonzeros[i]!=0:
elif abs_diff[i] != 0 and x_differential_mask_nonzeros[i] == 0 and y_differential_mask_nonzeros[
i] != 0:
inc_x[i + 1] = dilation_m1 * (-1 * y_differential_mask_nonzeros[i])
elif abs_diff[i]!=0 and x_differential_mask_nonzeros[i]!=0 and y_differential_mask_nonzeros[i]==0:
elif abs_diff[i] != 0 and x_differential_mask_nonzeros[i] != 0 and y_differential_mask_nonzeros[
i] == 0:
inc_y[i + 1] = dilation_m1 * (x_differential_mask_nonzeros[i])
elif abs_diff[i] != 0 and abs_diff[i] >= 3:
@ -4039,7 +4081,8 @@ class Eynollah:
results = [cv2.pointPolygonTest(contours[ind], (cx_main[ind_small], cy_main[ind_small]), False)
for ind in contours_index_big]
if marginal_cnts:
results_marginal = [cv2.pointPolygonTest(marginal_cnts[ind], (cx_main[ind_small], cy_main[ind_small]), False)
results_marginal = [
cv2.pointPolygonTest(marginal_cnts[ind], (cx_main[ind_small], cy_main[ind_small]), False)
for ind in range(len(marginal_cnts))]
results_marginal = np.array(results_marginal)
@ -4094,7 +4137,8 @@ class Eynollah:
args_with_bigger_area = np.array(args_all)[areas_without > 1.5 * area_of_con_interest]
if len(args_with_bigger_area) > 0:
results = [cv2.pointPolygonTest(contours_txtline_of_all_textregions[ind], (cx_main_tot[ij], cy_main_tot[ij]), False)
results = [cv2.pointPolygonTest(contours_txtline_of_all_textregions[ind],
(cx_main_tot[ij], cy_main_tot[ij]), False)
for ind in args_with_bigger_area]
results = np.array(results)
if np.any(results == 1):
@ -4106,7 +4150,8 @@ class Eynollah:
textregion_index_to_del = np.array(textregion_index_to_del)
textline_in_textregion_index_to_del = np.array(textline_in_textregion_index_to_del)
for ind_u_a_trs in np.unique(textregion_index_to_del):
textline_in_textregion_index_to_del_ind = textline_in_textregion_index_to_del[textregion_index_to_del==ind_u_a_trs]
textline_in_textregion_index_to_del_ind = textline_in_textregion_index_to_del[
textregion_index_to_del == ind_u_a_trs]
textline_in_textregion_index_to_del_ind = np.sort(textline_in_textregion_index_to_del_ind)[::-1]
for ittrd in textline_in_textregion_index_to_del_ind:
contours[ind_u_a_trs].pop(ittrd)
@ -4154,7 +4199,8 @@ class Eynollah:
if len(contours_only_text_parent_d_ordered) > 0:
contours_only_text_parent_d_ordered.pop(ind_u_a_trs)
return contours, text_con_org, contours_textline, contours_only_text_parent_d_ordered, np.array(range(len(contours)))
return contours, text_con_org, contours_textline, contours_only_text_parent_d_ordered, np.array(
range(len(contours)))
def dilate_textlines(self, all_found_textline_polygons):
for j in range(len(all_found_textline_polygons)):
@ -4325,7 +4371,8 @@ class Eynollah:
self.logger.warning("will skip input for existing output file '%s'", self.writer.output_filename)
continue
img_res, is_image_enhanced, num_col_classifier, num_column_is_classified = self.run_enhancement(self.light_version)
img_res, is_image_enhanced, num_col_classifier, num_column_is_classified = self.run_enhancement(
self.light_version)
self.logger.info("Enhancing took %.1fs ", time.time() - t0)
if self.extract_only_images:
text_regions_p_1, erosion_hurts, polygons_lines_xml, polygons_of_images, image_page, page_coord, cont_page = \
@ -4352,7 +4399,6 @@ class Eynollah:
page_coord, image_page, textline_mask_tot_ea, img_bin_light, cont_page = \
self.run_graphics_and_columns_without_layout(textline_mask_tot_ea, img_bin_light)
##all_found_textline_polygons =self.scale_contours_new(textline_mask_tot_ea)
cnt_clean_rot_raw, hir_on_cnt_clean_rot = return_contours_of_image(textline_mask_tot_ea)
@ -4366,7 +4412,6 @@ class Eynollah:
all_found_textline_polygons = self.filter_contours_inside_a_bigger_one(
all_found_textline_polygons, textline_mask_tot_ea, type_contour="textline")
order_text_new = [0]
slopes = [0]
id_of_texts_tot = ['region_0001']
@ -4414,7 +4459,8 @@ class Eynollah:
num_col, num_col_classifier, img_only_regions, page_coord, image_page, mask_images, mask_lines, \
text_regions_p_1, cont_page, table_prediction, textline_mask_tot_ea, img_bin_light = \
self.run_graphics_and_columns_light(text_regions_p_1, textline_mask_tot_ea,
num_col_classifier, num_column_is_classified, erosion_hurts, img_bin_light)
num_col_classifier, num_column_is_classified, erosion_hurts,
img_bin_light)
#self.logger.info("run graphics %.1fs ", time.time() - t1t)
#print("text region early -3 in %.1fs", time.time() - t0)
textline_mask_tot_ea_org = np.copy(textline_mask_tot_ea)
@ -4428,7 +4474,8 @@ class Eynollah:
t1 = time.time()
num_col, num_col_classifier, img_only_regions, page_coord, image_page, mask_images, mask_lines, \
text_regions_p_1, cont_page, table_prediction = \
self.run_graphics_and_columns(text_regions_p_1, num_col_classifier, num_column_is_classified, erosion_hurts)
self.run_graphics_and_columns(text_regions_p_1, num_col_classifier, num_column_is_classified,
erosion_hurts)
self.logger.info("Graphics detection took %.1fs ", time.time() - t1)
#self.logger.info('cont_page %s', cont_page)
#plt.imshow(table_prediction)
@ -4505,7 +4552,6 @@ class Eynollah:
drop_label_in_full_layout = 4
textline_mask_tot_ea_org[img_revised_tab == drop_label_in_full_layout] = 0
text_only = (img_revised_tab[:, :] == 1) * 1
if np.abs(slope_deskew) >= SLOPE_THRESHOLD:
text_only_d = (text_regions_p_1_n[:, :] == 1) * 1
@ -4562,8 +4608,10 @@ class Eynollah:
areas_cnt_text_d = self.return_list_of_contours_with_desired_order(
areas_cnt_text_d, index_con_parents_d)
cx_bigest_d_big, cy_biggest_d_big, _, _, _, _, _ = find_new_features_of_contours([contours_biggest_d])
cx_bigest_d, cy_biggest_d, _, _, _, _, _ = find_new_features_of_contours(contours_only_text_parent_d)
cx_bigest_d_big, cy_biggest_d_big, _, _, _, _, _ = find_new_features_of_contours(
[contours_biggest_d])
cx_bigest_d, cy_biggest_d, _, _, _, _, _ = find_new_features_of_contours(
contours_only_text_parent_d)
try:
if len(cx_bigest_d) >= 5:
cx_bigest_d_last5 = cx_bigest_d[-5:]
@ -4684,7 +4732,8 @@ class Eynollah:
all_found_textline_polygons_marginals)
contours_only_text_parent, txt_con_org, all_found_textline_polygons, contours_only_text_parent_d_ordered, \
index_by_text_par_con = self.filter_contours_without_textline_inside(
contours_only_text_parent, txt_con_org, all_found_textline_polygons, contours_only_text_parent_d_ordered)
contours_only_text_parent, txt_con_org, all_found_textline_polygons,
contours_only_text_parent_d_ordered)
else:
textline_mask_tot_ea = cv2.erode(textline_mask_tot_ea, kernel=KERNEL, iterations=1)
all_found_textline_polygons, boxes_text, txt_con_org, contours_only_text_parent, all_box_coord, \
@ -4784,10 +4833,12 @@ class Eynollah:
if num_col_classifier >= 3:
if np.abs(slope_deskew) < SLOPE_THRESHOLD:
regions_without_separators = regions_without_separators.astype(np.uint8)
regions_without_separators = cv2.erode(regions_without_separators[:, :], KERNEL, iterations=6)
regions_without_separators = cv2.erode(regions_without_separators[:, :], KERNEL,
iterations=6)
else:
regions_without_separators_d = regions_without_separators_d.astype(np.uint8)
regions_without_separators_d = cv2.erode(regions_without_separators_d[:, :], KERNEL, iterations=6)
regions_without_separators_d = cv2.erode(regions_without_separators_d[:, :], KERNEL,
iterations=6)
if np.abs(slope_deskew) < SLOPE_THRESHOLD:
boxes, peaks_neg_tot_tables = return_boxes_of_images_by_order_of_reading_new(
@ -4812,7 +4863,8 @@ class Eynollah:
contours_only_text_parent, contours_only_text_parent_h, boxes, textline_mask_tot)
else:
order_text_new, id_of_texts_tot = self.do_order_of_regions(
contours_only_text_parent_d_ordered, contours_only_text_parent_h_d_ordered, boxes_d, textline_mask_tot_d)
contours_only_text_parent_d_ordered, contours_only_text_parent_h_d_ordered, boxes_d,
textline_mask_tot_d)
self.logger.info("detection of reading order took %.1fs", time.time() - t_order)
if self.ocr:
@ -4852,7 +4904,8 @@ class Eynollah:
#contours_only_text_parent_d_ordered = \
#list(np.array(contours_only_text_parent_d_ordered, dtype=np.int32)[index_by_text_par_con])
order_text_new, id_of_texts_tot = self.do_order_of_regions(
contours_only_text_parent_d_ordered, contours_only_text_parent_h, boxes_d, textline_mask_tot_d)
contours_only_text_parent_d_ordered, contours_only_text_parent_h, boxes_d,
textline_mask_tot_d)
if self.ocr:
device = cuda.get_current_device()
@ -4897,7 +4950,9 @@ class Eynollah:
img_croped = img_poly_on_img[y:y + h, x:x + w, :]
#cv2.imwrite('./extracted_lines/'+str(ind_tot)+'.jpg', img_croped)
text_ocr = self.return_ocr_of_textline_without_common_section(img_croped, model_ocr, processor, device, w, h2w_ratio, ind_tot)
text_ocr = self.return_ocr_of_textline_without_common_section(img_croped, model_ocr,
processor, device, w,
h2w_ratio, ind_tot)
ocr_textline_in_textregion.append(text_ocr)
ind_tot = ind_tot + 1
ocr_all_textlines.append(ocr_textline_in_textregion)
@ -4961,11 +5016,9 @@ class Eynollah_ocr:
model_ocr.get_layer(name="image").input,
model_ocr.get_layer(name="dense2").output)
with open(os.path.join(self.model_ocr_dir, "characters_org.txt"), "r") as config_file:
characters = json.load(config_file)
AUTOTUNE = tf.data.AUTOTUNE
# Mapping characters to integers.
@ -5002,7 +5055,6 @@ class Eynollah_ocr:
output.append(d)
return output
def distortion_free_resize(self, image, img_size):
w, h = img_size
image = tf.image.resize(image, size=(h, w), preserve_aspect_ratio=True)
@ -5073,6 +5125,7 @@ class Eynollah_ocr:
return [image1, image2]
else:
return None
def preprocess_and_resize_image_for_ocrcnn_model(self, img, image_height, image_width):
ratio = image_height / float(img.shape[0])
w_ratio = int(ratio * img.shape[1])
@ -5110,8 +5163,6 @@ class Eynollah_ocr:
region_tags = np.unique([x for x in alltags if x.endswith('TextRegion')])
cropped_lines = []
cropped_lines_region_indexer = []
cropped_lines_meging_indexing = []
@ -5125,7 +5176,8 @@ class Eynollah_ocr:
if child_textlines.tag.endswith("Coords"):
cropped_lines_region_indexer.append(indexer_text_region)
p_h = child_textlines.attrib['points'].split(' ')
textline_coords = np.array( [ [ int(x.split(',')[0]) , int(x.split(',')[1]) ] for x in p_h] )
textline_coords = np.array(
[[int(x.split(',')[0]), int(x.split(',')[1])] for x in p_h])
x, y, w, h = cv2.boundingRect(textline_coords)
h2w_ratio = h / float(w)
@ -5154,7 +5206,6 @@ class Eynollah_ocr:
cropped_lines_meging_indexing.append(0)
indexer_text_region = indexer_text_region + 1
extracted_texts = []
n_iterations = math.ceil(len(cropped_lines) / b_s)
@ -5172,7 +5223,11 @@ class Eynollah_ocr:
extracted_texts = extracted_texts + generated_text_merged
extracted_texts_merged = [extracted_texts[ind] if cropped_lines_meging_indexing[ind]==0 else extracted_texts[ind]+extracted_texts[ind+1] if cropped_lines_meging_indexing[ind]==1 else None for ind in range(len(cropped_lines_meging_indexing))]
extracted_texts_merged = [
extracted_texts[ind] if cropped_lines_meging_indexing[ind] == 0 else extracted_texts[ind] +
extracted_texts[ind + 1] if
cropped_lines_meging_indexing[ind] == 1 else None for ind in
range(len(cropped_lines_meging_indexing))]
extracted_texts_merged = [ind for ind in extracted_texts_merged if ind is not None]
#print(extracted_texts_merged, len(extracted_texts_merged))
@ -5182,23 +5237,21 @@ class Eynollah_ocr:
#print(len(unique_cropped_lines_region_indexer), 'unique_cropped_lines_region_indexer')
text_by_textregion = []
for ind in unique_cropped_lines_region_indexer:
extracted_texts_merged_un = np.array(extracted_texts_merged)[np.array(cropped_lines_region_indexer)==ind]
extracted_texts_merged_un = np.array(extracted_texts_merged)[
np.array(cropped_lines_region_indexer) == ind]
text_by_textregion.append(" ".join(extracted_texts_merged_un))
#print(len(text_by_textregion) , indexer_text_region, "text_by_textregion")
#print(time.time() - t0 ,'elapsed time')
indexer = 0
indexer_textregion = 0
for nn in root1.iter(region_tags):
text_subelement_textregion = ET.SubElement(nn, 'TextEquiv')
unicode_textregion = ET.SubElement(text_subelement_textregion, 'Unicode')
has_textline = False
for child_textregion in nn:
if child_textregion.tag.endswith("TextLine"):
@ -5211,8 +5264,6 @@ class Eynollah_ocr:
unicode_textregion.text = text_by_textregion[indexer_textregion]
indexer_textregion = indexer_textregion + 1
ET.register_namespace("", name_space)
tree1.write(out_file_ocr, xml_declaration=True, method='xml', encoding="utf8", default_namespace=None)
#print("Job done in %.1fs", time.time() - t0)
@ -5223,7 +5274,6 @@ class Eynollah_ocr:
image_height = 32
b_s = 8
img_size = (image_width, image_height)
for ind_img in ls_imgs:
@ -5258,7 +5308,8 @@ class Eynollah_ocr:
if child_textlines.tag.endswith("Coords"):
cropped_lines_region_indexer.append(indexer_text_region)
p_h = child_textlines.attrib['points'].split(' ')
textline_coords = np.array( [ [ int(x.split(',')[0]) , int(x.split(',')[1]) ] for x in p_h] )
textline_coords = np.array(
[[int(x.split(',')[0]), int(x.split(',')[1])] for x in p_h])
x, y, w, h = cv2.boundingRect(textline_coords)
@ -5275,21 +5326,27 @@ class Eynollah_ocr:
if not self.export_textline_images_and_text:
if h2w_ratio > 0.05:
img_fin = self.preprocess_and_resize_image_for_ocrcnn_model(img_crop, image_height, image_width)
img_fin = self.preprocess_and_resize_image_for_ocrcnn_model(img_crop,
image_height,
image_width)
cropped_lines.append(img_fin)
cropped_lines_meging_indexing.append(0)
else:
splited_images = self.return_textlines_split_if_needed(img_crop)
if splited_images:
img_fin = self.preprocess_and_resize_image_for_ocrcnn_model(splited_images[0], image_height, image_width)
img_fin = self.preprocess_and_resize_image_for_ocrcnn_model(
splited_images[0], image_height, image_width)
cropped_lines.append(img_fin)
cropped_lines_meging_indexing.append(1)
img_fin = self.preprocess_and_resize_image_for_ocrcnn_model(splited_images[1], image_height, image_width)
img_fin = self.preprocess_and_resize_image_for_ocrcnn_model(
splited_images[1], image_height, image_width)
cropped_lines.append(img_fin)
cropped_lines_meging_indexing.append(-1)
else:
img_fin = self.preprocess_and_resize_image_for_ocrcnn_model(img_crop, image_height, image_width)
img_fin = self.preprocess_and_resize_image_for_ocrcnn_model(img_crop,
image_height,
image_width)
cropped_lines.append(img_fin)
cropped_lines_meging_indexing.append(0)
@ -5301,10 +5358,12 @@ class Eynollah_ocr:
if not textline_text:
pass
else:
with open(os.path.join(self.dir_out, file_name+'_line_'+str(indexer_textlines)+'.txt'), 'w') as text_file:
with open(os.path.join(self.dir_out, file_name + '_line_' + str(
indexer_textlines) + '.txt'), 'w') as text_file:
text_file.write(textline_text)
cv2.imwrite(os.path.join(self.dir_out, file_name+'_line_'+str(indexer_textlines)+'.png'), img_crop )
cv2.imwrite(os.path.join(self.dir_out, file_name + '_line_' + str(
indexer_textlines) + '.png'), img_crop)
indexer_textlines += 1
@ -5328,7 +5387,6 @@ class Eynollah_ocr:
imgs = cropped_lines[n_start:n_end]
imgs = np.array(imgs).reshape(b_s, image_height, image_width, 3)
preds = self.prediction_model.predict(imgs, verbose=0)
pred_texts = self.decode_batch_predictions(preds)
@ -5336,14 +5394,19 @@ class Eynollah_ocr:
pred_texts_ib = pred_texts[ib].strip("[UNK]")
extracted_texts.append(pred_texts_ib)
extracted_texts_merged = [extracted_texts[ind] if cropped_lines_meging_indexing[ind]==0 else extracted_texts[ind]+extracted_texts[ind+1] if cropped_lines_meging_indexing[ind]==1 else None for ind in range(len(cropped_lines_meging_indexing))]
extracted_texts_merged = [
extracted_texts[ind] if cropped_lines_meging_indexing[ind] == 0 else extracted_texts[ind] +
extracted_texts[ind + 1] if
cropped_lines_meging_indexing[ind] == 1 else None for ind in
range(len(cropped_lines_meging_indexing))]
extracted_texts_merged = [ind for ind in extracted_texts_merged if ind is not None]
unique_cropped_lines_region_indexer = np.unique(cropped_lines_region_indexer)
text_by_textregion = []
for ind in unique_cropped_lines_region_indexer:
extracted_texts_merged_un = np.array(extracted_texts_merged)[np.array(cropped_lines_region_indexer)==ind]
extracted_texts_merged_un = np.array(extracted_texts_merged)[
np.array(cropped_lines_region_indexer) == ind]
text_by_textregion.append(" ".join(extracted_texts_merged_un))
indexer = 0
@ -5352,7 +5415,6 @@ class Eynollah_ocr:
text_subelement_textregion = ET.SubElement(nn, 'TextEquiv')
unicode_textregion = ET.SubElement(text_subelement_textregion, 'Unicode')
has_textline = False
for child_textregion in nn:
if child_textregion.tag.endswith("TextLine"):
@ -5366,5 +5428,6 @@ class Eynollah_ocr:
indexer_textregion = indexer_textregion + 1
ET.register_namespace("", name_space)
tree1.write(out_file_ocr,xml_declaration=True,method='xml',encoding="utf8",default_namespace=None)
tree1.write(out_file_ocr, xml_declaration=True, method='xml', encoding="utf8",
default_namespace=None)
#print("Job done in %.1fs", time.time() - t0)

@ -115,14 +115,16 @@ class SbbBinarizeProcessor(Processor):
file_id + '.IMG-BIN',
page_id=input_file.pageId,
file_grp=self.output_file_grp)
page.add_AlternativeImage(AlternativeImageType(filename=bin_image_path, comments='%s,binarized' % page_xywh['features']))
page.add_AlternativeImage(
AlternativeImageType(filename=bin_image_path, comments='%s,binarized' % page_xywh['features']))
elif oplevel == 'region':
regions = page.get_AllRegions(['Text', 'Table'], depth=1)
if not regions:
LOG.warning("Page '%s' contains no text/table regions", page_id)
for region in regions:
region_image, region_xywh = self.workspace.image_from_segment(region, page_image, page_xywh, feature_filter='binarized')
region_image, region_xywh = self.workspace.image_from_segment(region, page_image, page_xywh,
feature_filter='binarized')
region_image_bin = cv2pil(binarizer.run(image=pil2cv(region_image), use_patches=True))
region_image_bin_path = self.workspace.save_image_file(
region_image_bin,
@ -130,14 +132,16 @@ class SbbBinarizeProcessor(Processor):
page_id=input_file.pageId,
file_grp=self.output_file_grp)
region.add_AlternativeImage(
AlternativeImageType(filename=region_image_bin_path, comments='%s,binarized' % region_xywh['features']))
AlternativeImageType(filename=region_image_bin_path,
comments='%s,binarized' % region_xywh['features']))
elif oplevel == 'line':
region_line_tuples = [(r.id, r.get_TextLine()) for r in page.get_AllRegions(['Text'], depth=0)]
if not region_line_tuples:
LOG.warning("Page '%s' contains no text lines", page_id)
for region_id, line in region_line_tuples:
line_image, line_xywh = self.workspace.image_from_segment(line, page_image, page_xywh, feature_filter='binarized')
line_image, line_xywh = self.workspace.image_from_segment(line, page_image, page_xywh,
feature_filter='binarized')
line_image_bin = cv2pil(binarizer.run(image=pil2cv(line_image), use_patches=True))
line_image_bin_path = self.workspace.save_image_file(
line_image_bin,
@ -145,7 +149,8 @@ class SbbBinarizeProcessor(Processor):
page_id=input_file.pageId,
file_grp=self.output_file_grp)
line.add_AlternativeImage(
AlternativeImageType(filename=line_image_bin_path, comments='%s,binarized' % line_xywh['features']))
AlternativeImageType(filename=line_image_bin_path,
comments='%s,binarized' % line_xywh['features']))
self.workspace.add_file(
ID=file_id,

@ -51,11 +51,12 @@ class EynollahPlotter:
plt.rcParams["font.size"] = "40"
im = plt.imshow(text_regions_p[:, :])
colors = [im.cmap(im.norm(value)) for value in values]
patches = [mpatches.Patch(color=colors[np.where(values == i)[0][0]], label="{l}".format(l=pixels[int(np.where(values_indexes == i)[0][0])])) for i in values]
patches = [mpatches.Patch(color=colors[np.where(values == i)[0][0]],
label="{l}".format(l=pixels[int(np.where(values_indexes == i)[0][0])])) for i in
values]
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.0, fontsize=40)
plt.savefig(os.path.join(self.dir_of_layout, self.image_filename_stem + "_layout_main.png"))
def save_plot_of_layout_main_all(self, text_regions_p, image_page):
if self.dir_of_all is not None:
values = np.unique(text_regions_p[:, :])
@ -69,7 +70,9 @@ class EynollahPlotter:
plt.subplot(1, 2, 2)
im = plt.imshow(text_regions_p[:, :])
colors = [im.cmap(im.norm(value)) for value in values]
patches = [mpatches.Patch(color=colors[np.where(values == i)[0][0]], label="{l}".format(l=pixels[int(np.where(values_indexes == i)[0][0])])) for i in values]
patches = [mpatches.Patch(color=colors[np.where(values == i)[0][0]],
label="{l}".format(l=pixels[int(np.where(values_indexes == i)[0][0])])) for i in
values]
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.0, fontsize=60)
plt.savefig(os.path.join(self.dir_of_all, self.image_filename_stem + "_layout_main_and_page.png"))
@ -83,7 +86,9 @@ class EynollahPlotter:
plt.rcParams["font.size"] = "40"
im = plt.imshow(text_regions_p[:, :])
colors = [im.cmap(im.norm(value)) for value in values]
patches = [mpatches.Patch(color=colors[np.where(values == i)[0][0]], label="{l}".format(l=pixels[int(np.where(values_indexes == i)[0][0])])) for i in values]
patches = [mpatches.Patch(color=colors[np.where(values == i)[0][0]],
label="{l}".format(l=pixels[int(np.where(values_indexes == i)[0][0])])) for i in
values]
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.0, fontsize=40)
plt.savefig(os.path.join(self.dir_of_layout, self.image_filename_stem + "_layout.png"))
@ -100,7 +105,9 @@ class EynollahPlotter:
plt.subplot(1, 2, 2)
im = plt.imshow(text_regions_p[:, :])
colors = [im.cmap(im.norm(value)) for value in values]
patches = [mpatches.Patch(color=colors[np.where(values == i)[0][0]], label="{l}".format(l=pixels[int(np.where(values_indexes == i)[0][0])])) for i in values]
patches = [mpatches.Patch(color=colors[np.where(values == i)[0][0]],
label="{l}".format(l=pixels[int(np.where(values_indexes == i)[0][0])])) for i in
values]
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.0, fontsize=60)
plt.savefig(os.path.join(self.dir_of_all, self.image_filename_stem + "_layout_and_page.png"))
@ -116,7 +123,9 @@ class EynollahPlotter:
plt.subplot(1, 2, 2)
im = plt.imshow(textline_mask_tot_ea[:, :])
colors = [im.cmap(im.norm(value)) for value in values]
patches = [mpatches.Patch(color=colors[np.where(values == i)[0][0]], label="{l}".format(l=pixels[int(np.where(values_indexes == i)[0][0])])) for i in values]
patches = [mpatches.Patch(color=colors[np.where(values == i)[0][0]],
label="{l}".format(l=pixels[int(np.where(values_indexes == i)[0][0])])) for i in
values]
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.0, fontsize=60)
plt.savefig(os.path.join(self.dir_of_all, self.image_filename_stem + "_textline_and_page.png"))
@ -132,6 +141,7 @@ class EynollahPlotter:
cv2.imwrite(os.path.join(self.dir_of_all, self.image_filename_stem + "_page.png"), image_page)
if self.dir_save_page is not None:
cv2.imwrite(os.path.join(self.dir_save_page, self.image_filename_stem + "_page.png"), image_page)
def save_enhanced_image(self, img_res):
cv2.imwrite(os.path.join(self.dir_out, self.image_filename_stem + "_enhanced.png"), img_res)
@ -142,7 +152,8 @@ class EynollahPlotter:
plt.subplot(1, 2, 1)
plt.imshow(img_patch_org)
plt.subplot(1, 2, 2)
plt.plot(gaussian_filter1d(img_patch_org.sum(axis=1), 3),np.array(range(len(gaussian_filter1d(img_patch_org.sum(axis=1), 3)))),linewidth=8)
plt.plot(gaussian_filter1d(img_patch_org.sum(axis=1), 3),
np.array(range(len(gaussian_filter1d(img_patch_org.sum(axis=1), 3)))), linewidth=8)
plt.xlabel('Density of textline prediction in direction of X axis', fontsize=60)
plt.ylabel('Height', fontsize=60)
plt.yticks([0, len(gaussian_filter1d(img_patch_org.sum(axis=1), 3))])
@ -156,7 +167,8 @@ class EynollahPlotter:
plt.plot(angels, np.array(var_res), '-o', markersize=25, linewidth=4)
plt.xlabel('angle', fontsize=50)
plt.ylabel('variance of sum of rotated textline in direction of x axis', fontsize=50)
plt.plot(angels[np.argmax(var_res)],var_res[np.argmax(np.array(var_res))] ,'*',markersize=50,label='Angle of deskewing=' +str("{:.2f}".format(angels[np.argmax(var_res)]))+r'$\degree$')
plt.plot(angels[np.argmax(var_res)], var_res[np.argmax(np.array(var_res))], '*', markersize=50,
label='Angle of deskewing=' + str("{:.2f}".format(angels[np.argmax(var_res)])) + r'$\degree$')
plt.legend(loc='best')
plt.savefig(os.path.join(self.dir_of_all, self.image_filename_stem + '_rotation_angle.png'))
@ -168,9 +180,9 @@ class EynollahPlotter:
box = [x, y, w, h]
croped_page, page_coord = crop_image_inside_box(box, image_page)
croped_page = resize_image(croped_page, int(croped_page.shape[0] / self.scale_y), int(croped_page.shape[1] / self.scale_x))
croped_page = resize_image(croped_page, int(croped_page.shape[0] / self.scale_y),
int(croped_page.shape[1] / self.scale_x))
path = os.path.join(self.dir_of_cropped_images, self.image_filename_stem + "_" + str(index) + ".jpg")
cv2.imwrite(path, croped_page)
index += 1

@ -12,14 +12,15 @@ import os
import numpy as np
from PIL import Image
import cv2
environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
stderr = sys.stderr
sys.stderr = open(devnull, 'w')
import tensorflow as tf
from tensorflow.keras.models import load_model
from tensorflow.python.keras import backend as tensorflow_backend
sys.stderr = stderr
sys.stderr = stderr
import logging
@ -84,25 +85,22 @@ class SbbBinarizer:
img_padded[:, index_start_w: index_start_w + img.shape[1], :] = img[:, :, :]
elif img.shape[0] < model_height and img.shape[1] < model_width:
img_padded = np.zeros((model_height, model_width, img.shape[2]))
index_start_h = int(abs(img.shape[0] - model_height) / 2.)
index_start_w = int(abs(img.shape[1] - model_width) / 2.)
img_padded [ index_start_h: index_start_h+img.shape[0], index_start_w: index_start_w+img.shape[1], : ] = img[:,:,:]
img_padded[index_start_h: index_start_h + img.shape[0], index_start_w: index_start_w + img.shape[1],
:] = img[:, :, :]
else:
index_start_h = 0
index_start_w = 0
img_padded = np.copy(img)
img = np.copy(img_padded)
if use_patches:
margin = int(0.1 * model_width)
@ -110,7 +108,6 @@ class SbbBinarizer:
width_mid = model_width - 2 * margin
height_mid = model_height - 2 * margin
img = img / float(255.0)
img_h = img.shape[0]
@ -131,7 +128,6 @@ class SbbBinarizer:
else:
nyf = int(nyf)
list_i_s = []
list_j_s = []
list_x_u = []
@ -167,7 +163,6 @@ class SbbBinarizer:
index_y_u = img_h
index_y_d = img_h - model_height
list_i_s.append(i)
list_j_s.append(j)
list_x_u.append(index_x_u)
@ -175,13 +170,10 @@ class SbbBinarizer:
list_y_d.append(index_y_d)
list_y_u.append(index_y_u)
img_patch[batch_indexer, :, :, :] = img[index_y_d:index_y_u, index_x_d:index_x_u, :]
batch_indexer = batch_indexer + 1
if batch_indexer == n_batch_inference:
label_p_pred = model.predict(img_patch, verbose=0)
@ -203,35 +195,48 @@ class SbbBinarizer:
if i_batch == 0 and j_batch == 0:
seg_color = seg_color[0: seg_color.shape[0] - margin, 0: seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + 0 : index_y_u_in - margin, index_x_d_in + 0 : index_x_u_in - margin, :] = seg_color
prediction_true[index_y_d_in + 0: index_y_u_in - margin,
index_x_d_in + 0: index_x_u_in - margin, :] = seg_color
elif i_batch == nxf - 1 and j_batch == nyf - 1:
seg_color = seg_color[margin: seg_color.shape[0] - 0, margin: seg_color.shape[1] - 0, :]
prediction_true[index_y_d_in + margin : index_y_u_in - 0, index_x_d_in + margin : index_x_u_in - 0, :] = seg_color
prediction_true[index_y_d_in + margin: index_y_u_in - 0,
index_x_d_in + margin: index_x_u_in - 0, :] = seg_color
elif i_batch == 0 and j_batch == nyf - 1:
seg_color = seg_color[margin: seg_color.shape[0] - 0, 0: seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin : index_y_u_in - 0, index_x_d_in + 0 : index_x_u_in - margin, :] = seg_color
prediction_true[index_y_d_in + margin: index_y_u_in - 0,
index_x_d_in + 0: index_x_u_in - margin, :] = seg_color
elif i_batch == nxf - 1 and j_batch == 0:
seg_color = seg_color[0: seg_color.shape[0] - margin, margin: seg_color.shape[1] - 0, :]
prediction_true[index_y_d_in + 0 : index_y_u_in - margin, index_x_d_in + margin : index_x_u_in - 0, :] = seg_color
prediction_true[index_y_d_in + 0: index_y_u_in - margin,
index_x_d_in + margin: index_x_u_in - 0, :] = seg_color
elif i_batch == 0 and j_batch != 0 and j_batch != nyf - 1:
seg_color = seg_color[margin : seg_color.shape[0] - margin, 0 : seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin : index_y_u_in - margin, index_x_d_in + 0 : index_x_u_in - margin, :] = seg_color
seg_color = seg_color[margin: seg_color.shape[0] - margin,
0: seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin: index_y_u_in - margin,
index_x_d_in + 0: index_x_u_in - margin, :] = seg_color
elif i_batch == nxf - 1 and j_batch != 0 and j_batch != nyf - 1:
seg_color = seg_color[margin : seg_color.shape[0] - margin, margin : seg_color.shape[1] - 0, :]
prediction_true[index_y_d_in + margin : index_y_u_in - margin, index_x_d_in + margin : index_x_u_in - 0, :] = seg_color
seg_color = seg_color[margin: seg_color.shape[0] - margin,
margin: seg_color.shape[1] - 0, :]
prediction_true[index_y_d_in + margin: index_y_u_in - margin,
index_x_d_in + margin: index_x_u_in - 0, :] = seg_color
elif i_batch != 0 and i_batch != nxf - 1 and j_batch == 0:
seg_color = seg_color[0 : seg_color.shape[0] - margin, margin : seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + 0 : index_y_u_in - margin, index_x_d_in + margin : index_x_u_in - margin, :] = seg_color
seg_color = seg_color[0: seg_color.shape[0] - margin,
margin: seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + 0: index_y_u_in - margin,
index_x_d_in + margin: index_x_u_in - margin, :] = seg_color
elif i_batch != 0 and i_batch != nxf - 1 and j_batch == nyf - 1:
seg_color = seg_color[margin : seg_color.shape[0] - 0, margin : seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin : index_y_u_in - 0, index_x_d_in + margin : index_x_u_in - margin, :] = seg_color
seg_color = seg_color[margin: seg_color.shape[0] - 0,
margin: seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin: index_y_u_in - 0,
index_x_d_in + margin: index_x_u_in - margin, :] = seg_color
else:
seg_color = seg_color[margin : seg_color.shape[0] - margin, margin : seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin : index_y_u_in - margin, index_x_d_in + margin : index_x_u_in - margin, :] = seg_color
seg_color = seg_color[margin: seg_color.shape[0] - margin,
margin: seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin: index_y_u_in - margin,
index_x_d_in + margin: index_x_u_in - margin, :] = seg_color
indexer_inside_batch = indexer_inside_batch + 1
list_i_s = []
list_j_s = []
list_x_u = []
@ -263,35 +268,48 @@ class SbbBinarizer:
if i_batch == 0 and j_batch == 0:
seg_color = seg_color[0: seg_color.shape[0] - margin, 0: seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + 0 : index_y_u_in - margin, index_x_d_in + 0 : index_x_u_in - margin, :] = seg_color
prediction_true[index_y_d_in + 0: index_y_u_in - margin,
index_x_d_in + 0: index_x_u_in - margin, :] = seg_color
elif i_batch == nxf - 1 and j_batch == nyf - 1:
seg_color = seg_color[margin: seg_color.shape[0] - 0, margin: seg_color.shape[1] - 0, :]
prediction_true[index_y_d_in + margin : index_y_u_in - 0, index_x_d_in + margin : index_x_u_in - 0, :] = seg_color
prediction_true[index_y_d_in + margin: index_y_u_in - 0,
index_x_d_in + margin: index_x_u_in - 0, :] = seg_color
elif i_batch == 0 and j_batch == nyf - 1:
seg_color = seg_color[margin: seg_color.shape[0] - 0, 0: seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin : index_y_u_in - 0, index_x_d_in + 0 : index_x_u_in - margin, :] = seg_color
prediction_true[index_y_d_in + margin: index_y_u_in - 0,
index_x_d_in + 0: index_x_u_in - margin, :] = seg_color
elif i_batch == nxf - 1 and j_batch == 0:
seg_color = seg_color[0: seg_color.shape[0] - margin, margin: seg_color.shape[1] - 0, :]
prediction_true[index_y_d_in + 0 : index_y_u_in - margin, index_x_d_in + margin : index_x_u_in - 0, :] = seg_color
prediction_true[index_y_d_in + 0: index_y_u_in - margin,
index_x_d_in + margin: index_x_u_in - 0, :] = seg_color
elif i_batch == 0 and j_batch != 0 and j_batch != nyf - 1:
seg_color = seg_color[margin : seg_color.shape[0] - margin, 0 : seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin : index_y_u_in - margin, index_x_d_in + 0 : index_x_u_in - margin, :] = seg_color
seg_color = seg_color[margin: seg_color.shape[0] - margin,
0: seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin: index_y_u_in - margin,
index_x_d_in + 0: index_x_u_in - margin, :] = seg_color
elif i_batch == nxf - 1 and j_batch != 0 and j_batch != nyf - 1:
seg_color = seg_color[margin : seg_color.shape[0] - margin, margin : seg_color.shape[1] - 0, :]
prediction_true[index_y_d_in + margin : index_y_u_in - margin, index_x_d_in + margin : index_x_u_in - 0, :] = seg_color
seg_color = seg_color[margin: seg_color.shape[0] - margin,
margin: seg_color.shape[1] - 0, :]
prediction_true[index_y_d_in + margin: index_y_u_in - margin,
index_x_d_in + margin: index_x_u_in - 0, :] = seg_color
elif i_batch != 0 and i_batch != nxf - 1 and j_batch == 0:
seg_color = seg_color[0 : seg_color.shape[0] - margin, margin : seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + 0 : index_y_u_in - margin, index_x_d_in + margin : index_x_u_in - margin, :] = seg_color
seg_color = seg_color[0: seg_color.shape[0] - margin,
margin: seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + 0: index_y_u_in - margin,
index_x_d_in + margin: index_x_u_in - margin, :] = seg_color
elif i_batch != 0 and i_batch != nxf - 1 and j_batch == nyf - 1:
seg_color = seg_color[margin : seg_color.shape[0] - 0, margin : seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin : index_y_u_in - 0, index_x_d_in + margin : index_x_u_in - margin, :] = seg_color
seg_color = seg_color[margin: seg_color.shape[0] - 0,
margin: seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin: index_y_u_in - 0,
index_x_d_in + margin: index_x_u_in - margin, :] = seg_color
else:
seg_color = seg_color[margin : seg_color.shape[0] - margin, margin : seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin : index_y_u_in - margin, index_x_d_in + margin : index_x_u_in - margin, :] = seg_color
seg_color = seg_color[margin: seg_color.shape[0] - margin,
margin: seg_color.shape[1] - margin, :]
prediction_true[index_y_d_in + margin: index_y_u_in - margin,
index_x_d_in + margin: index_x_u_in - margin, :] = seg_color
indexer_inside_batch = indexer_inside_batch + 1
list_i_s = []
list_j_s = []
list_x_u = []
@ -303,9 +321,8 @@ class SbbBinarizer:
img_patch = np.zeros((n_batch_inference, model_height, model_width, 3))
prediction_true = prediction_true[index_start_h: index_start_h+img_org_h, index_start_w: index_start_w+img_org_w,:]
prediction_true = prediction_true[index_start_h: index_start_h + img_org_h,
index_start_w: index_start_w + img_org_w, :]
prediction_true = prediction_true.astype(np.uint8)
else:

@ -17,7 +17,6 @@ from .contour import (contours_in_same_horizon,
def return_x_start_end_mothers_childs_and_type_of_reading_order(
x_min_hor_some, x_max_hor_some, cy_hor_some, peak_points, cy_hor_diff):
x_start = []
x_end = []
kind = [] #if covers 2 and more than 2 columns set it to 1 otherwise 0
@ -240,7 +239,8 @@ def return_x_start_end_mothers_childs_and_type_of_reading_order(
##remained_sep_indexes_without_mother = remained_sep_indexes[mother==0]
##remained_sep_indexes_with_child_without_mother = remained_sep_indexes[mother==0 & child==1]
remained_sep_indexes_without_mother = np.array(list(remained_sep_indexes))[np.array(mother) == 0]
remained_sep_indexes_with_child_without_mother=np.array(list(remained_sep_indexes))[(np.array(mother)==0) & (np.array(child)==1)]
remained_sep_indexes_with_child_without_mother = np.array(list(remained_sep_indexes))[
(np.array(mother) == 0) & (np.array(child) == 1)]
#print(remained_sep_indexes_without_mother,'remained_sep_indexes_without_mother')
#print(remained_sep_indexes_without_mother,'remained_sep_indexes_without_mother')
@ -297,10 +297,12 @@ def return_x_start_end_mothers_childs_and_type_of_reading_order(
x_end_with_child_without_mother,
new_main_sep_y)
def crop_image_inside_box(box, img_org_copy):
image_box = img_org_copy[box[1]: box[1] + box[3], box[0]: box[0] + box[2]]
return image_box, [box[1], box[1] + box[3], box[0], box[0] + box[2]]
def otsu_copy_binary(img):
img_r = np.zeros((img.shape[0], img.shape[1], 3))
img1 = img[:, :, 0]
@ -313,6 +315,7 @@ def otsu_copy_binary(img):
img_r = img_r / float(np.max(img_r)) * 255
return img_r
def find_features_of_lines(contours_main):
areas_main = np.array([cv2.contourArea(contours_main[j]) for j in range(len(contours_main))])
M_main = [cv2.moments(contours_main[j]) for j in range(len(contours_main))]
@ -347,6 +350,7 @@ def find_features_of_lines(contours_main):
y_max_main,
np.array(cx_main))
def boosting_headers_by_longshot_region_segmentation(textregion_pre_p, textregion_pre_np, img_only_text):
textregion_pre_p_org = np.copy(textregion_pre_p)
# 4 is drop capitals
@ -366,11 +370,13 @@ def boosting_headers_by_longshot_region_segmentation(textregion_pre_p, textregio
(textregion_pre_p[:, :, 0] != 2)] = 1
return textregion_pre_p
def find_num_col_deskew(regions_without_separators, sigma_, multiplier=3.8):
regions_without_separators_0 = regions_without_separators.sum(axis=1)
z = gaussian_filter1d(regions_without_separators_0, sigma_)
return np.std(z)
def find_num_col(regions_without_separators, num_col_classifier, tables, multiplier=3.8):
regions_without_separators_0 = regions_without_separators.sum(axis=0)
##plt.plot(regions_without_separators_0)
@ -867,7 +873,6 @@ def check_any_text_region_in_model_one_is_main_or_header(
all_box_coord, all_found_textline_polygons,
slopes,
contours_only_text_parent_d_ordered):
cx_main, cy_main, x_min_main, x_max_main, y_min_main, y_max_main, y_corr_x_min_from_argmin = \
find_new_features_of_contours(contours_only_text_parent)
@ -929,13 +934,13 @@ def check_any_text_region_in_model_one_is_main_or_header(
contours_only_text_parent_main_d,
contours_only_text_parent_head_d)
def check_any_text_region_in_model_one_is_main_or_header_light(
regions_model_1, regions_model_full,
contours_only_text_parent,
all_box_coord, all_found_textline_polygons,
slopes,
contours_only_text_parent_d_ordered):
### to make it faster
h_o = regions_model_1.shape[0]
w_o = regions_model_1.shape[1]
@ -1145,6 +1150,7 @@ def small_textlines_to_parent_adherence2(textlines_con, textline_iamge, num_col)
textlines_con_changed.append(textlines_big_org_form)
return textlines_con_changed
def order_of_regions(textline_mask, contours_main, contours_header, y_ref):
##plt.imshow(textline_mask)
##plt.show()
@ -1291,7 +1297,6 @@ def order_of_regions(textline_mask, contours_main, contours_header, y_ref):
def combine_hor_lines_and_delete_cross_points_and_get_lines_features_back_new(
img_p_in_ver, img_in_hor, num_col_classifier):
#img_p_in_ver = cv2.erode(img_p_in_ver, self.kernel, iterations=2)
img_p_in_ver = img_p_in_ver.astype(np.uint8)
img_p_in_ver = np.repeat(img_p_in_ver[:, :, np.newaxis], 3, axis=2)
@ -1321,8 +1326,10 @@ def combine_hor_lines_and_delete_cross_points_and_get_lines_features_back_new(
find_features_of_lines(contours_lines_hor)
x_width_smaller_than_acolumn_width = img_in_hor.shape[1] / float(num_col_classifier + 1.)
len_lines_bigger_than_x_width_smaller_than_acolumn_width=len( dist_x_hor[dist_x_hor>=x_width_smaller_than_acolumn_width] )
len_lines_bigger_than_x_width_smaller_than_acolumn_width_per_column=int(len_lines_bigger_than_x_width_smaller_than_acolumn_width /
len_lines_bigger_than_x_width_smaller_than_acolumn_width = len(
dist_x_hor[dist_x_hor >= x_width_smaller_than_acolumn_width])
len_lines_bigger_than_x_width_smaller_than_acolumn_width_per_column = int(
len_lines_bigger_than_x_width_smaller_than_acolumn_width /
float(num_col_classifier))
if len_lines_bigger_than_x_width_smaller_than_acolumn_width_per_column < 10:
args_hor = np.arange(len(slope_lines_hor))
@ -1612,7 +1619,6 @@ def return_boxes_of_images_by_order_of_reading_new(
splitter_y_new, regions_without_separators,
matrix_of_lines_ch,
num_col_classifier, erosion_hurts, tables, right2left_readingorder):
if right2left_readingorder:
regions_without_separators = cv2.flip(regions_without_separators, 1)
boxes = []
@ -1840,7 +1846,8 @@ def return_boxes_of_images_by_order_of_reading_new(
y_lines_by_order = []
x_start_by_order = []
x_end_by_order = []
if (len(x_end_with_child_without_mother)==0 and reading_order_type==0) or reading_order_type==1:
if (
len(x_end_with_child_without_mother) == 0 and reading_order_type == 0) or reading_order_type == 1:
if reading_order_type == 1:
y_lines_by_order.append(int(splitter_y_new[i]))
x_start_by_order.append(0)
@ -1856,7 +1863,8 @@ def return_boxes_of_images_by_order_of_reading_new(
all_columns = np.arange(len(peaks_neg_tot) - 1)
columns_not_covered = list(set(all_columns) - set(columns_covered_by_mothers))
y_type_2 = np.append(y_type_2, [int(splitter_y_new[i])] * (len(columns_not_covered) + len(x_start_without_mother)))
y_type_2 = np.append(y_type_2, [int(splitter_y_new[i])] * (
len(columns_not_covered) + len(x_start_without_mother)))
##y_lines_by_order = np.append(y_lines_by_order, [int(splitter_y_new[i])] * len(columns_not_covered))
##x_start_by_order = np.append(x_start_by_order, [0] * len(columns_not_covered))
x_starting = np.append(x_starting, columns_not_covered)
@ -1899,7 +1907,8 @@ def return_boxes_of_images_by_order_of_reading_new(
all_columns = np.arange(len(peaks_neg_tot) - 1)
columns_not_covered = list(set(all_columns) - set(columns_covered_by_mothers))
y_type_2 = np.append(y_type_2, [int(splitter_y_new[i])] * (len(columns_not_covered) + len(x_start_without_mother)))
y_type_2 = np.append(y_type_2, [int(splitter_y_new[i])] * (
len(columns_not_covered) + len(x_start_without_mother)))
##y_lines_by_order = np.append(y_lines_by_order, [int(splitter_y_new[i])] * len(columns_not_covered))
##x_start_by_order = np.append(x_start_by_order, [0] * len(columns_not_covered))
x_starting = np.append(x_starting, columns_not_covered)
@ -1915,7 +1924,8 @@ def return_boxes_of_images_by_order_of_reading_new(
columns_covered_by_with_child_no_mothers = list(set(columns_covered_by_with_child_no_mothers))
all_columns = np.arange(len(peaks_neg_tot) - 1)
columns_not_covered_child_no_mother = list(set(all_columns) - set(columns_covered_by_with_child_no_mothers))
columns_not_covered_child_no_mother = list(
set(all_columns) - set(columns_covered_by_with_child_no_mothers))
#indexes_to_be_spanned=[]
for i_s in range(len(x_end_with_child_without_mother)):
columns_not_covered_child_no_mother.append(x_start_with_child_without_mother[i_s])
@ -1925,7 +1935,8 @@ def return_boxes_of_images_by_order_of_reading_new(
x_start_with_child_without_mother = np.array(x_start_with_child_without_mother)
for i_s_nc in columns_not_covered_child_no_mother:
if i_s_nc in x_start_with_child_without_mother:
x_end_biggest_column = x_end_with_child_without_mother[x_start_with_child_without_mother==i_s_nc][0]
x_end_biggest_column = \
x_end_with_child_without_mother[x_start_with_child_without_mother == i_s_nc][0]
args_all_biggest_lines = ind_args[(x_starting == i_s_nc) &
(x_ending == x_end_biggest_column)]
y_column_nc = y_type_2[args_all_biggest_lines]
@ -1968,32 +1979,43 @@ def return_boxes_of_images_by_order_of_reading_new(
list(columns_not_covered)) != set(all_columns)):
should_longest_line_be_extended = 1
index_lines_so_close_to_top_separator = \
np.arange(len(y_all_between_nm_wc))[(y_all_between_nm_wc>y_column_nc[i_c]) &
np.arange(len(y_all_between_nm_wc))[
(y_all_between_nm_wc > y_column_nc[i_c]) &
(y_all_between_nm_wc <= (y_column_nc[i_c] + 500))]
if len(index_lines_so_close_to_top_separator) > 0:
indexes_remained_after_deleting_closed_lines = \
np.array(list(set(list(range(len(y_all_between_nm_wc)))) -
set(list(index_lines_so_close_to_top_separator))))
if len(indexes_remained_after_deleting_closed_lines) > 0:
y_all_between_nm_wc = y_all_between_nm_wc[indexes_remained_after_deleting_closed_lines]
x_starting_all_between_nm_wc = x_starting_all_between_nm_wc[indexes_remained_after_deleting_closed_lines]
x_ending_all_between_nm_wc = x_ending_all_between_nm_wc[indexes_remained_after_deleting_closed_lines]
y_all_between_nm_wc = y_all_between_nm_wc[
indexes_remained_after_deleting_closed_lines]
x_starting_all_between_nm_wc = x_starting_all_between_nm_wc[
indexes_remained_after_deleting_closed_lines]
x_ending_all_between_nm_wc = x_ending_all_between_nm_wc[
indexes_remained_after_deleting_closed_lines]
y_all_between_nm_wc = np.append(y_all_between_nm_wc, y_column_nc[i_c])
x_starting_all_between_nm_wc = np.append(x_starting_all_between_nm_wc, i_s_nc)
x_ending_all_between_nm_wc = np.append(x_ending_all_between_nm_wc, x_end_biggest_column)
x_ending_all_between_nm_wc = np.append(x_ending_all_between_nm_wc,
x_end_biggest_column)
if len(x_diff_all_between_nm_wc) > 0:
try:
y_all_between_nm_wc = np.append(y_all_between_nm_wc, y_column_nc[i_c])
x_starting_all_between_nm_wc = np.append(x_starting_all_between_nm_wc, x_starting_all_between_nm_wc[biggest])
x_ending_all_between_nm_wc = np.append(x_ending_all_between_nm_wc, x_ending_all_between_nm_wc[biggest])
x_starting_all_between_nm_wc = np.append(x_starting_all_between_nm_wc,
x_starting_all_between_nm_wc[
biggest])
x_ending_all_between_nm_wc = np.append(x_ending_all_between_nm_wc,
x_ending_all_between_nm_wc[biggest])
except:
pass
y_all_between_nm_wc = np.append(y_all_between_nm_wc, [y_column_nc[i_c]] * len(columns_not_covered))
x_starting_all_between_nm_wc = np.append(x_starting_all_between_nm_wc, columns_not_covered)
x_ending_all_between_nm_wc = np.append(x_ending_all_between_nm_wc, np.array(columns_not_covered) + 1)
y_all_between_nm_wc = np.append(y_all_between_nm_wc,
[y_column_nc[i_c]] * len(columns_not_covered))
x_starting_all_between_nm_wc = np.append(x_starting_all_between_nm_wc,
columns_not_covered)
x_ending_all_between_nm_wc = np.append(x_ending_all_between_nm_wc,
np.array(columns_not_covered) + 1)
ind_args_between = np.arange(len(x_ending_all_between_nm_wc))
for column in range(i_s_nc, x_end_biggest_column):
@ -2083,7 +2105,8 @@ def return_boxes_of_images_by_order_of_reading_new(
else:
columns_covered_by_lines_covered_more_than_2col = columns_covered_by_lines_covered_more_than_2col + \
list(range(x_starting[dj], x_ending[dj]))
columns_covered_by_lines_covered_more_than_2col = list(set(columns_covered_by_lines_covered_more_than_2col))
columns_covered_by_lines_covered_more_than_2col = list(
set(columns_covered_by_lines_covered_more_than_2col))
columns_not_covered = list(set(all_columns) - set(columns_covered_by_lines_covered_more_than_2col))
y_type_2 = np.append(y_type_2, [int(splitter_y_new[i])] * (len(columns_not_covered) + 1))

@ -339,4 +339,3 @@ def return_contours_of_interested_region_by_size(region_pre_p, pixel, min_area,
img_ret = cv2.fillPoly(img_ret, pts=contours_imgs, color=(1, 1, 1))
return img_ret[:, :, 0]

@ -29,7 +29,8 @@ def adhere_drop_capital_region_into_corresponding_textline(
img_con_all = np.zeros((text_regions_p.shape[0], text_regions_p.shape[1], 3))
for j_cont in range(len(contours_only_text_parent)):
img_con_all[all_box_coord[j_cont][0] : all_box_coord[j_cont][1], all_box_coord[j_cont][2] : all_box_coord[j_cont][3], 0] = (j_cont + 1) * 3
img_con_all[all_box_coord[j_cont][0]: all_box_coord[j_cont][1],
all_box_coord[j_cont][2]: all_box_coord[j_cont][3], 0] = (j_cont + 1) * 3
# img_con_all=cv2.fillPoly(img_con_all,pts=[contours_only_text_parent[j_cont]],color=((j_cont+1)*3,(j_cont+1)*3,(j_cont+1)*3))
# plt.imshow(img_con_all[:,:,0])
@ -85,14 +86,16 @@ def adhere_drop_capital_region_into_corresponding_textline(
sum_pixels_of_intersection = []
for i in range(len(region_with_intersected_drop)):
# print((region_with_intersected_drop[i]*3+1))
sum_pixels_of_intersection.append(((img_con_all_copy[:, :, 0] == (region_with_intersected_drop[i] * 3 + 1)) * 1).sum())
sum_pixels_of_intersection.append(
((img_con_all_copy[:, :, 0] == (region_with_intersected_drop[i] * 3 + 1)) * 1).sum())
# print(sum_pixels_of_intersection)
region_final = region_with_intersected_drop[np.argmax(sum_pixels_of_intersection)] - 1
# print(region_final,'region_final')
# cx_t,cy_t ,_, _, _ ,_,_= find_new_features_of_contours(all_found_textline_polygons[int(region_final)])
try:
cx_t, cy_t, _, _, _, _, _ = find_new_features_of_contours(all_found_textline_polygons[int(region_final)])
cx_t, cy_t, _, _, _, _, _ = find_new_features_of_contours(
all_found_textline_polygons[int(region_final)])
# print(all_box_coord[j_cont])
# print(cx_t)
# print(cy_t)
@ -109,12 +112,15 @@ def adhere_drop_capital_region_into_corresponding_textline(
# print(arg_min)
cnt_nearest = np.copy(all_found_textline_polygons[int(region_final)][arg_min])
cnt_nearest[:, 0, 0] = all_found_textline_polygons[int(region_final)][arg_min][:, 0, 0] # +all_box_coord[int(region_final)][2]
cnt_nearest[:, 0, 1] = all_found_textline_polygons[int(region_final)][arg_min][:, 0, 1] # +all_box_coord[int(region_final)][0]
cnt_nearest[:, 0, 0] = all_found_textline_polygons[int(region_final)][arg_min][:, 0,
0] # +all_box_coord[int(region_final)][2]
cnt_nearest[:, 0, 1] = all_found_textline_polygons[int(region_final)][arg_min][:, 0,
1] # +all_box_coord[int(region_final)][0]
img_textlines = np.zeros((text_regions_p.shape[0], text_regions_p.shape[1], 3))
img_textlines = cv2.fillPoly(img_textlines, pts=[cnt_nearest], color=(255, 255, 255))
img_textlines = cv2.fillPoly(img_textlines, pts=[polygons_of_drop_capitals[i_drop]], color=(255, 255, 255))
img_textlines = cv2.fillPoly(img_textlines, pts=[polygons_of_drop_capitals[i_drop]],
color=(255, 255, 255))
img_textlines = img_textlines.astype(np.uint8)
@ -128,7 +134,8 @@ def adhere_drop_capital_region_into_corresponding_textline(
#contours_combined, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
areas_cnt_text = np.array([cv2.contourArea(contours_combined[j]) for j in range(len(contours_combined))])
areas_cnt_text = np.array(
[cv2.contourArea(contours_combined[j]) for j in range(len(contours_combined))])
contours_biggest = contours_combined[np.argmax(areas_cnt_text)]
@ -142,7 +149,8 @@ def adhere_drop_capital_region_into_corresponding_textline(
if len(contours_combined) == 1:
all_found_textline_polygons[int(region_final)][arg_min] = contours_biggest
elif len(contours_combined) == 2:
all_found_textline_polygons[int(region_final)].insert(arg_min, polygons_of_drop_capitals[i_drop] )
all_found_textline_polygons[int(region_final)].insert(arg_min,
polygons_of_drop_capitals[i_drop])
else:
pass
@ -156,7 +164,8 @@ def adhere_drop_capital_region_into_corresponding_textline(
# cx_t,cy_t ,_, _, _ ,_,_= find_new_features_of_contours(all_found_textline_polygons[int(region_final)])
try:
cx_t, cy_t, _, _, _, _, _ = find_new_features_of_contours(all_found_textline_polygons[int(region_final)])
cx_t, cy_t, _, _, _, _, _ = find_new_features_of_contours(
all_found_textline_polygons[int(region_final)])
# print(all_box_coord[j_cont])
# print(cx_t)
# print(cy_t)
@ -171,23 +180,26 @@ def adhere_drop_capital_region_into_corresponding_textline(
# print(arg_min)
cnt_nearest = np.copy(all_found_textline_polygons[int(region_final)][arg_min])
cnt_nearest[:, 0, 0] = all_found_textline_polygons[int(region_final)][arg_min][:, 0, 0] # +all_box_coord[int(region_final)][2]
cnt_nearest[:, 0, 1] = all_found_textline_polygons[int(region_final)][arg_min][:, 0, 1] # +all_box_coord[int(region_final)][0]
cnt_nearest[:, 0, 0] = all_found_textline_polygons[int(region_final)][arg_min][:, 0,
0] # +all_box_coord[int(region_final)][2]
cnt_nearest[:, 0, 1] = all_found_textline_polygons[int(region_final)][arg_min][:, 0,
1] # +all_box_coord[int(region_final)][0]
img_textlines = np.zeros((text_regions_p.shape[0], text_regions_p.shape[1], 3))
img_textlines = cv2.fillPoly(img_textlines, pts=[cnt_nearest], color=(255, 255, 255))
img_textlines = cv2.fillPoly(img_textlines, pts=[polygons_of_drop_capitals[i_drop]], color=(255, 255, 255))
img_textlines = cv2.fillPoly(img_textlines, pts=[polygons_of_drop_capitals[i_drop]],
color=(255, 255, 255))
img_textlines = img_textlines.astype(np.uint8)
contours_combined = return_contours_of_interested_region(img_textlines, 255, 0)
##imgray = cv2.cvtColor(img_textlines, cv2.COLOR_BGR2GRAY)
##ret, thresh = cv2.threshold(imgray, 0, 255, 0)
##contours_combined, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
areas_cnt_text = np.array([cv2.contourArea(contours_combined[j]) for j in range(len(contours_combined))])
areas_cnt_text = np.array(
[cv2.contourArea(contours_combined[j]) for j in range(len(contours_combined))])
contours_biggest = contours_combined[np.argmax(areas_cnt_text)]
@ -201,7 +213,8 @@ def adhere_drop_capital_region_into_corresponding_textline(
if len(contours_combined) == 1:
all_found_textline_polygons[int(region_final)][arg_min] = contours_biggest
elif len(contours_combined) == 2:
all_found_textline_polygons[int(region_final)].insert(arg_min, polygons_of_drop_capitals[i_drop] )
all_found_textline_polygons[int(region_final)].insert(arg_min,
polygons_of_drop_capitals[i_drop])
else:
pass
except:
@ -209,7 +222,8 @@ def adhere_drop_capital_region_into_corresponding_textline(
try:
# print(all_found_textline_polygons[j_cont][0])
cx_t, cy_t, _, _, _, _, _ = find_new_features_of_contours(all_found_textline_polygons[int(region_final)])
cx_t, cy_t, _, _, _, _, _ = find_new_features_of_contours(
all_found_textline_polygons[int(region_final)])
# print(all_box_coord[j_cont])
# print(cx_t)
# print(cy_t)
@ -224,12 +238,15 @@ def adhere_drop_capital_region_into_corresponding_textline(
# print(arg_min)
cnt_nearest = np.copy(all_found_textline_polygons[int(region_final)][arg_min])
cnt_nearest[:, 0, 0] = all_found_textline_polygons[int(region_final)][arg_min][:, 0, 0] # +all_box_coord[int(region_final)][2]
cnt_nearest[:, 0, 1] = all_found_textline_polygons[int(region_final)][arg_min][:, 0, 1] # +all_box_coord[int(region_final)][0]
cnt_nearest[:, 0, 0] = all_found_textline_polygons[int(region_final)][arg_min][:, 0,
0] # +all_box_coord[int(region_final)][2]
cnt_nearest[:, 0, 1] = all_found_textline_polygons[int(region_final)][arg_min][:, 0,
1] # +all_box_coord[int(region_final)][0]
img_textlines = np.zeros((text_regions_p.shape[0], text_regions_p.shape[1], 3))
img_textlines = cv2.fillPoly(img_textlines, pts=[cnt_nearest], color=(255, 255, 255))
img_textlines = cv2.fillPoly(img_textlines, pts=[polygons_of_drop_capitals[i_drop]], color=(255, 255, 255))
img_textlines = cv2.fillPoly(img_textlines, pts=[polygons_of_drop_capitals[i_drop]],
color=(255, 255, 255))
img_textlines = img_textlines.astype(np.uint8)
contours_combined = return_contours_of_interested_region(img_textlines, 255, 0)
@ -239,7 +256,8 @@ def adhere_drop_capital_region_into_corresponding_textline(
#contours_combined, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# print(len(contours_combined),'len textlines mixed')
areas_cnt_text = np.array([cv2.contourArea(contours_combined[j]) for j in range(len(contours_combined))])
areas_cnt_text = np.array(
[cv2.contourArea(contours_combined[j]) for j in range(len(contours_combined))])
contours_biggest = contours_combined[np.argmax(areas_cnt_text)]
@ -252,7 +270,8 @@ def adhere_drop_capital_region_into_corresponding_textline(
if len(contours_combined) == 1:
all_found_textline_polygons[int(region_final)][arg_min] = contours_biggest
elif len(contours_combined) == 2:
all_found_textline_polygons[int(region_final)].insert(arg_min, polygons_of_drop_capitals[i_drop] )
all_found_textline_polygons[int(region_final)].insert(arg_min,
polygons_of_drop_capitals[i_drop])
else:
pass
# all_found_textline_polygons[int(region_final)][arg_min]=contours_biggest
@ -311,14 +330,16 @@ def adhere_drop_capital_region_into_corresponding_textline(
sum_pixels_of_intersection = []
for i in range(len(region_with_intersected_drop)):
# print((region_with_intersected_drop[i]*3+1))
sum_pixels_of_intersection.append(((img_con_all_copy[:, :, 0] == (region_with_intersected_drop[i] * 3 + 1)) * 1).sum())
sum_pixels_of_intersection.append(
((img_con_all_copy[:, :, 0] == (region_with_intersected_drop[i] * 3 + 1)) * 1).sum())
# print(sum_pixels_of_intersection)
region_final = region_with_intersected_drop[np.argmax(sum_pixels_of_intersection)] - 1
# print(region_final,'region_final')
# cx_t,cy_t ,_, _, _ ,_,_= find_new_features_of_contours(all_found_textline_polygons[int(region_final)])
try:
cx_t, cy_t, _, _, _, _, _ = find_new_features_of_contours(all_found_textline_polygons[int(region_final)])
cx_t, cy_t, _, _, _, _, _ = find_new_features_of_contours(
all_found_textline_polygons[int(region_final)])
# print(all_box_coord[j_cont])
# print(cx_t)
# print(cy_t)
@ -335,12 +356,15 @@ def adhere_drop_capital_region_into_corresponding_textline(
# print(arg_min)
cnt_nearest = np.copy(all_found_textline_polygons[int(region_final)][arg_min])
cnt_nearest[:, 0] = all_found_textline_polygons[int(region_final)][arg_min][:, 0] + all_box_coord[int(region_final)][2]
cnt_nearest[:, 1] = all_found_textline_polygons[int(region_final)][arg_min][:, 1] + all_box_coord[int(region_final)][0]
cnt_nearest[:, 0] = all_found_textline_polygons[int(region_final)][arg_min][:, 0] + \
all_box_coord[int(region_final)][2]
cnt_nearest[:, 1] = all_found_textline_polygons[int(region_final)][arg_min][:, 1] + \
all_box_coord[int(region_final)][0]
img_textlines = np.zeros((text_regions_p.shape[0], text_regions_p.shape[1], 3))
img_textlines = cv2.fillPoly(img_textlines, pts=[cnt_nearest], color=(255, 255, 255))
img_textlines = cv2.fillPoly(img_textlines, pts=[polygons_of_drop_capitals[i_drop]], color=(255, 255, 255))
img_textlines = cv2.fillPoly(img_textlines, pts=[polygons_of_drop_capitals[i_drop]],
color=(255, 255, 255))
img_textlines = img_textlines.astype(np.uint8)
contours_combined = return_contours_of_interested_region(img_textlines, 255, 0)
@ -351,7 +375,8 @@ def adhere_drop_capital_region_into_corresponding_textline(
#contours_combined, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# print(len(contours_combined),'len textlines mixed')
areas_cnt_text = np.array([cv2.contourArea(contours_combined[j]) for j in range(len(contours_combined))])
areas_cnt_text = np.array(
[cv2.contourArea(contours_combined[j]) for j in range(len(contours_combined))])
contours_biggest = contours_combined[np.argmax(areas_cnt_text)]
@ -360,11 +385,13 @@ def adhere_drop_capital_region_into_corresponding_textline(
contours_biggest[:, 0, 0] = contours_biggest[:, 0, 0] - all_box_coord[int(region_final)][2]
contours_biggest[:, 0, 1] = contours_biggest[:, 0, 1] - all_box_coord[int(region_final)][0]
contours_biggest = contours_biggest.reshape(np.shape(contours_biggest)[0], np.shape(contours_biggest)[2])
contours_biggest = contours_biggest.reshape(np.shape(contours_biggest)[0],
np.shape(contours_biggest)[2])
if len(contours_combined) == 1:
all_found_textline_polygons[int(region_final)][arg_min] = contours_biggest
elif len(contours_combined) == 2:
all_found_textline_polygons[int(region_final)].insert(arg_min, polygons_of_drop_capitals[i_drop] )
all_found_textline_polygons[int(region_final)].insert(arg_min,
polygons_of_drop_capitals[i_drop])
else:
pass
@ -381,7 +408,8 @@ def adhere_drop_capital_region_into_corresponding_textline(
# print(cx_t,'print')
try:
# print(all_found_textline_polygons[j_cont][0])
cx_t, cy_t, _, _, _, _, _ = find_new_features_of_contours(all_found_textline_polygons[int(region_final)])
cx_t, cy_t, _, _, _, _, _ = find_new_features_of_contours(
all_found_textline_polygons[int(region_final)])
# print(all_box_coord[j_cont])
# print(cx_t)
# print(cy_t)
@ -396,12 +424,15 @@ def adhere_drop_capital_region_into_corresponding_textline(
# print(arg_min)
cnt_nearest = np.copy(all_found_textline_polygons[int(region_final)][arg_min])
cnt_nearest[:, 0] = all_found_textline_polygons[int(region_final)][arg_min][:, 0] + all_box_coord[int(region_final)][2]
cnt_nearest[:, 1] = all_found_textline_polygons[int(region_final)][arg_min][:, 1] + all_box_coord[int(region_final)][0]
cnt_nearest[:, 0] = all_found_textline_polygons[int(region_final)][arg_min][:, 0] + \
all_box_coord[int(region_final)][2]
cnt_nearest[:, 1] = all_found_textline_polygons[int(region_final)][arg_min][:, 1] + \
all_box_coord[int(region_final)][0]
img_textlines = np.zeros((text_regions_p.shape[0], text_regions_p.shape[1], 3))
img_textlines = cv2.fillPoly(img_textlines, pts=[cnt_nearest], color=(255, 255, 255))
img_textlines = cv2.fillPoly(img_textlines, pts=[polygons_of_drop_capitals[i_drop]], color=(255, 255, 255))
img_textlines = cv2.fillPoly(img_textlines, pts=[polygons_of_drop_capitals[i_drop]],
color=(255, 255, 255))
img_textlines = img_textlines.astype(np.uint8)
contours_combined = return_contours_of_interested_region(img_textlines, 255, 0)
@ -412,7 +443,8 @@ def adhere_drop_capital_region_into_corresponding_textline(
#contours_combined, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# print(len(contours_combined),'len textlines mixed')
areas_cnt_text = np.array([cv2.contourArea(contours_combined[j]) for j in range(len(contours_combined))])
areas_cnt_text = np.array(
[cv2.contourArea(contours_combined[j]) for j in range(len(contours_combined))])
contours_biggest = contours_combined[np.argmax(areas_cnt_text)]
@ -421,11 +453,13 @@ def adhere_drop_capital_region_into_corresponding_textline(
contours_biggest[:, 0, 0] = contours_biggest[:, 0, 0] - all_box_coord[int(region_final)][2]
contours_biggest[:, 0, 1] = contours_biggest[:, 0, 1] - all_box_coord[int(region_final)][0]
contours_biggest = contours_biggest.reshape(np.shape(contours_biggest)[0], np.shape(contours_biggest)[2])
contours_biggest = contours_biggest.reshape(np.shape(contours_biggest)[0],
np.shape(contours_biggest)[2])
if len(contours_combined) == 1:
all_found_textline_polygons[int(region_final)][arg_min] = contours_biggest
elif len(contours_combined) == 2:
all_found_textline_polygons[int(region_final)].insert(arg_min, polygons_of_drop_capitals[i_drop] )
all_found_textline_polygons[int(region_final)].insert(arg_min,
polygons_of_drop_capitals[i_drop])
else:
pass
# all_found_textline_polygons[int(region_final)][arg_min]=contours_biggest
@ -502,7 +536,6 @@ def adhere_drop_capital_region_into_corresponding_textline(
def filter_small_drop_capitals_from_no_patch_layout(layout_no_patch, layout1):
drop_only = (layout_no_patch[:, :, 0] == 4) * 1
contours_drop, hir_on_drop = return_contours_of_image(drop_only)
contours_drop_parent = return_parent_contours(contours_drop, hir_on_drop)
@ -510,7 +543,8 @@ def filter_small_drop_capitals_from_no_patch_layout(layout_no_patch, layout1):
areas_cnt_text = np.array([cv2.contourArea(contours_drop_parent[j]) for j in range(len(contours_drop_parent))])
areas_cnt_text = areas_cnt_text / float(drop_only.shape[0] * drop_only.shape[1])
contours_drop_parent = [contours_drop_parent[jz] for jz in range(len(contours_drop_parent)) if areas_cnt_text[jz] > 0.001]
contours_drop_parent = [contours_drop_parent[jz] for jz in range(len(contours_drop_parent)) if
areas_cnt_text[jz] > 0.001]
areas_cnt_text = [areas_cnt_text[jz] for jz in range(len(areas_cnt_text)) if areas_cnt_text[jz] > 0.001]
@ -520,7 +554,8 @@ def filter_small_drop_capitals_from_no_patch_layout(layout_no_patch, layout1):
x, y, w, h = cv2.boundingRect(contours_drop_parent[jj])
# boxes.append([int(x), int(y), int(w), int(h)])
iou_of_box_and_contoure = float(drop_only.shape[0] * drop_only.shape[1]) * areas_cnt_text[jj] / float(w * h) * 100
iou_of_box_and_contoure = float(drop_only.shape[0] * drop_only.shape[1]) * areas_cnt_text[jj] / float(
w * h) * 100
height_to_weight_ratio = h / float(w)
weigh_to_height_ratio = w / float(h)
@ -528,7 +563,8 @@ def filter_small_drop_capitals_from_no_patch_layout(layout_no_patch, layout1):
map_of_drop_contour_bb = np.zeros((layout1.shape[0], layout1.shape[1]))
map_of_drop_contour_bb[y: y + h, x: x + w] = layout1[y: y + h, x: x + w]
if (((map_of_drop_contour_bb == 1) * 1).sum() / float(((map_of_drop_contour_bb == 5) * 1).sum()) * 100) >= 15:
if (((map_of_drop_contour_bb == 1) * 1).sum() / float(
((map_of_drop_contour_bb == 5) * 1).sum()) * 100) >= 15:
contours_drop_parent_final.append(contours_drop_parent[jj])
layout_no_patch[:, :, 0][layout_no_patch[:, :, 0] == 4] = 0
@ -536,4 +572,3 @@ def filter_small_drop_capitals_from_no_patch_layout(layout_no_patch, layout1):
layout_no_patch = cv2.fillPoly(layout_no_patch, pts=contours_drop_parent_final, color=(4, 4, 4))
return layout_no_patch

@ -11,7 +11,6 @@ def get_marginals(text_with_lines, text_regions, num_col, slope_deskew, light_ve
mask_marginals = np.zeros((text_with_lines.shape[0], text_with_lines.shape[1]))
mask_marginals = mask_marginals.astype(np.uint8)
text_with_lines = text_with_lines.astype(np.uint8)
##text_with_lines=cv2.erode(text_with_lines,self.kernel,iterations=3)
@ -22,12 +21,13 @@ def get_marginals(text_with_lines, text_regions, num_col, slope_deskew, light_ve
elif 1500 < text_with_lines.shape[0] <= 1800:
text_with_lines = resize_image(text_with_lines, int(text_with_lines.shape[0] * 1.5), text_with_lines.shape[1])
text_with_lines = cv2.erode(text_with_lines, kernel, iterations=5)
text_with_lines=resize_image(text_with_lines,text_with_lines_eroded.shape[0],text_with_lines_eroded.shape[1])
text_with_lines = resize_image(text_with_lines, text_with_lines_eroded.shape[0],
text_with_lines_eroded.shape[1])
else:
text_with_lines = resize_image(text_with_lines, int(text_with_lines.shape[0] * 1.8), text_with_lines.shape[1])
text_with_lines = cv2.erode(text_with_lines, kernel, iterations=7)
text_with_lines=resize_image(text_with_lines,text_with_lines_eroded.shape[0],text_with_lines_eroded.shape[1])
text_with_lines = resize_image(text_with_lines, text_with_lines_eroded.shape[0],
text_with_lines_eroded.shape[1])
text_with_lines_y = text_with_lines.sum(axis=0)
text_with_lines_y_eroded = text_with_lines_eroded.sum(axis=0)
@ -43,8 +43,6 @@ def get_marginals(text_with_lines, text_regions, num_col, slope_deskew, light_ve
else:
min_textline_thickness = 40
if thickness_along_y_percent >= 14:
text_with_lines_y_rev = -1 * text_with_lines_y[:]
@ -61,12 +59,10 @@ def get_marginals(text_with_lines, text_regions, num_col, slope_deskew, light_ve
first_nonzero = (next((i for i, x in enumerate(region_sum_0) if x), None))
last_nonzero = (next((i for i, x in enumerate(region_sum_0_updown) if x), None))
last_nonzero = len(region_sum_0) - last_nonzero
mid_point = (last_nonzero + first_nonzero) / 2.
one_third_right = (last_nonzero - mid_point) / 3.0
one_third_left = (mid_point - first_nonzero) / 3.0
@ -75,7 +71,6 @@ def get_marginals(text_with_lines, text_regions, num_col, slope_deskew, light_ve
peaks = peaks[(peaks > first_nonzero) & (peaks < last_nonzero)]
peaks = peaks[region_sum_0[peaks] < min_textline_thickness]
if num_col == 1:
peaks_right = peaks[peaks > mid_point]
peaks_left = peaks[peaks < mid_point]
@ -83,20 +78,16 @@ def get_marginals(text_with_lines, text_regions, num_col, slope_deskew, light_ve
peaks_right = peaks[peaks > (mid_point + one_third_right)]
peaks_left = peaks[peaks < (mid_point - one_third_left)]
try:
point_right = np.min(peaks_right)
except:
point_right = last_nonzero
try:
point_left = np.max(peaks_left)
except:
point_left = first_nonzero
if point_right >= mask_marginals.shape[1]:
point_right = mask_marginals.shape[1] - 1
@ -135,7 +126,8 @@ def get_marginals(text_with_lines, text_regions, num_col, slope_deskew, light_ve
polygons_of_marginals = return_contours_of_interested_region(text_regions, pixel_img, min_area_text)
cx_text_only,cy_text_only ,x_min_text_only,x_max_text_only, y_min_text_only ,y_max_text_only,y_cor_x_min_main=find_new_features_of_contours(polygons_of_marginals)
cx_text_only, cy_text_only, x_min_text_only, x_max_text_only, y_min_text_only, y_max_text_only, y_cor_x_min_main = find_new_features_of_contours(
polygons_of_marginals)
text_regions[(text_regions[:, :] == 4)] = 1
@ -145,17 +137,15 @@ def get_marginals(text_with_lines, text_regions, num_col, slope_deskew, light_ve
x_min_marginals_right = []
for i in range(len(cx_text_only)):
results = cv2.pointPolygonTest(polygon_mask_marginals_rotated, (cx_text_only[i], cy_text_only[i]), False)
results = cv2.pointPolygonTest(polygon_mask_marginals_rotated, (cx_text_only[i], cy_text_only[i]),
False)
if results == -1:
marginlas_should_be_main_text.append(polygons_of_marginals[i])
text_regions_org = cv2.fillPoly(text_regions_org, pts=marginlas_should_be_main_text, color=(4, 4))
text_regions = np.copy(text_regions_org)
else:
text_regions[(mask_marginals_rotated[:, :] != 1) & (text_regions[:, :] == 1)] = 4
@ -165,7 +155,8 @@ def get_marginals(text_with_lines, text_regions, num_col, slope_deskew, light_ve
polygons_of_marginals = return_contours_of_interested_region(text_regions, pixel_img, min_area_text)
cx_text_only,cy_text_only ,x_min_text_only,x_max_text_only, y_min_text_only ,y_max_text_only,y_cor_x_min_main=find_new_features_of_contours(polygons_of_marginals)
cx_text_only, cy_text_only, x_min_text_only, x_max_text_only, y_min_text_only, y_max_text_only, y_cor_x_min_main = find_new_features_of_contours(
polygons_of_marginals)
text_regions[(text_regions[:, :] == 4)] = 1
@ -198,16 +189,15 @@ def get_marginals(text_with_lines, text_regions, num_col, slope_deskew, light_ve
if len(x_min_marginals_right) == 0:
x_min_marginals_right = [text_regions.shape[1] - 1]
text_regions = cv2.fillPoly(text_regions, pts=marginlas_should_be_main_text, color=(4, 4))
#text_regions[:,:int(x_min_marginals_left[0])][text_regions[:,:int(x_min_marginals_left[0])]==1]=0
#text_regions[:,int(x_min_marginals_right[0]):][text_regions[:,int(x_min_marginals_right[0]):]==1]=0
text_regions[:,:int(min_point_of_left_marginal)][text_regions[:,:int(min_point_of_left_marginal)]==1]=0
text_regions[:,int(max_point_of_right_marginal):][text_regions[:,int(max_point_of_right_marginal):]==1]=0
text_regions[:, :int(min_point_of_left_marginal)][
text_regions[:, :int(min_point_of_left_marginal)] == 1] = 0
text_regions[:, int(max_point_of_right_marginal):][
text_regions[:, int(max_point_of_right_marginal):] == 1] = 0
###text_regions[:,0:point_left][text_regions[:,0:point_left]==1]=4
@ -216,7 +206,6 @@ def get_marginals(text_with_lines, text_regions, num_col, slope_deskew, light_ve
#plt.plot(peaks,region_sum_0[peaks],'*')
#plt.show()
#plt.imshow(text_regions)
#plt.show()

@ -3,6 +3,7 @@ import numpy as np
from ocrd_models import OcrdExif
from cv2 import COLOR_GRAY2BGR, COLOR_RGB2BGR, COLOR_BGR2RGB, cvtColor, imread
# from sbb_binarization

@ -65,7 +65,8 @@ def rotate_max_area(image, rotated, rotated_textline, rotated_layout, rotated_ta
y2 = y1 + int(hr)
x1 = w // 2 - int(wr / 2)
x2 = x1 + int(wr)
return rotated[y1:y2, x1:x2], rotated_textline[y1:y2, x1:x2], rotated_layout[y1:y2, x1:x2], rotated_table_prediction[y1:y2, x1:x2]
return rotated[y1:y2, x1:x2], rotated_textline[y1:y2, x1:x2], rotated_layout[y1:y2,
x1:x2], rotated_table_prediction[y1:y2, x1:x2]
def rotation_not_90_func(img, textline, text_regions_p_1, table_prediction, thetha):
@ -91,5 +92,5 @@ def rotate_max_area_full_layout(image, rotated, rotated_textline, rotated_layout
y2 = y1 + int(hr)
x1 = w // 2 - int(wr / 2)
x2 = x1 + int(wr)
return rotated[y1:y2, x1:x2], rotated_textline[y1:y2, x1:x2], rotated_layout[y1:y2, x1:x2], rotated_layout_full[y1:y2, x1:x2]
return rotated[y1:y2, x1:x2], rotated_textline[y1:y2, x1:x2], rotated_layout[y1:y2, x1:x2], rotated_layout_full[
y1:y2, x1:x2]

@ -63,7 +63,8 @@ def dedup_separate_lines(img_patch, contour_text_interest, thetha, axis):
peaks_neg_e, _ = find_peaks(y_padded_up_to_down_padded_e, height=0)
neg_peaks_max = np.max(y_padded_up_to_down_padded_e[peaks_neg_e])
arg_neg_must_be_deleted = np.arange(len(peaks_neg_e))[y_padded_up_to_down_padded_e[peaks_neg_e] / float(neg_peaks_max) < 0.3]
arg_neg_must_be_deleted = np.arange(len(peaks_neg_e))[
y_padded_up_to_down_padded_e[peaks_neg_e] / float(neg_peaks_max) < 0.3]
diff_arg_neg_must_be_deleted = np.diff(arg_neg_must_be_deleted)
arg_diff = np.array(range(len(diff_arg_neg_must_be_deleted)))
@ -172,12 +173,12 @@ def separate_lines(img_patch, contour_text_interest, thetha, x_help, y_help):
y_padded_up_to_down_padded_e[20:len(y_padded_up_to_down_e) + 20] = y_padded_up_to_down_e
y_padded_up_to_down_padded_e = gaussian_filter1d(y_padded_up_to_down_padded_e, 2)
peaks_e, _ = find_peaks(y_padded_smoothed_e, height=0)
peaks_neg_e, _ = find_peaks(y_padded_up_to_down_padded_e, height=0)
neg_peaks_max = np.max(y_padded_up_to_down_padded_e[peaks_neg_e])
arg_neg_must_be_deleted= np.arange(len(peaks_neg_e))[y_padded_up_to_down_padded_e[peaks_neg_e]/float(neg_peaks_max)<0.3]
arg_neg_must_be_deleted = np.arange(len(peaks_neg_e))[
y_padded_up_to_down_padded_e[peaks_neg_e] / float(neg_peaks_max) < 0.3]
diff_arg_neg_must_be_deleted = np.diff(arg_neg_must_be_deleted)
arg_diff = np.array(range(len(diff_arg_neg_must_be_deleted)))
@ -236,7 +237,8 @@ def separate_lines(img_patch, contour_text_interest, thetha, x_help, y_help):
try:
neg_peaks_max = np.max(y_padded_smoothed[peaks])
arg_neg_must_be_deleted= np.arange(len(peaks_neg))[y_padded_up_to_down_padded[peaks_neg]/float(neg_peaks_max)<0.42]
arg_neg_must_be_deleted = np.arange(len(peaks_neg))[
y_padded_up_to_down_padded[peaks_neg] / float(neg_peaks_max) < 0.42]
diff_arg_neg_must_be_deleted = np.diff(arg_neg_must_be_deleted)
arg_diff = np.array(range(len(diff_arg_neg_must_be_deleted)))
@ -339,20 +341,22 @@ def separate_lines(img_patch, contour_text_interest, thetha, x_help, y_help):
if peaks_values[jj] > mean_value_of_peaks - std_value_of_peaks / 2.:
point_up = peaks[jj] + first_nonzero - int(1.1 * dis_to_next_up) ##+int(dis_to_next_up*1./4.0)
point_down = peaks[jj] + first_nonzero + int(1.1 * dis_to_next_down) ###-int(dis_to_next_down*1./4.0)
point_down = peaks[jj] + first_nonzero + int(
1.1 * dis_to_next_down) ###-int(dis_to_next_down*1./4.0)
else:
point_up = peaks[jj] + first_nonzero - int(1.23 * dis_to_next_up) ##+int(dis_to_next_up*1./4.0)
point_down = peaks[jj] + first_nonzero + int(1.33 * dis_to_next_down) ###-int(dis_to_next_down*1./4.0)
point_down = peaks[jj] + first_nonzero + int(
1.33 * dis_to_next_down) ###-int(dis_to_next_down*1./4.0)
point_down_narrow = peaks[jj] + first_nonzero + int(
1.1 * dis_to_next_down) ###-int(dis_to_next_down*1./2)
if point_down_narrow >= img_patch.shape[0]:
point_down_narrow = img_patch.shape[0] - 2
distances = [cv2.pointPolygonTest(contour_text_interest_copy, tuple(int(x) for x in np.array([xv[mj], peaks[jj] + first_nonzero])), True)
distances = [cv2.pointPolygonTest(contour_text_interest_copy,
tuple(int(x) for x in np.array([xv[mj], peaks[jj] + first_nonzero])),
True)
for mj in range(len(xv))]
distances = np.array(distances)
@ -479,7 +483,8 @@ def separate_lines(img_patch, contour_text_interest, thetha, x_help, y_help):
point_up = peaks[jj] + first_nonzero - int(1. / 1.8 * dis_to_next)
distances = [cv2.pointPolygonTest(contour_text_interest_copy,
tuple(int(x) for x in np.array([xv[mj], peaks[jj] + first_nonzero])), True)
tuple(int(x) for x in np.array([xv[mj], peaks[jj] + first_nonzero])),
True)
for mj in range(len(xv))]
distances = np.array(distances)
@ -554,7 +559,8 @@ def separate_lines(img_patch, contour_text_interest, thetha, x_help, y_help):
point_down = peaks[jj] + first_nonzero + int(1. / 1.9 * dis_to_next_down)
distances = [cv2.pointPolygonTest(contour_text_interest_copy,
tuple(int(x) for x in np.array([xv[mj], peaks[jj] + first_nonzero])), True)
tuple(int(x) for x in np.array([xv[mj], peaks[jj] + first_nonzero])),
True)
for mj in range(len(xv))]
distances = np.array(distances)
@ -626,7 +632,8 @@ def separate_lines_vertical(img_patch, contour_text_interest, thetha):
neg_peaks_max = np.max(y_padded_up_to_down_padded[peaks_neg])
arg_neg_must_be_deleted = np.arange(len(peaks_neg))[y_padded_up_to_down_padded[peaks_neg] / float(neg_peaks_max) < 0.42]
arg_neg_must_be_deleted = np.arange(len(peaks_neg))[
y_padded_up_to_down_padded[peaks_neg] / float(neg_peaks_max) < 0.42]
diff_arg_neg_must_be_deleted = np.diff(arg_neg_must_be_deleted)
arg_diff = np.array(range(len(diff_arg_neg_must_be_deleted)))
@ -704,24 +711,30 @@ def separate_lines_vertical(img_patch, contour_text_interest, thetha):
point_up = peaks[jj] + first_nonzero - int(1.4 * dis_to_next_up) ##+int(dis_to_next_up*1./4.0)
point_down = x_max_cont - 1 ##peaks[jj] + first_nonzero + int(1.6 * dis_to_next_down) #point_up# np.max(y_cont)#peaks[jj] + first_nonzero + int(1.4 * dis_to_next_down) ###-int(dis_to_next_down*1./4.0)
point_down_narrow = peaks[jj] + first_nonzero + int(1.4 * dis_to_next_down) ###-int(dis_to_next_down*1./2)
point_down_narrow = peaks[jj] + first_nonzero + int(
1.4 * dis_to_next_down) ###-int(dis_to_next_down*1./2)
else:
dis_to_next_up = abs(peaks[jj] - peaks_neg[jj])
dis_to_next_down = abs(peaks[jj] - peaks_neg[jj + 1])
if peaks_values[jj] > mean_value_of_peaks - std_value_of_peaks / 2.0:
point_up = peaks[jj] + first_nonzero - int(1.1 * dis_to_next_up) ##+int(dis_to_next_up*1./4.0)
point_down = peaks[jj] + first_nonzero + int(1.1 * dis_to_next_down) ###-int(dis_to_next_down*1./4.0)
point_down = peaks[jj] + first_nonzero + int(
1.1 * dis_to_next_down) ###-int(dis_to_next_down*1./4.0)
else:
point_up = peaks[jj] + first_nonzero - int(1.23 * dis_to_next_up) ##+int(dis_to_next_up*1./4.0)
point_down = peaks[jj] + first_nonzero + int(1.33 * dis_to_next_down) ###-int(dis_to_next_down*1./4.0)
point_down = peaks[jj] + first_nonzero + int(
1.33 * dis_to_next_down) ###-int(dis_to_next_down*1./4.0)
point_down_narrow = peaks[jj] + first_nonzero + int(1.1 * dis_to_next_down) ###-int(dis_to_next_down*1./2)
point_down_narrow = peaks[jj] + first_nonzero + int(
1.1 * dis_to_next_down) ###-int(dis_to_next_down*1./2)
if point_down_narrow >= img_patch.shape[0]:
point_down_narrow = img_patch.shape[0] - 2
distances = [cv2.pointPolygonTest(contour_text_interest_copy, tuple(int(x) for x in np.array([xv[mj], peaks[jj] + first_nonzero])), True) for mj in range(len(xv))]
distances = [cv2.pointPolygonTest(contour_text_interest_copy,
tuple(int(x) for x in np.array([xv[mj], peaks[jj] + first_nonzero])),
True) for mj in range(len(xv))]
distances = np.array(distances)
xvinside = xv[distances >= 0]
@ -810,7 +823,8 @@ def separate_lines_vertical(img_patch, contour_text_interest, thetha):
point_up = peaks[jj] + first_nonzero - int(1.0 / 1.8 * dis_to_next)
distances = [cv2.pointPolygonTest(contour_text_interest_copy,
tuple(int(x) for x in np.array([xv[mj], peaks[jj] + first_nonzero])), True)
tuple(int(x) for x in np.array([xv[mj], peaks[jj] + first_nonzero])),
True)
for mj in range(len(xv))]
distances = np.array(distances)
@ -875,7 +889,8 @@ def separate_lines_vertical(img_patch, contour_text_interest, thetha):
point_down = peaks[jj] + first_nonzero + int(1.0 / 1.9 * dis_to_next_down)
distances = [cv2.pointPolygonTest(contour_text_interest_copy,
tuple(int(x) for x in np.array([xv[mj], peaks[jj] + first_nonzero])), True)
tuple(int(x) for x in np.array([xv[mj], peaks[jj] + first_nonzero])),
True)
for mj in range(len(xv))]
distances = np.array(distances)
@ -960,7 +975,8 @@ def separate_lines_new_inside_tiles2(img_patch, thetha):
peaks_neg_e, _ = find_peaks(y_padded_up_to_down_padded_e, height=0)
neg_peaks_max = np.max(y_padded_up_to_down_padded_e[peaks_neg_e])
arg_neg_must_be_deleted = np.arange(len(peaks_neg_e))[y_padded_up_to_down_padded_e[peaks_neg_e] / float(neg_peaks_max) < 0.3]
arg_neg_must_be_deleted = np.arange(len(peaks_neg_e))[
y_padded_up_to_down_padded_e[peaks_neg_e] / float(neg_peaks_max) < 0.3]
diff_arg_neg_must_be_deleted = np.diff(arg_neg_must_be_deleted)
arg_diff = np.array(range(len(diff_arg_neg_must_be_deleted)))
@ -973,7 +989,8 @@ def separate_lines_new_inside_tiles2(img_patch, thetha):
if len(arg_diff_cluster) > 0:
clusters_to_be_deleted.append(arg_neg_must_be_deleted[0: arg_diff_cluster[0] + 1])
for i in range(len(arg_diff_cluster) - 1):
clusters_to_be_deleted.append(arg_neg_must_be_deleted[arg_diff_cluster[i] + 1 : arg_diff_cluster[i + 1] + 1])
clusters_to_be_deleted.append(
arg_neg_must_be_deleted[arg_diff_cluster[i] + 1: arg_diff_cluster[i + 1] + 1])
clusters_to_be_deleted.append(arg_neg_must_be_deleted[arg_diff_cluster[len(arg_diff_cluster) - 1] + 1:])
if len(clusters_to_be_deleted) > 0:
peaks_new_extra = []
@ -1023,7 +1040,8 @@ def separate_lines_new_inside_tiles2(img_patch, thetha):
try:
neg_peaks_max = np.max(y_padded_smoothed[peaks])
arg_neg_must_be_deleted = np.arange(len(peaks_neg))[y_padded_up_to_down_padded[peaks_neg] / float(neg_peaks_max) < 0.24]
arg_neg_must_be_deleted = np.arange(len(peaks_neg))[
y_padded_up_to_down_padded[peaks_neg] / float(neg_peaks_max) < 0.24]
diff_arg_neg_must_be_deleted = np.diff(arg_neg_must_be_deleted)
arg_diff = np.array(range(len(diff_arg_neg_must_be_deleted)))
@ -1118,6 +1136,7 @@ def separate_lines_new_inside_tiles2(img_patch, thetha):
img_patch = cv2.erode(img_patch, kernel, iterations=1)
return img_patch
def separate_lines_new_inside_tiles(img_path, thetha):
(h, w) = img_path.shape[:2]
center = (w // 2, h // 2)
@ -1305,7 +1324,8 @@ def separate_lines_vertical_cont(img_patch, contour_text_interest, thetha, box_i
return None, cont_final
def textline_contours_postprocessing(textline_mask, slope, contour_text_interest, box_ind, add_boxes_coor_into_textlines=False):
def textline_contours_postprocessing(textline_mask, slope, contour_text_interest, box_ind,
add_boxes_coor_into_textlines=False):
textline_mask = np.repeat(textline_mask[:, :, np.newaxis], 3, axis=2) * 255
textline_mask = textline_mask.astype(np.uint8)
kernel = np.ones((5, 5), np.uint8)
@ -1497,8 +1517,10 @@ def separate_lines_new2(img_path, thetha, num_col, slope_region, logger=None, pl
img_patch_separated_returned[:, :][img_patch_separated_returned[:, :] != 0] = 1
img_patch_separated_returned_true_size = img_patch_separated_returned[
int(img_int.shape[0] * 0.1): int(img_int.shape[0] * 0.1) + img_int.shape[0],
int(img_int.shape[1] * 1.0): int(img_int.shape[1] * 1.0) + img_int.shape[1]]
int(img_int.shape[0] * 0.1): int(img_int.shape[0] * 0.1) +
img_int.shape[0],
int(img_int.shape[1] * 1.0): int(img_int.shape[1] * 1.0) +
img_int.shape[1]]
img_patch_separated_returned_true_size = img_patch_separated_returned_true_size[:, margin: length_x - margin]
img_patch_ineterst_revised[:, index_x_d + margin: index_x_u - margin] = img_patch_separated_returned_true_size
@ -1746,14 +1768,16 @@ def do_work_of_slopes_new_curved(
mask_biggest2 = cv2.dilate(mask_biggest2, KERNEL, iterations=4)
pixel_img = 1
mask_biggest2 = resize_image(mask_biggest2, int(mask_biggest2.shape[0] * scale_par), int(mask_biggest2.shape[1] * scale_par))
mask_biggest2 = resize_image(mask_biggest2, int(mask_biggest2.shape[0] * scale_par),
int(mask_biggest2.shape[1] * scale_par))
cnt_textlines_in_image_ind = return_contours_of_interested_textline(mask_biggest2, pixel_img)
try:
textlines_cnt_per_region.append(cnt_textlines_in_image_ind[0])
except Exception as why:
logger.error(why)
else:
textlines_cnt_per_region = textline_contours_postprocessing(all_text_region_raw, slope_for_all, contour_par, box_text, True)
textlines_cnt_per_region = textline_contours_postprocessing(all_text_region_raw, slope_for_all, contour_par,
box_text, True)
# print(np.shape(textlines_cnt_per_region),'textlines_cnt_per_region')
return textlines_cnt_per_region[::-1], box_text, contour, contour_par, crop_coor, index_r_con, slope

@ -57,7 +57,8 @@ class EynollahXmlWriter:
points_page_print = points_page_print + ' '
return points_page_print[:-1]
def serialize_lines_in_marginal(self, marginal_region, all_found_textline_polygons_marginals, marginal_idx, page_coord, all_box_coord_marginals, slopes_marginals, counter):
def serialize_lines_in_marginal(self, marginal_region, all_found_textline_polygons_marginals, marginal_idx,
page_coord, all_box_coord_marginals, slopes_marginals, counter):
for j in range(len(all_found_textline_polygons_marginals[marginal_idx])):
coords = CoordsType()
textline = TextLineType(id=counter.next_line_id, Coords=coords)
@ -67,37 +68,54 @@ class EynollahXmlWriter:
for l in range(len(all_found_textline_polygons_marginals[marginal_idx][j])):
if not (self.curved_line or self.textline_light):
if len(all_found_textline_polygons_marginals[marginal_idx][j][l]) == 2:
textline_x_coord = max(0, int((all_found_textline_polygons_marginals[marginal_idx][j][l][0] + all_box_coord_marginals[marginal_idx][2] + page_coord[2]) / self.scale_x) )
textline_y_coord = max(0, int((all_found_textline_polygons_marginals[marginal_idx][j][l][1] + all_box_coord_marginals[marginal_idx][0] + page_coord[0]) / self.scale_y) )
textline_x_coord = max(0, int((all_found_textline_polygons_marginals[marginal_idx][j][l][0] +
all_box_coord_marginals[marginal_idx][2] + page_coord[
2]) / self.scale_x))
textline_y_coord = max(0, int((all_found_textline_polygons_marginals[marginal_idx][j][l][1] +
all_box_coord_marginals[marginal_idx][0] + page_coord[
0]) / self.scale_y))
else:
textline_x_coord = max(0, int((all_found_textline_polygons_marginals[marginal_idx][j][l][0][0] + all_box_coord_marginals[marginal_idx][2] + page_coord[2]) / self.scale_x) )
textline_y_coord = max(0, int((all_found_textline_polygons_marginals[marginal_idx][j][l][0][1] + all_box_coord_marginals[marginal_idx][0] + page_coord[0]) / self.scale_y) )
textline_x_coord = max(0, int((all_found_textline_polygons_marginals[marginal_idx][j][l][0][0] +
all_box_coord_marginals[marginal_idx][2] + page_coord[
2]) / self.scale_x))
textline_y_coord = max(0, int((all_found_textline_polygons_marginals[marginal_idx][j][l][0][1] +
all_box_coord_marginals[marginal_idx][0] + page_coord[
0]) / self.scale_y))
points_co += str(textline_x_coord)
points_co += ','
points_co += str(textline_y_coord)
if (self.curved_line or self.textline_light) and np.abs(slopes_marginals[marginal_idx]) <= 45:
if len(all_found_textline_polygons_marginals[marginal_idx][j][l]) == 2:
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][0] + page_coord[2]) / self.scale_x))
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][0] + page_coord[
2]) / self.scale_x))
points_co += ','
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][1] + page_coord[0]) / self.scale_y))
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][1] + page_coord[
0]) / self.scale_y))
else:
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][0][0] + page_coord[2]) / self.scale_x))
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][0][0] +
page_coord[2]) / self.scale_x))
points_co += ','
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][0][1] + page_coord[0]) / self.scale_y))
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][0][1] +
page_coord[0]) / self.scale_y))
elif (self.curved_line or self.textline_light) and np.abs(slopes_marginals[marginal_idx]) > 45:
if len(all_found_textline_polygons_marginals[marginal_idx][j][l]) == 2:
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][0] + all_box_coord_marginals[marginal_idx][2] + page_coord[2]) / self.scale_x))
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][0] +
all_box_coord_marginals[marginal_idx][2] + page_coord[2]) / self.scale_x))
points_co += ','
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][1] + all_box_coord_marginals[marginal_idx][0] + page_coord[0]) / self.scale_y))
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][1] +
all_box_coord_marginals[marginal_idx][0] + page_coord[0]) / self.scale_y))
else:
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][0][0] + all_box_coord_marginals[marginal_idx][2] + page_coord[2]) / self.scale_x))
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][0][0] +
all_box_coord_marginals[marginal_idx][2] + page_coord[2]) / self.scale_x))
points_co += ','
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][0][1] + all_box_coord_marginals[marginal_idx][0] + page_coord[0]) / self.scale_y))
points_co += str(int((all_found_textline_polygons_marginals[marginal_idx][j][l][0][1] +
all_box_coord_marginals[marginal_idx][0] + page_coord[0]) / self.scale_y))
points_co += ' '
coords.set_points(points_co[:-1])
def serialize_lines_in_region(self, text_region, all_found_textline_polygons, region_idx, page_coord, all_box_coord, slopes, counter, ocr_all_textlines_textregion):
def serialize_lines_in_region(self, text_region, all_found_textline_polygons, region_idx, page_coord, all_box_coord,
slopes, counter, ocr_all_textlines_textregion):
self.logger.debug('enter serialize_lines_in_region')
for j in range(len(all_found_textline_polygons[region_idx])):
coords = CoordsType()
@ -111,11 +129,15 @@ class EynollahXmlWriter:
for idx_contour_textline, contour_textline in enumerate(all_found_textline_polygons[region_idx][j]):
if not (self.curved_line or self.textline_light):
if len(contour_textline) == 2:
textline_x_coord = max(0, int((contour_textline[0] + region_bboxes[2] + page_coord[2]) / self.scale_x))
textline_y_coord = max(0, int((contour_textline[1] + region_bboxes[0] + page_coord[0]) / self.scale_y))
textline_x_coord = max(0, int((contour_textline[0] + region_bboxes[2] + page_coord[
2]) / self.scale_x))
textline_y_coord = max(0, int((contour_textline[1] + region_bboxes[0] + page_coord[
0]) / self.scale_y))
else:
textline_x_coord = max(0, int((contour_textline[0][0] + region_bboxes[2] + page_coord[2]) / self.scale_x))
textline_y_coord = max(0, int((contour_textline[0][1] + region_bboxes[0] + page_coord[0]) / self.scale_y))
textline_x_coord = max(0, int((contour_textline[0][0] + region_bboxes[2] + page_coord[
2]) / self.scale_x))
textline_y_coord = max(0, int((contour_textline[0][1] + region_bboxes[0] + page_coord[
0]) / self.scale_y))
points_co += str(textline_x_coord)
points_co += ','
points_co += str(textline_y_coord)
@ -135,13 +157,16 @@ class EynollahXmlWriter:
points_co += ','
points_co += str(int((contour_textline[1] + region_bboxes[0] + page_coord[0]) / self.scale_y))
else:
points_co += str(int((contour_textline[0][0] + region_bboxes[2]+page_coord[2])/self.scale_x))
points_co += str(
int((contour_textline[0][0] + region_bboxes[2] + page_coord[2]) / self.scale_x))
points_co += ','
points_co += str(int((contour_textline[0][1] + region_bboxes[0]+page_coord[0])/self.scale_y))
points_co += str(
int((contour_textline[0][1] + region_bboxes[0] + page_coord[0]) / self.scale_y))
points_co += ' '
coords.set_points(points_co[:-1])
def serialize_lines_in_dropcapital(self, text_region, all_found_textline_polygons, region_idx, page_coord, all_box_coord, slopes, counter, ocr_all_textlines_textregion):
def serialize_lines_in_dropcapital(self, text_region, all_found_textline_polygons, region_idx, page_coord,
all_box_coord, slopes, counter, ocr_all_textlines_textregion):
self.logger.debug('enter serialize_lines_in_region')
for j in range(1):
coords = CoordsType()
@ -169,7 +194,11 @@ class EynollahXmlWriter:
with open(self.output_filename, 'w') as f:
f.write(to_xml(pcgts))
def build_pagexml_no_full_layout(self, found_polygons_text_region, page_coord, order_of_texts, id_of_texts, all_found_textline_polygons, all_box_coord, found_polygons_text_region_img, found_polygons_marginals, all_found_textline_polygons_marginals, all_box_coord_marginals, slopes, slopes_marginals, cont_page, polygons_lines_to_be_written_in_xml, found_polygons_tables, ocr_all_textlines):
def build_pagexml_no_full_layout(self, found_polygons_text_region, page_coord, order_of_texts, id_of_texts,
all_found_textline_polygons, all_box_coord, found_polygons_text_region_img,
found_polygons_marginals, all_found_textline_polygons_marginals,
all_box_coord_marginals, slopes, slopes_marginals, cont_page,
polygons_lines_to_be_written_in_xml, found_polygons_tables, ocr_all_textlines):
self.logger.debug('enter build_pagexml_no_full_layout')
# create the file structure
@ -185,20 +214,26 @@ class EynollahXmlWriter:
for mm in range(len(found_polygons_text_region)):
textregion = TextRegionType(id=counter.next_region_id, type_='paragraph',
Coords=CoordsType(points=self.calculate_polygon_coords(found_polygons_text_region[mm], page_coord)),
Coords=CoordsType(
points=self.calculate_polygon_coords(found_polygons_text_region[mm],
page_coord)),
)
page.add_TextRegion(textregion)
if ocr_all_textlines:
ocr_textlines = ocr_all_textlines[mm]
else:
ocr_textlines = None
self.serialize_lines_in_region(textregion, all_found_textline_polygons, mm, page_coord, all_box_coord, slopes, counter, ocr_textlines)
self.serialize_lines_in_region(textregion, all_found_textline_polygons, mm, page_coord, all_box_coord,
slopes, counter, ocr_textlines)
for mm in range(len(found_polygons_marginals)):
marginal = TextRegionType(id=counter.next_region_id, type_='marginalia',
Coords=CoordsType(points=self.calculate_polygon_coords(found_polygons_marginals[mm], page_coord)))
Coords=CoordsType(
points=self.calculate_polygon_coords(found_polygons_marginals[mm],
page_coord)))
page.add_TextRegion(marginal)
self.serialize_lines_in_marginal(marginal, all_found_textline_polygons_marginals, mm, page_coord, all_box_coord_marginals, slopes_marginals, counter)
self.serialize_lines_in_marginal(marginal, all_found_textline_polygons_marginals, mm, page_coord,
all_box_coord_marginals, slopes_marginals, counter)
for mm in range(len(found_polygons_text_region_img)):
img_region = ImageRegionType(id=counter.next_region_id, Coords=CoordsType())
@ -206,9 +241,11 @@ class EynollahXmlWriter:
points_co = ''
for lmm in range(len(found_polygons_text_region_img[mm])):
try:
points_co += str(int((found_polygons_text_region_img[mm][lmm,0,0] + page_coord[2]) / self.scale_x))
points_co += str(
int((found_polygons_text_region_img[mm][lmm, 0, 0] + page_coord[2]) / self.scale_x))
points_co += ','
points_co += str(int((found_polygons_text_region_img[mm][lmm,0,1] + page_coord[0]) / self.scale_y))
points_co += str(
int((found_polygons_text_region_img[mm][lmm, 0, 1] + page_coord[0]) / self.scale_y))
points_co += ' '
except:
@ -242,7 +279,13 @@ class EynollahXmlWriter:
return pcgts
def build_pagexml_full_layout(self, found_polygons_text_region, found_polygons_text_region_h, page_coord, order_of_texts, id_of_texts, all_found_textline_polygons, all_found_textline_polygons_h, all_box_coord, all_box_coord_h, found_polygons_text_region_img, found_polygons_tables, found_polygons_drop_capitals, found_polygons_marginals, all_found_textline_polygons_marginals, all_box_coord_marginals, slopes, slopes_h, slopes_marginals, cont_page, polygons_lines_to_be_written_in_xml, ocr_all_textlines):
def build_pagexml_full_layout(self, found_polygons_text_region, found_polygons_text_region_h, page_coord,
order_of_texts, id_of_texts, all_found_textline_polygons,
all_found_textline_polygons_h, all_box_coord, all_box_coord_h,
found_polygons_text_region_img, found_polygons_tables, found_polygons_drop_capitals,
found_polygons_marginals, all_found_textline_polygons_marginals,
all_box_coord_marginals, slopes, slopes_h, slopes_marginals, cont_page,
polygons_lines_to_be_written_in_xml, ocr_all_textlines):
self.logger.debug('enter build_pagexml_full_layout')
# create the file structure
@ -257,49 +300,63 @@ class EynollahXmlWriter:
for mm in range(len(found_polygons_text_region)):
textregion = TextRegionType(id=counter.next_region_id, type_='paragraph',
Coords=CoordsType(points=self.calculate_polygon_coords(found_polygons_text_region[mm], page_coord)))
Coords=CoordsType(
points=self.calculate_polygon_coords(found_polygons_text_region[mm],
page_coord)))
page.add_TextRegion(textregion)
if ocr_all_textlines:
ocr_textlines = ocr_all_textlines[mm]
else:
ocr_textlines = None
self.serialize_lines_in_region(textregion, all_found_textline_polygons, mm, page_coord, all_box_coord, slopes, counter, ocr_textlines)
self.serialize_lines_in_region(textregion, all_found_textline_polygons, mm, page_coord, all_box_coord,
slopes, counter, ocr_textlines)
self.logger.debug('len(found_polygons_text_region_h) %s', len(found_polygons_text_region_h))
for mm in range(len(found_polygons_text_region_h)):
textregion = TextRegionType(id=counter.next_region_id, type_='header',
Coords=CoordsType(points=self.calculate_polygon_coords(found_polygons_text_region_h[mm], page_coord)))
Coords=CoordsType(
points=self.calculate_polygon_coords(found_polygons_text_region_h[mm],
page_coord)))
page.add_TextRegion(textregion)
if ocr_all_textlines:
ocr_textlines = ocr_all_textlines[mm]
else:
ocr_textlines = None
self.serialize_lines_in_region(textregion, all_found_textline_polygons_h, mm, page_coord, all_box_coord_h, slopes_h, counter, ocr_textlines)
self.serialize_lines_in_region(textregion, all_found_textline_polygons_h, mm, page_coord, all_box_coord_h,
slopes_h, counter, ocr_textlines)
for mm in range(len(found_polygons_marginals)):
marginal = TextRegionType(id=counter.next_region_id, type_='marginalia',
Coords=CoordsType(points=self.calculate_polygon_coords(found_polygons_marginals[mm], page_coord)))
Coords=CoordsType(
points=self.calculate_polygon_coords(found_polygons_marginals[mm],
page_coord)))
page.add_TextRegion(marginal)
self.serialize_lines_in_marginal(marginal, all_found_textline_polygons_marginals, mm, page_coord, all_box_coord_marginals, slopes_marginals, counter)
self.serialize_lines_in_marginal(marginal, all_found_textline_polygons_marginals, mm, page_coord,
all_box_coord_marginals, slopes_marginals, counter)
for mm in range(len(found_polygons_drop_capitals)):
dropcapital = TextRegionType(id=counter.next_region_id, type_='drop-capital',
Coords=CoordsType(points=self.calculate_polygon_coords(found_polygons_drop_capitals[mm], page_coord)))
Coords=CoordsType(
points=self.calculate_polygon_coords(found_polygons_drop_capitals[mm],
page_coord)))
page.add_TextRegion(dropcapital)
###all_box_coord_drop = None
###slopes_drop = None
###self.serialize_lines_in_dropcapital(dropcapital, [found_polygons_drop_capitals[mm]], mm, page_coord, all_box_coord_drop, slopes_drop, counter, ocr_all_textlines_textregion=None)
for mm in range(len(found_polygons_text_region_img)):
page.add_ImageRegion(ImageRegionType(id=counter.next_region_id, Coords=CoordsType(points=self.calculate_polygon_coords(found_polygons_text_region_img[mm], page_coord))))
page.add_ImageRegion(ImageRegionType(id=counter.next_region_id, Coords=CoordsType(
points=self.calculate_polygon_coords(found_polygons_text_region_img[mm], page_coord))))
for mm in range(len(polygons_lines_to_be_written_in_xml)):
page.add_SeparatorRegion(ImageRegionType(id=counter.next_region_id, Coords=CoordsType(points=self.calculate_polygon_coords(polygons_lines_to_be_written_in_xml[mm], [0 , 0, 0, 0]))))
page.add_SeparatorRegion(ImageRegionType(id=counter.next_region_id, Coords=CoordsType(
points=self.calculate_polygon_coords(polygons_lines_to_be_written_in_xml[mm], [0, 0, 0, 0]))))
for mm in range(len(found_polygons_tables)):
page.add_TableRegion(TableRegionType(id=counter.next_region_id, Coords=CoordsType(points=self.calculate_polygon_coords(found_polygons_tables[mm], page_coord))))
page.add_TableRegion(TableRegionType(id=counter.next_region_id, Coords=CoordsType(
points=self.calculate_polygon_coords(found_polygons_tables[mm], page_coord))))
return pcgts
@ -317,4 +374,3 @@ class EynollahXmlWriter:
coords += str(int((value_bbox[0][1] + page_coord[0]) / self.scale_y))
coords = coords + ' '
return coords[:-1]

Loading…
Cancel
Save