all options checked, failures are fixed and all tests passed

pull/19/head
vahid 4 years ago
parent c25fcd8137
commit 3bda2f128e

@ -1,4 +1,3 @@
#check first update from repaired pc
# ocrd includes opencv, numpy, shapely, click # ocrd includes opencv, numpy, shapely, click
ocrd >= 2.20.3 ocrd >= 2.20.3
keras >= 2.3.1, < 2.4 keras >= 2.3.1, < 2.4

@ -28,6 +28,7 @@ import tensorflow as tf
tf.get_logger().setLevel("ERROR") tf.get_logger().setLevel("ERROR")
warnings.filterwarnings("ignore") warnings.filterwarnings("ignore")
from .utils.contour import ( from .utils.contour import (
filter_contours_area_of_image, filter_contours_area_of_image,
find_contours_mean_y_diff, find_contours_mean_y_diff,
@ -110,7 +111,7 @@ class Eynollah:
dir_of_cropped_images=dir_of_cropped_images, dir_of_cropped_images=dir_of_cropped_images,
dir_of_layout=dir_of_layout, dir_of_layout=dir_of_layout,
image_filename=image_filename, image_filename=image_filename,
image_filename_stem=image_filename_stem) image_filename_stem=self.image_filename_stem)
self.writer = EynollahXmlWriter( self.writer = EynollahXmlWriter(
dir_out=self.dir_out, dir_out=self.dir_out,
image_filename=self.image_filename, image_filename=self.image_filename,
@ -336,7 +337,10 @@ class Eynollah:
def resize_and_enhance_image_with_column_classifier(self): def resize_and_enhance_image_with_column_classifier(self):
self.logger.debug("enter resize_and_enhance_image_with_column_classifier") self.logger.debug("enter resize_and_enhance_image_with_column_classifier")
dpi = check_dpi(self.image_filename) try:
dpi = check_dpi(self.image_filename)
except:
dpi = 230
self.logger.info("Detected %s DPI", dpi) self.logger.info("Detected %s DPI", dpi)
img = self.imread() img = self.imread()
@ -705,13 +709,12 @@ class Eynollah:
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):
self.logger.debug("enter get_slopes_and_deskew_new") self.logger.debug("enter get_slopes_and_deskew_new")
num_cores = cpu_count() num_cores = 1#cpu_count()
queue_of_all_params = Queue() queue_of_all_params = Queue()
processes = [] processes = []
nh = np.linspace(0, len(boxes), num_cores + 1) nh = np.linspace(0, len(boxes), num_cores + 1)
indexes_by_text_con = np.array(range(len(contours_par))) indexes_by_text_con = np.array(range(len(contours_par)))
for i in range(num_cores): for i in range(num_cores):
boxes_per_process = boxes[int(nh[i]) : int(nh[i + 1])] boxes_per_process = boxes[int(nh[i]) : int(nh[i + 1])]
contours_per_process = contours[int(nh[i]) : int(nh[i + 1])] contours_per_process = contours[int(nh[i]) : int(nh[i + 1])]
@ -719,7 +722,6 @@ class Eynollah:
indexes_text_con_per_process = indexes_by_text_con[int(nh[i]) : int(nh[i + 1])] indexes_text_con_per_process = indexes_by_text_con[int(nh[i]) : int(nh[i + 1])]
processes.append(Process(target=self.do_work_of_slopes_new, args=(queue_of_all_params, boxes_per_process, textline_mask_tot, contours_per_process, contours_par_per_process, indexes_text_con_per_process, image_page_rotated, slope_deskew))) processes.append(Process(target=self.do_work_of_slopes_new, args=(queue_of_all_params, boxes_per_process, textline_mask_tot, contours_per_process, contours_par_per_process, indexes_text_con_per_process, image_page_rotated, slope_deskew)))
for i in range(num_cores): for i in range(num_cores):
processes[i].start() processes[i].start()
@ -730,7 +732,6 @@ class Eynollah:
boxes = [] boxes = []
all_box_coord = [] all_box_coord = []
all_index_text_con = [] all_index_text_con = []
for i in range(num_cores): for i in range(num_cores):
list_all_par = queue_of_all_params.get(True) list_all_par = queue_of_all_params.get(True)
slopes_for_sub_process = list_all_par[0] slopes_for_sub_process = list_all_par[0]
@ -748,7 +749,6 @@ class Eynollah:
all_found_text_regions_par.append(contours_par_for_subprocess[j]) all_found_text_regions_par.append(contours_par_for_subprocess[j])
all_box_coord.append(boxes_coord_for_subprocess[j]) all_box_coord.append(boxes_coord_for_subprocess[j])
all_index_text_con.append(indexes_for_subprocess[j]) all_index_text_con.append(indexes_for_subprocess[j])
for i in range(num_cores): for i in range(num_cores):
processes[i].join() processes[i].join()
self.logger.debug('slopes %s', slopes) self.logger.debug('slopes %s', slopes)
@ -918,7 +918,6 @@ class Eynollah:
def do_work_of_slopes_new(self, queue_of_all_params, boxes_text, textline_mask_tot_ea, contours_per_process, contours_par_per_process, indexes_r_con_per_pro, image_page_rotated, slope_deskew): def do_work_of_slopes_new(self, queue_of_all_params, boxes_text, textline_mask_tot_ea, contours_per_process, contours_par_per_process, indexes_r_con_per_pro, image_page_rotated, slope_deskew):
self.logger.debug('enter do_work_of_slopes_new') self.logger.debug('enter do_work_of_slopes_new')
slopes_per_each_subprocess = [] slopes_per_each_subprocess = []
bounding_box_of_textregion_per_each_subprocess = [] bounding_box_of_textregion_per_each_subprocess = []
textlines_rectangles_per_each_subprocess = [] textlines_rectangles_per_each_subprocess = []
@ -926,7 +925,6 @@ class Eynollah:
contours_textregion_par_per_each_subprocess = [] contours_textregion_par_per_each_subprocess = []
all_box_coord_per_process = [] all_box_coord_per_process = []
index_by_text_region_contours = [] index_by_text_region_contours = []
for mv in range(len(boxes_text)): for mv in range(len(boxes_text)):
_, crop_coor = crop_image_inside_box(boxes_text[mv],image_page_rotated) _, crop_coor = crop_image_inside_box(boxes_text[mv],image_page_rotated)
mask_textline = np.zeros((textline_mask_tot_ea.shape)) mask_textline = np.zeros((textline_mask_tot_ea.shape))
@ -959,7 +957,6 @@ class Eynollah:
except Exception as why: except Exception as why:
self.logger.error(why) self.logger.error(why)
slope_for_all = MAX_SLOPE slope_for_all = MAX_SLOPE
if slope_for_all == MAX_SLOPE: if slope_for_all == MAX_SLOPE:
slope_for_all = [slope_deskew][0] slope_for_all = [slope_deskew][0]
slopes_per_each_subprocess.append(slope_for_all) slopes_per_each_subprocess.append(slope_for_all)
@ -988,7 +985,6 @@ class Eynollah:
contours_textregion_per_each_subprocess.append(contours_per_process[mv]) contours_textregion_per_each_subprocess.append(contours_per_process[mv])
contours_textregion_par_per_each_subprocess.append(contours_par_per_process[mv]) contours_textregion_par_per_each_subprocess.append(contours_par_per_process[mv])
all_box_coord_per_process.append(crop_coor) all_box_coord_per_process.append(crop_coor)
queue_of_all_params.put([slopes_per_each_subprocess, textlines_rectangles_per_each_subprocess, bounding_box_of_textregion_per_each_subprocess, contours_textregion_per_each_subprocess, contours_textregion_par_per_each_subprocess, all_box_coord_per_process, index_by_text_region_contours]) queue_of_all_params.put([slopes_per_each_subprocess, textlines_rectangles_per_each_subprocess, bounding_box_of_textregion_per_each_subprocess, contours_textregion_per_each_subprocess, contours_textregion_par_per_each_subprocess, all_box_coord_per_process, index_by_text_region_contours])
def textline_contours(self, img, patches, scaler_h, scaler_w): def textline_contours(self, img, patches, scaler_h, scaler_w):
@ -1596,6 +1592,9 @@ class Eynollah:
t0 = time.time() t0 = time.time()
img_res, is_image_enhanced, num_col_classifier, num_column_is_classified = self.run_enhancement() img_res, is_image_enhanced, num_col_classifier, num_column_is_classified = self.run_enhancement()
self.logger.info("Enhancing took %ss ", str(time.time() - t0)) self.logger.info("Enhancing took %ss ", str(time.time() - t0))
t1 = time.time() t1 = time.time()
@ -1636,8 +1635,6 @@ class Eynollah:
if self.full_layout: if self.full_layout:
polygons_of_images, img_revised_tab, text_regions_p_1_n, textline_mask_tot_d, regions_without_seperators_d, regions_fully, regions_without_seperators = self.run_boxes_full_layout(image_page, textline_mask_tot, text_regions_p, slope_deskew, num_col_classifier, img_only_regions) polygons_of_images, img_revised_tab, text_regions_p_1_n, textline_mask_tot_d, regions_without_seperators_d, regions_fully, regions_without_seperators = self.run_boxes_full_layout(image_page, textline_mask_tot, text_regions_p, slope_deskew, num_col_classifier, img_only_regions)
# plt.imshow(img_revised_tab)
# plt.show()
text_only = ((img_revised_tab[:, :] == 1)) * 1 text_only = ((img_revised_tab[:, :] == 1)) * 1
if np.abs(slope_deskew) >= SLOPE_THRESHOLD: if np.abs(slope_deskew) >= SLOPE_THRESHOLD:
@ -1723,25 +1720,22 @@ class Eynollah:
self.logger.debug('areas_cnt_text_parent %s', areas_cnt_text_parent) self.logger.debug('areas_cnt_text_parent %s', areas_cnt_text_parent)
# self.logger.debug('areas_cnt_text_parent_d %s', areas_cnt_text_parent_d) # self.logger.debug('areas_cnt_text_parent_d %s', areas_cnt_text_parent_d)
# self.logger.debug('len(contours_only_text_parent) %s', len(contours_only_text_parent_d)) # self.logger.debug('len(contours_only_text_parent) %s', len(contours_only_text_parent_d))
txt_con_org = get_textregion_contours_in_org_image(contours_only_text_parent, self.image, slope_first) txt_con_org = get_textregion_contours_in_org_image(contours_only_text_parent, self.image, slope_first)
boxes_text, _ = get_text_region_boxes_by_given_contours(contours_only_text_parent) boxes_text, _ = get_text_region_boxes_by_given_contours(contours_only_text_parent)
boxes_marginals, _ = get_text_region_boxes_by_given_contours(polygons_of_marginals) boxes_marginals, _ = get_text_region_boxes_by_given_contours(polygons_of_marginals)
if not self.curved_line: if not self.curved_line:
slopes, all_found_texline_polygons, boxes_text, txt_con_org, contours_only_text_parent, all_box_coord, index_by_text_par_con = self.get_slopes_and_deskew_new(txt_con_org, contours_only_text_parent, textline_mask_tot_ea, image_page_rotated, boxes_text, slope_deskew) slopes, all_found_texline_polygons, boxes_text, txt_con_org, contours_only_text_parent, all_box_coord, index_by_text_par_con = self.get_slopes_and_deskew_new(txt_con_org, contours_only_text_parent, textline_mask_tot_ea, image_page_rotated, boxes_text, slope_deskew)
_, all_found_texline_polygons_marginals, boxes_marginals, _, polygons_of_marginals, all_box_coord_marginals, _ = self.get_slopes_and_deskew_new(polygons_of_marginals, polygons_of_marginals, textline_mask_tot_ea, image_page_rotated, boxes_marginals, slope_deskew) slopes_marginals, all_found_texline_polygons_marginals, boxes_marginals, _, polygons_of_marginals, all_box_coord_marginals, _ = self.get_slopes_and_deskew_new(polygons_of_marginals, polygons_of_marginals, textline_mask_tot_ea, image_page_rotated, boxes_marginals, slope_deskew)
else: else:
scale_param = 1 scale_param = 1
all_found_texline_polygons, boxes_text, txt_con_org, contours_only_text_parent, all_box_coord, index_by_text_par_con, slopes = self.get_slopes_and_deskew_new_curved(txt_con_org, contours_only_text_parent, cv2.erode(textline_mask_tot_ea, kernel=KERNEL, iterations=1), image_page_rotated, boxes_text, text_only, num_col_classifier, scale_param, slope_deskew) all_found_texline_polygons, boxes_text, txt_con_org, contours_only_text_parent, all_box_coord, index_by_text_par_con, slopes = self.get_slopes_and_deskew_new_curved(txt_con_org, contours_only_text_parent, cv2.erode(textline_mask_tot_ea, kernel=KERNEL, iterations=1), image_page_rotated, boxes_text, text_only, num_col_classifier, scale_param, slope_deskew)
all_found_texline_polygons = small_textlines_to_parent_adherence2(all_found_texline_polygons, textline_mask_tot_ea, num_col_classifier) all_found_texline_polygons = small_textlines_to_parent_adherence2(all_found_texline_polygons, textline_mask_tot_ea, num_col_classifier)
all_found_texline_polygons_marginals, boxes_marginals, _, polygons_of_marginals, all_box_coord_marginals, _, _ = self.get_slopes_and_deskew_new_curved(polygons_of_marginals, polygons_of_marginals, cv2.erode(textline_mask_tot_ea, kernel=KERNEL, iterations=1), image_page_rotated, boxes_marginals, text_only, num_col_classifier, scale_param, slope_deskew) all_found_texline_polygons_marginals, boxes_marginals, _, polygons_of_marginals, all_box_coord_marginals, _, slopes_marginals = self.get_slopes_and_deskew_new_curved(polygons_of_marginals, polygons_of_marginals, cv2.erode(textline_mask_tot_ea, kernel=KERNEL, iterations=1), image_page_rotated, boxes_marginals, text_only, num_col_classifier, scale_param, slope_deskew)
all_found_texline_polygons_marginals = small_textlines_to_parent_adherence2(all_found_texline_polygons_marginals, textline_mask_tot_ea, num_col_classifier) all_found_texline_polygons_marginals = small_textlines_to_parent_adherence2(all_found_texline_polygons_marginals, textline_mask_tot_ea, num_col_classifier)
K.clear_session() K.clear_session()
# print(index_by_text_par_con,'index_by_text_par_con')
if self.full_layout: if self.full_layout:
if np.abs(slope_deskew) >= SLOPE_THRESHOLD: if np.abs(slope_deskew) >= SLOPE_THRESHOLD:
contours_only_text_parent_d_ordered = list(np.array(contours_only_text_parent_d_ordered)[index_by_text_par_con]) contours_only_text_parent_d_ordered = list(np.array(contours_only_text_parent_d_ordered)[index_by_text_par_con])
@ -1809,7 +1803,7 @@ class Eynollah:
else: 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) 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)
pcgts = self.writer.build_pagexml_full_layout(contours_only_text_parent, contours_only_text_parent_h, page_coord, order_text_new, id_of_texts_tot, all_found_texline_polygons, all_found_texline_polygons_h, all_box_coord, all_box_coord_h, polygons_of_images, polygons_of_tabels, polygons_of_drop_capitals, polygons_of_marginals, all_found_texline_polygons_marginals, all_box_coord_marginals, slopes, cont_page) pcgts = self.writer.build_pagexml_full_layout(contours_only_text_parent, contours_only_text_parent_h, page_coord, order_text_new, id_of_texts_tot, all_found_texline_polygons, all_found_texline_polygons_h, all_box_coord, all_box_coord_h, polygons_of_images, polygons_of_tabels, polygons_of_drop_capitals, polygons_of_marginals, all_found_texline_polygons_marginals, all_box_coord_marginals, slopes, slopes_marginals, cont_page)
self.logger.info("Job done in %ss", str(time.time() - t0)) self.logger.info("Job done in %ss", str(time.time() - t0))
return pcgts return pcgts
else: else:
@ -1819,6 +1813,6 @@ class Eynollah:
else: else:
contours_only_text_parent_d_ordered = list(np.array(contours_only_text_parent_d_ordered)[index_by_text_par_con]) contours_only_text_parent_d_ordered = list(np.array(contours_only_text_parent_d_ordered)[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) 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)
pcgts = self.writer.build_pagexml_no_full_layout(txt_con_org, page_coord, order_text_new, id_of_texts_tot, all_found_texline_polygons, all_box_coord, polygons_of_images, polygons_of_marginals, all_found_texline_polygons_marginals, all_box_coord_marginals, slopes, cont_page) pcgts = self.writer.build_pagexml_no_full_layout(txt_con_org, page_coord, order_text_new, id_of_texts_tot, all_found_texline_polygons, all_box_coord, polygons_of_images, polygons_of_marginals, all_found_texline_polygons_marginals, all_box_coord_marginals, slopes, slopes_marginals, cont_page)
self.logger.info("Job done in %ss", str(time.time() - t0)) self.logger.info("Job done in %ss", str(time.time() - t0))
return pcgts return pcgts

@ -39,121 +39,131 @@ class EynollahPlotter():
self.scale_y = scale_y self.scale_y = scale_y
def save_plot_of_layout_main(self, text_regions_p, image_page): def save_plot_of_layout_main(self, text_regions_p, image_page):
values = np.unique(text_regions_p[:, :]) if self.dir_of_layout is not None:
# pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics'] values = np.unique(text_regions_p[:, :])
pixels=['Background' , 'Main text' , 'Image' , 'Separator','Marginalia'] # pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics']
values_indexes = [0, 1, 2, 3, 4] pixels=['Background' , 'Main text' , 'Image' , 'Separator','Marginalia']
plt.figure(figsize=(40, 40)) values_indexes = [0, 1, 2, 3, 4]
plt.rcParams["font.size"] = "40" plt.figure(figsize=(40, 40))
im = plt.imshow(text_regions_p[:, :]) plt.rcParams["font.size"] = "40"
colors = [im.cmap(im.norm(value)) for value in values] im = plt.imshow(text_regions_p[:, :])
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] colors = [im.cmap(im.norm(value)) for value in values]
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.0, fontsize=40) 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.savefig(os.path.join(self.dir_of_layout, self.image_filename_stem + "_layout_main.png")) 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): def save_plot_of_layout_main_all(self, text_regions_p, image_page):
values = np.unique(text_regions_p[:, :]) if self.dir_of_all is not None:
# pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics'] values = np.unique(text_regions_p[:, :])
pixels=['Background' , 'Main text' , 'Image' , 'Separator','Marginalia'] # pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics']
values_indexes = [0, 1, 2, 3, 4] pixels=['Background' , 'Main text' , 'Image' , 'Separator','Marginalia']
plt.figure(figsize=(80, 40)) values_indexes = [0, 1, 2, 3, 4]
plt.rcParams["font.size"] = "40" plt.figure(figsize=(80, 40))
plt.subplot(1, 2, 1) plt.rcParams["font.size"] = "40"
plt.imshow(image_page) plt.subplot(1, 2, 1)
plt.subplot(1, 2, 2) plt.imshow(image_page)
im = plt.imshow(text_regions_p[:, :]) plt.subplot(1, 2, 2)
colors = [im.cmap(im.norm(value)) for value in values] im = plt.imshow(text_regions_p[:, :])
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] colors = [im.cmap(im.norm(value)) for value in values]
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.0, fontsize=60) 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.savefig(os.path.join(self.dir_of_all, self.image_filename_stem + "_layout_main_and_page.png")) 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"))
def save_plot_of_layout(self, text_regions_p, image_page): def save_plot_of_layout(self, text_regions_p, image_page):
values = np.unique(text_regions_p[:, :]) if self.dir_of_layout is not None:
# pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics'] values = np.unique(text_regions_p[:, :])
pixels = ["Background", "Main text", "Header", "Marginalia", "Drop capital", "Image", "Separator"] # pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics']
values_indexes = [0, 1, 2, 8, 4, 5, 6] pixels = ["Background", "Main text", "Header", "Marginalia", "Drop capital", "Image", "Separator"]
plt.figure(figsize=(40, 40)) values_indexes = [0, 1, 2, 8, 4, 5, 6]
plt.rcParams["font.size"] = "40" plt.figure(figsize=(40, 40))
im = plt.imshow(text_regions_p[:, :]) plt.rcParams["font.size"] = "40"
colors = [im.cmap(im.norm(value)) for value in values] im = plt.imshow(text_regions_p[:, :])
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] colors = [im.cmap(im.norm(value)) for value in values]
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.0, fontsize=40) 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.savefig(os.path.join(self.dir_of_layout, self.image_filename_stem + "_layout.png")) 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"))
def save_plot_of_layout_all(self, text_regions_p, image_page): def save_plot_of_layout_all(self, text_regions_p, image_page):
values = np.unique(text_regions_p[:, :]) if self.dir_of_all is not None:
# pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics'] values = np.unique(text_regions_p[:, :])
pixels = ["Background", "Main text", "Header", "Marginalia", "Drop capital", "Image", "Separator"] # pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics']
values_indexes = [0, 1, 2, 8, 4, 5, 6] pixels = ["Background", "Main text", "Header", "Marginalia", "Drop capital", "Image", "Separator"]
plt.figure(figsize=(80, 40)) values_indexes = [0, 1, 2, 8, 4, 5, 6]
plt.rcParams["font.size"] = "40" plt.figure(figsize=(80, 40))
plt.subplot(1, 2, 1) plt.rcParams["font.size"] = "40"
plt.imshow(image_page) plt.subplot(1, 2, 1)
plt.subplot(1, 2, 2) plt.imshow(image_page)
im = plt.imshow(text_regions_p[:, :]) plt.subplot(1, 2, 2)
colors = [im.cmap(im.norm(value)) for value in values] im = plt.imshow(text_regions_p[:, :])
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] colors = [im.cmap(im.norm(value)) for value in values]
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.0, fontsize=60) 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.savefig(os.path.join(self.dir_of_all, self.image_filename_stem + "_layout_and_page.png")) 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"))
def save_plot_of_textlines(self, textline_mask_tot_ea, image_page): def save_plot_of_textlines(self, textline_mask_tot_ea, image_page):
values = np.unique(textline_mask_tot_ea[:, :]) if self.dir_of_all is not None:
pixels = ["Background", "Textlines"] values = np.unique(textline_mask_tot_ea[:, :])
values_indexes = [0, 1] pixels = ["Background", "Textlines"]
plt.figure(figsize=(80, 40)) values_indexes = [0, 1]
plt.rcParams["font.size"] = "40" plt.figure(figsize=(80, 40))
plt.subplot(1, 2, 1) plt.rcParams["font.size"] = "40"
plt.imshow(image_page) plt.subplot(1, 2, 1)
plt.subplot(1, 2, 2) plt.imshow(image_page)
im = plt.imshow(textline_mask_tot_ea[:, :]) plt.subplot(1, 2, 2)
colors = [im.cmap(im.norm(value)) for value in values] im = plt.imshow(textline_mask_tot_ea[:, :])
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] colors = [im.cmap(im.norm(value)) for value in values]
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.0, fontsize=60) 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.savefig(os.path.join(self.dir_of_all, self.image_filename_stem + "_textline_and_page.png")) 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"))
def save_deskewed_image(self, slope_deskew): def save_deskewed_image(self, slope_deskew):
if self.dir_of_all is not None: if self.dir_of_all is not None:
img_rotated = rotyate_image_different(self.image_org, slope_deskew)
cv2.imwrite(os.path.join(self.dir_of_all, self.image_filename_stem + "_org.png"), self.image_org) cv2.imwrite(os.path.join(self.dir_of_all, self.image_filename_stem + "_org.png"), self.image_org)
cv2.imwrite(os.path.join(self.dir_of_deskewed, self.image_filename_stem + "_deskewed.png"), img_rotated) if self.dir_of_deskewed is not None:
img_rotated = rotyate_image_different(self.image_org, slope_deskew)
cv2.imwrite(os.path.join(self.dir_of_deskewed, self.image_filename_stem + "_deskewed.png"), img_rotated)
def save_page_image(self, image_page): def save_page_image(self, image_page):
cv2.imwrite(os.path.join(self.dir_of_all, self.image_filename_stem + "_page.png"), image_page) if self.dir_of_all is not None:
cv2.imwrite(os.path.join(self.dir_of_all, self.image_filename_stem + "_page.png"), image_page)
def save_plot_of_textline_density(self, img_patch_org): def save_plot_of_textline_density(self, img_patch_org):
plt.figure(figsize=(80,40)) if self.dir_of_all is not None:
plt.rcParams['font.size']='50' plt.figure(figsize=(80,40))
plt.subplot(1,2,1) plt.rcParams['font.size']='50'
plt.imshow(img_patch_org) plt.subplot(1,2,1)
plt.subplot(1,2,2) plt.imshow(img_patch_org)
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.subplot(1,2,2)
plt.xlabel('Density of textline prediction in direction of X axis',fontsize=60) 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.ylabel('Height',fontsize=60) plt.xlabel('Density of textline prediction in direction of X axis',fontsize=60)
plt.yticks([0,len(gaussian_filter1d(img_patch_org.sum(axis=1), 3))]) plt.ylabel('Height',fontsize=60)
plt.gca().invert_yaxis() plt.yticks([0,len(gaussian_filter1d(img_patch_org.sum(axis=1), 3))])
plt.savefig(os.path.join(self.dir_of_all, self.image_filename_stem+'_density_of_textline.png')) plt.gca().invert_yaxis()
plt.savefig(os.path.join(self.dir_of_all, self.image_filename_stem+'_density_of_textline.png'))
def save_plot_of_rotation_angle(self, angels, var_res): def save_plot_of_rotation_angle(self, angels, var_res):
#print('galdi?') if self.dir_of_all is not None:
plt.figure(figsize=(60,30)) plt.figure(figsize=(60,30))
plt.rcParams['font.size']='50' plt.rcParams['font.size']='50'
plt.plot(angels,np.array(var_res),'-o',markersize=25,linewidth=4) plt.plot(angels,np.array(var_res),'-o',markersize=25,linewidth=4)
plt.xlabel('angle',fontsize=50) plt.xlabel('angle',fontsize=50)
plt.ylabel('variance of sum of rotated textline in direction of x axis',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.legend(loc='best')
plt.savefig(os.path.join(self.dir_of_all, self.image_filename_stem+'_rotation_angle.png')) plt.savefig(os.path.join(self.dir_of_all, self.image_filename_stem+'_rotation_angle.png'))
def write_images_into_directory(self, img_contoures, image_page): def write_images_into_directory(self, img_contoures, image_page):
index = 0 if self.dir_of_cropped_images is not None:
for cont_ind in img_contoures: index = 0
x, y, w, h = cv2.boundingRect(cont_ind) for cont_ind in img_contoures:
box = [x, y, w, h] x, y, w, h = cv2.boundingRect(cont_ind)
croped_page, page_coord = crop_image_inside_box(box, image_page) 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) path = os.path.join(self.dir_of_cropped_images, self.image_filename_stem + "_" + str(index) + ".jpg")
index += 1 cv2.imwrite(path, croped_page)
index += 1

@ -43,7 +43,6 @@ def get_text_region_boxes_by_given_contours(contours):
def filter_contours_area_of_image(image, contours, hirarchy, max_area, min_area): def filter_contours_area_of_image(image, contours, hirarchy, max_area, min_area):
found_polygons_early = list() found_polygons_early = list()
jv = 0 jv = 0
for c in contours: for c in contours:
if len(c) < 3: # A polygon cannot have less than 3 points if len(c) < 3: # A polygon cannot have less than 3 points

@ -58,4 +58,5 @@ def xml_reading_order(page, order_of_texts, id_of_texts, id_of_marginalia, found
name.set('index', str(indexer_region)) name.set('index', str(indexer_region))
name.set('regionRef', 'r%s' % indexer_region) name.set('regionRef', 'r%s' % indexer_region)
indexer_region += 1 indexer_region += 1
return id_of_marginalia

@ -36,7 +36,7 @@ class EynollahXmlWriter():
points_page_print = points_page_print + ' ' points_page_print = points_page_print + ' '
return points_page_print[:-1] return points_page_print[:-1]
def serialize_lines_in_marginal(self, marginal, all_found_texline_polygons_marginals, marginal_idx, page_coord, all_box_coord_marginals, id_indexer_l): def serialize_lines_in_marginal(self, marginal, all_found_texline_polygons_marginals, marginal_idx, page_coord, all_box_coord_marginals, slopes_marginals, id_indexer_l):
for j in range(len(all_found_texline_polygons_marginals[marginal_idx])): for j in range(len(all_found_texline_polygons_marginals[marginal_idx])):
textline = ET.SubElement(marginal, 'TextLine') textline = ET.SubElement(marginal, 'TextLine')
textline.set('id', 'l%s' % id_indexer_l) textline.set('id', 'l%s' % id_indexer_l)
@ -54,7 +54,7 @@ class EynollahXmlWriter():
points_co += str(int((all_found_texline_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_texline_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 += ','
points_co += str(int((all_found_texline_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_texline_polygons_marginals[marginal_idx][j][l][0][1] + all_box_coord_marginals[marginal_idx][0] + page_coord[0])/self.scale_y))
else: if self.curved_line and np.abs(slopes_marginals[marginal_idx]) <= 45:
if len(all_found_texline_polygons_marginals[marginal_idx][j][l]) == 2: if len(all_found_texline_polygons_marginals[marginal_idx][j][l]) == 2:
points_co += str(int((all_found_texline_polygons_marginals[marginal_idx][j][l][0] + page_coord[2]) / self.scale_x)) points_co += str(int((all_found_texline_polygons_marginals[marginal_idx][j][l][0] + page_coord[2]) / self.scale_x))
points_co += ',' points_co += ','
@ -63,6 +63,17 @@ class EynollahXmlWriter():
points_co += str(int((all_found_texline_polygons_marginals[marginal_idx][j][l][0][0] + page_coord[2]) / self.scale_x)) points_co += str(int((all_found_texline_polygons_marginals[marginal_idx][j][l][0][0] + page_coord[2]) / self.scale_x))
points_co += ',' points_co += ','
points_co += str(int((all_found_texline_polygons_marginals[marginal_idx][j][l][0][1] + page_coord[0]) / self.scale_y)) points_co += str(int((all_found_texline_polygons_marginals[marginal_idx][j][l][0][1] + page_coord[0]) / self.scale_y))
elif self.curved_line and np.abs(slopes_marginals[marginal_idx]) > 45:
if len(all_found_texline_polygons_marginals[marginal_idx][j][l]) == 2:
points_co += str(int((all_found_texline_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_texline_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_texline_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_texline_polygons_marginals[marginal_idx][j][l][0][1] + all_box_coord_marginals[marginal_idx][0] + page_coord[0]) / self.scale_y))
if l < len(all_found_texline_polygons_marginals[marginal_idx][j]) - 1: if l < len(all_found_texline_polygons_marginals[marginal_idx][j]) - 1:
points_co += ' ' points_co += ' '
coord.set('points',points_co) coord.set('points',points_co)
@ -119,7 +130,7 @@ class EynollahXmlWriter():
tree = ET.ElementTree(pcgts) tree = ET.ElementTree(pcgts)
tree.write(os.path.join(self.dir_out, self.image_filename_stem) + ".xml") tree.write(os.path.join(self.dir_out, self.image_filename_stem) + ".xml")
def build_pagexml_no_full_layout(self, found_polygons_text_region, page_coord, order_of_texts, id_of_texts, all_found_texline_polygons, all_box_coord, found_polygons_text_region_img, found_polygons_marginals, all_found_texline_polygons_marginals, all_box_coord_marginals, slopes, cont_page): def build_pagexml_no_full_layout(self, found_polygons_text_region, page_coord, order_of_texts, id_of_texts, all_found_texline_polygons, all_box_coord, found_polygons_text_region_img, found_polygons_marginals, all_found_texline_polygons_marginals, all_box_coord_marginals, slopes, slopes_marginals, cont_page):
self.logger.debug('enter build_pagexml_no_full_layout') self.logger.debug('enter build_pagexml_no_full_layout')
# create the file structure # create the file structure
@ -132,7 +143,7 @@ class EynollahXmlWriter():
id_indexer = 0 id_indexer = 0
id_indexer_l = 0 id_indexer_l = 0
if len(found_polygons_text_region) > 0: if len(found_polygons_text_region) > 0:
xml_reading_order(page, order_of_texts, id_of_texts, id_of_marginalia, found_polygons_marginals) id_of_marginalia = xml_reading_order(page, order_of_texts, id_of_texts, id_of_marginalia, found_polygons_marginals)
for mm in range(len(found_polygons_text_region)): for mm in range(len(found_polygons_text_region)):
textregion = ET.SubElement(page, 'TextRegion') textregion = ET.SubElement(page, 'TextRegion')
textregion.set('id', 'r%s' % id_indexer) textregion.set('id', 'r%s' % id_indexer)
@ -143,13 +154,13 @@ class EynollahXmlWriter():
id_indexer_l = self.serialize_lines_in_region(textregion, all_found_texline_polygons, mm, page_coord, all_box_coord, slopes, id_indexer_l) id_indexer_l = self.serialize_lines_in_region(textregion, all_found_texline_polygons, mm, page_coord, all_box_coord, slopes, id_indexer_l)
add_textequiv(textregion) add_textequiv(textregion)
for marginal_idx in range(len(found_polygons_marginals)): for mm in range(len(found_polygons_marginals)):
marginal = ET.SubElement(page, 'TextRegion') marginal = ET.SubElement(page, 'TextRegion')
marginal.set('id', id_of_marginalia[mm]) marginal.set('id', id_of_marginalia[mm])
marginal.set('type', 'marginalia') marginal.set('type', 'marginalia')
coord_text = ET.SubElement(marginal, 'Coords') coord_text = ET.SubElement(marginal, 'Coords')
coord_text.set('points', self.calculate_polygon_coords(found_polygons_marginals, mm, page_coord)) coord_text.set('points', self.calculate_polygon_coords(found_polygons_marginals, mm, page_coord))
self.serialize_lines_in_marginal(marginal, all_found_texline_polygons_marginals, marginal_idx, page_coord, all_box_coord_marginals, id_indexer_l) id_indexer_l = self.serialize_lines_in_marginal(marginal, all_found_texline_polygons_marginals, mm, page_coord, all_box_coord_marginals, slopes_marginals, id_indexer_l)
id_indexer = len(found_polygons_text_region) + len(found_polygons_marginals) id_indexer = len(found_polygons_text_region) + len(found_polygons_marginals)
for mm in range(len(found_polygons_text_region_img)): for mm in range(len(found_polygons_text_region_img)):
@ -168,7 +179,7 @@ class EynollahXmlWriter():
return pcgts 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_texline_polygons, all_found_texline_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_texline_polygons_marginals, all_box_coord_marginals, slopes, cont_page): 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_texline_polygons, all_found_texline_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_texline_polygons_marginals, all_box_coord_marginals, slopes, slopes_marginals, cont_page):
self.logger.debug('enter build_pagexml_full_layout') self.logger.debug('enter build_pagexml_full_layout')
# create the file structure # create the file structure
@ -182,7 +193,7 @@ class EynollahXmlWriter():
id_of_marginalia = [] id_of_marginalia = []
if len(found_polygons_text_region) > 0: if len(found_polygons_text_region) > 0:
xml_reading_order(page, order_of_texts, id_of_texts, id_of_marginalia, found_polygons_marginals) id_of_marginalia = xml_reading_order(page, order_of_texts, id_of_texts, id_of_marginalia, found_polygons_marginals)
for mm in range(len(found_polygons_text_region)): for mm in range(len(found_polygons_text_region)):
textregion=ET.SubElement(page, 'TextRegion') textregion=ET.SubElement(page, 'TextRegion')
textregion.set('id', 'r%s' % id_indexer) textregion.set('id', 'r%s' % id_indexer)
@ -216,14 +227,14 @@ class EynollahXmlWriter():
coord_text.set('points', self.calculate_polygon_coords(found_polygons_drop_capitals, mm, page_coord)) coord_text.set('points', self.calculate_polygon_coords(found_polygons_drop_capitals, mm, page_coord))
add_textequiv(textregion) add_textequiv(textregion)
for marginal_idx in range(len(found_polygons_marginals)): for mm in range(len(found_polygons_marginals)):
marginal = ET.SubElement(page, 'TextRegion') marginal = ET.SubElement(page, 'TextRegion')
add_textequiv(textregion) add_textequiv(textregion)
marginal.set('id', id_of_marginalia[mm]) marginal.set('id', id_of_marginalia[mm])
marginal.set('type', 'marginalia') marginal.set('type', 'marginalia')
coord_text = ET.SubElement(marginal, 'Coords') coord_text = ET.SubElement(marginal, 'Coords')
coord_text.set('points', self.calculate_polygon_coords(found_polygons_marginals, mm, page_coord)) coord_text.set('points', self.calculate_polygon_coords(found_polygons_marginals, mm, page_coord))
self.serialize_lines_in_marginal(marginal, all_found_texline_polygons_marginals, marginal_idx, page_coord, all_box_coord_marginals, id_indexer_l) id_indexer_l = self.serialize_lines_in_marginal(marginal, all_found_texline_polygons_marginals, mm, page_coord, all_box_coord_marginals, slopes_marginals, id_indexer_l)
id_indexer = len(found_polygons_text_region) + len(found_polygons_text_region_h) + len(found_polygons_marginals) + len(found_polygons_drop_capitals) id_indexer = len(found_polygons_text_region) + len(found_polygons_text_region_h) + len(found_polygons_marginals) + len(found_polygons_drop_capitals)
for mm in range(len(found_polygons_text_region_img)): for mm in range(len(found_polygons_text_region_img)):

Loading…
Cancel
Save