diff --git a/requirements.txt b/requirements.txt index 242649a..9fd7bd8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -#check first update from repaired pc # ocrd includes opencv, numpy, shapely, click ocrd >= 2.20.3 keras >= 2.3.1, < 2.4 diff --git a/sbb_newspapers_org_image/eynollah.py b/sbb_newspapers_org_image/eynollah.py index 21747b4..4bd0c56 100644 --- a/sbb_newspapers_org_image/eynollah.py +++ b/sbb_newspapers_org_image/eynollah.py @@ -28,6 +28,7 @@ import tensorflow as tf tf.get_logger().setLevel("ERROR") warnings.filterwarnings("ignore") + from .utils.contour import ( filter_contours_area_of_image, find_contours_mean_y_diff, @@ -110,7 +111,7 @@ class Eynollah: dir_of_cropped_images=dir_of_cropped_images, dir_of_layout=dir_of_layout, image_filename=image_filename, - image_filename_stem=image_filename_stem) + image_filename_stem=self.image_filename_stem) self.writer = EynollahXmlWriter( dir_out=self.dir_out, image_filename=self.image_filename, @@ -336,7 +337,10 @@ class Eynollah: def resize_and_enhance_image_with_column_classifier(self): 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) 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): self.logger.debug("enter get_slopes_and_deskew_new") - num_cores = cpu_count() + num_cores = 1#cpu_count() queue_of_all_params = Queue() processes = [] nh = np.linspace(0, len(boxes), num_cores + 1) indexes_by_text_con = np.array(range(len(contours_par))) - for i in range(num_cores): boxes_per_process = boxes[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])] 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): processes[i].start() @@ -730,7 +732,6 @@ class Eynollah: boxes = [] all_box_coord = [] all_index_text_con = [] - for i in range(num_cores): list_all_par = queue_of_all_params.get(True) 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_box_coord.append(boxes_coord_for_subprocess[j]) all_index_text_con.append(indexes_for_subprocess[j]) - for i in range(num_cores): processes[i].join() 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): self.logger.debug('enter do_work_of_slopes_new') - slopes_per_each_subprocess = [] bounding_box_of_textregion_per_each_subprocess = [] textlines_rectangles_per_each_subprocess = [] @@ -926,7 +925,6 @@ class Eynollah: contours_textregion_par_per_each_subprocess = [] all_box_coord_per_process = [] index_by_text_region_contours = [] - for mv in range(len(boxes_text)): _, crop_coor = crop_image_inside_box(boxes_text[mv],image_page_rotated) mask_textline = np.zeros((textline_mask_tot_ea.shape)) @@ -959,7 +957,6 @@ class Eynollah: except Exception as why: self.logger.error(why) slope_for_all = MAX_SLOPE - if slope_for_all == MAX_SLOPE: slope_for_all = [slope_deskew][0] 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_par_per_each_subprocess.append(contours_par_per_process[mv]) 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]) def textline_contours(self, img, patches, scaler_h, scaler_w): @@ -1596,6 +1592,9 @@ class Eynollah: t0 = time.time() 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)) t1 = time.time() @@ -1633,11 +1632,9 @@ class Eynollah: pixel_img = 4 min_area_mar = 0.00001 polygons_of_marginals = return_contours_of_interested_region(text_regions_p, pixel_img, min_area_mar) - + 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) - # plt.imshow(img_revised_tab) - # plt.show() text_only = ((img_revised_tab[:, :] == 1)) * 1 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_d %s', areas_cnt_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) 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) 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) - _, 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: + 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 = 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) - K.clear_session() - # print(index_by_text_par_con,'index_by_text_par_con') - if self.full_layout: 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]) @@ -1809,7 +1803,7 @@ class Eynollah: 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) - 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)) return pcgts else: @@ -1819,6 +1813,6 @@ class Eynollah: else: 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) - 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)) return pcgts diff --git a/sbb_newspapers_org_image/plot.py b/sbb_newspapers_org_image/plot.py index cba8b58..4dee928 100644 --- a/sbb_newspapers_org_image/plot.py +++ b/sbb_newspapers_org_image/plot.py @@ -39,121 +39,131 @@ class EynollahPlotter(): self.scale_y = scale_y def save_plot_of_layout_main(self, text_regions_p, image_page): - values = np.unique(text_regions_p[:, :]) - # pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics'] - pixels=['Background' , 'Main text' , 'Image' , 'Separator','Marginalia'] - values_indexes = [0, 1, 2, 3, 4] - plt.figure(figsize=(40, 40)) - 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] - 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")) + if self.dir_of_layout is not None: + values = np.unique(text_regions_p[:, :]) + # pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics'] + pixels=['Background' , 'Main text' , 'Image' , 'Separator','Marginalia'] + values_indexes = [0, 1, 2, 3, 4] + plt.figure(figsize=(40, 40)) + 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] + 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): - values = np.unique(text_regions_p[:, :]) - # pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics'] - pixels=['Background' , 'Main text' , 'Image' , 'Separator','Marginalia'] - values_indexes = [0, 1, 2, 3, 4] - plt.figure(figsize=(80, 40)) - plt.rcParams["font.size"] = "40" - plt.subplot(1, 2, 1) - plt.imshow(image_page) - 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] - 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")) + if self.dir_of_all is not None: + values = np.unique(text_regions_p[:, :]) + # pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics'] + pixels=['Background' , 'Main text' , 'Image' , 'Separator','Marginalia'] + values_indexes = [0, 1, 2, 3, 4] + plt.figure(figsize=(80, 40)) + plt.rcParams["font.size"] = "40" + plt.subplot(1, 2, 1) + plt.imshow(image_page) + 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] + 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): - values = np.unique(text_regions_p[:, :]) - # pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics'] - pixels = ["Background", "Main text", "Header", "Marginalia", "Drop capital", "Image", "Separator"] - values_indexes = [0, 1, 2, 8, 4, 5, 6] - plt.figure(figsize=(40, 40)) - 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] - 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")) + if self.dir_of_layout is not None: + values = np.unique(text_regions_p[:, :]) + # pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics'] + pixels = ["Background", "Main text", "Header", "Marginalia", "Drop capital", "Image", "Separator"] + values_indexes = [0, 1, 2, 8, 4, 5, 6] + plt.figure(figsize=(40, 40)) + 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] + 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): - values = np.unique(text_regions_p[:, :]) - # pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics'] - pixels = ["Background", "Main text", "Header", "Marginalia", "Drop capital", "Image", "Separator"] - values_indexes = [0, 1, 2, 8, 4, 5, 6] - plt.figure(figsize=(80, 40)) - plt.rcParams["font.size"] = "40" - plt.subplot(1, 2, 1) - plt.imshow(image_page) - 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] - 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")) + if self.dir_of_all is not None: + values = np.unique(text_regions_p[:, :]) + # pixels=['Background' , 'Main text' , 'Heading' , 'Marginalia' ,'Drop capitals' , 'Images' , 'Seperators' , 'Tables', 'Graphics'] + pixels = ["Background", "Main text", "Header", "Marginalia", "Drop capital", "Image", "Separator"] + values_indexes = [0, 1, 2, 8, 4, 5, 6] + plt.figure(figsize=(80, 40)) + plt.rcParams["font.size"] = "40" + plt.subplot(1, 2, 1) + plt.imshow(image_page) + 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] + 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): - values = np.unique(textline_mask_tot_ea[:, :]) - pixels = ["Background", "Textlines"] - values_indexes = [0, 1] - plt.figure(figsize=(80, 40)) - plt.rcParams["font.size"] = "40" - plt.subplot(1, 2, 1) - plt.imshow(image_page) - 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] - 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")) + if self.dir_of_all is not None: + values = np.unique(textline_mask_tot_ea[:, :]) + pixels = ["Background", "Textlines"] + values_indexes = [0, 1] + plt.figure(figsize=(80, 40)) + plt.rcParams["font.size"] = "40" + plt.subplot(1, 2, 1) + plt.imshow(image_page) + 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] + 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): 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_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): - 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): - plt.figure(figsize=(80,40)) - plt.rcParams['font.size']='50' - 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.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))]) - plt.gca().invert_yaxis() - plt.savefig(os.path.join(self.dir_of_all, self.image_filename_stem+'_density_of_textline.png')) + if self.dir_of_all is not None: + plt.figure(figsize=(80,40)) + plt.rcParams['font.size']='50' + 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.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))]) + 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): - #print('galdi?') - plt.figure(figsize=(60,30)) - plt.rcParams['font.size']='50' - 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.legend(loc='best') - plt.savefig(os.path.join(self.dir_of_all, self.image_filename_stem+'_rotation_angle.png')) + if self.dir_of_all is not None: + plt.figure(figsize=(60,30)) + plt.rcParams['font.size']='50' + 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.legend(loc='best') + 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): - index = 0 - for cont_ind in img_contoures: - x, y, w, h = cv2.boundingRect(cont_ind) - 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)) - - path = os.path.join(self.dir_of_cropped_images, self.image_filename_stem + "_" + str(index) + ".jpg") - cv2.imwrite(path, croped_page) - index += 1 + if self.dir_of_cropped_images is not None: + index = 0 + for cont_ind in img_contoures: + x, y, w, h = cv2.boundingRect(cont_ind) + 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)) + + path = os.path.join(self.dir_of_cropped_images, self.image_filename_stem + "_" + str(index) + ".jpg") + cv2.imwrite(path, croped_page) + index += 1 diff --git a/sbb_newspapers_org_image/utils/contour.py b/sbb_newspapers_org_image/utils/contour.py index 06e2ee8..4fe3ae6 100644 --- a/sbb_newspapers_org_image/utils/contour.py +++ b/sbb_newspapers_org_image/utils/contour.py @@ -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): found_polygons_early = list() - jv = 0 for c in contours: if len(c) < 3: # A polygon cannot have less than 3 points diff --git a/sbb_newspapers_org_image/utils/xml.py b/sbb_newspapers_org_image/utils/xml.py index bba7db8..fe806e9 100644 --- a/sbb_newspapers_org_image/utils/xml.py +++ b/sbb_newspapers_org_image/utils/xml.py @@ -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('regionRef', 'r%s' % indexer_region) indexer_region += 1 + return id_of_marginalia diff --git a/sbb_newspapers_org_image/writer.py b/sbb_newspapers_org_image/writer.py index a949322..c8c34e4 100644 --- a/sbb_newspapers_org_image/writer.py +++ b/sbb_newspapers_org_image/writer.py @@ -36,7 +36,7 @@ class EynollahXmlWriter(): points_page_print = points_page_print + ' ' 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])): textline = ET.SubElement(marginal, 'TextLine') 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 += ',' 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: points_co += str(int((all_found_texline_polygons_marginals[marginal_idx][j][l][0] + page_coord[2]) / self.scale_x)) 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 += ',' 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: points_co += ' ' coord.set('points',points_co) @@ -119,7 +130,7 @@ class EynollahXmlWriter(): tree = ET.ElementTree(pcgts) 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') # create the file structure @@ -132,7 +143,7 @@ class EynollahXmlWriter(): id_indexer = 0 id_indexer_l = 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)): textregion = ET.SubElement(page, 'TextRegion') 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) 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.set('id', id_of_marginalia[mm]) marginal.set('type', 'marginalia') coord_text = ET.SubElement(marginal, 'Coords') 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) for mm in range(len(found_polygons_text_region_img)): @@ -168,7 +179,7 @@ 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_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') # create the file structure @@ -182,7 +193,7 @@ class EynollahXmlWriter(): id_of_marginalia = [] 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)): textregion=ET.SubElement(page, 'TextRegion') 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)) 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') add_textequiv(textregion) marginal.set('id', id_of_marginalia[mm]) marginal.set('type', 'marginalia') coord_text = ET.SubElement(marginal, 'Coords') 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) for mm in range(len(found_polygons_text_region_img)):