diff --git a/sbb_newspapers_org_image/eynollah.py b/sbb_newspapers_org_image/eynollah.py index c1c0f1e..8748dd6 100644 --- a/sbb_newspapers_org_image/eynollah.py +++ b/sbb_newspapers_org_image/eynollah.py @@ -46,6 +46,20 @@ from .utils import ( crop_image_inside_box, otsu_copy, otsu_copy_binary, + return_bonding_box_of_contours, + find_features_of_lines, + isNaN, + return_parent_contours, + return_contours_of_interested_region, + return_contours_of_interested_region_by_min_size, + return_contours_of_interested_textline, + boosting_headers_by_longshot_region_segmentation, + return_contours_of_image, + get_textregion_contours_in_org_image, + seperate_lines_vertical_cont, + seperate_lines, + seperate_lines_new_inside_teils2, + filter_small_drop_capitals_from_no_patch_layout, ) @@ -612,151 +626,6 @@ class eynollah: return model, session - def return_bonding_box_of_contours(self, cnts): - boxes_tot = [] - for i in range(len(cnts)): - x, y, w, h = cv2.boundingRect(cnts[i]) - - box = [x, y, w, h] - boxes_tot.append(box) - return boxes_tot - - def find_features_of_lines(self, 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))] - cx_main = [(M_main[j]["m10"] / (M_main[j]["m00"] + 1e-32)) for j in range(len(M_main))] - cy_main = [(M_main[j]["m01"] / (M_main[j]["m00"] + 1e-32)) for j in range(len(M_main))] - x_min_main = np.array([np.min(contours_main[j][:, 0, 0]) for j in range(len(contours_main))]) - x_max_main = np.array([np.max(contours_main[j][:, 0, 0]) for j in range(len(contours_main))]) - - y_min_main = np.array([np.min(contours_main[j][:, 0, 1]) for j in range(len(contours_main))]) - y_max_main = np.array([np.max(contours_main[j][:, 0, 1]) for j in range(len(contours_main))]) - - slope_lines = [] - - for kk in range(len(contours_main)): - [vx, vy, x, y] = cv2.fitLine(contours_main[kk], cv2.DIST_L2, 0, 0.01, 0.01) - slope_lines.append(((vy / vx) / np.pi * 180)[0]) - - slope_lines_org = slope_lines - slope_lines = np.array(slope_lines) - slope_lines[(slope_lines < 10) & (slope_lines > -10)] = 0 - - slope_lines[(slope_lines < -200) | (slope_lines > 200)] = 1 - slope_lines[(slope_lines != 0) & (slope_lines != 1)] = 2 - - dis_x = np.abs(x_max_main - x_min_main) - return slope_lines, dis_x, x_min_main, x_max_main, np.array(cy_main), np.array(slope_lines_org), y_min_main, y_max_main, np.array(cx_main) - - def return_parent_contours(self, contours, hierarchy): - contours_parent = [contours[i] for i in range(len(contours)) if hierarchy[0][i][3] == -1] - return contours_parent - - def isNaN(self, num): - return num != num - - def early_deskewing_slope_calculation_based_on_lines(self, region_pre_p): - # lines are labels by 6 in this model - seperators_closeup = ((region_pre_p[:, :, :] == 6)) * 1 - - seperators_closeup = seperators_closeup.astype(np.uint8) - imgray = cv2.cvtColor(seperators_closeup, cv2.COLOR_BGR2GRAY) - ret, thresh = cv2.threshold(imgray, 0, 255, 0) - - contours_lines, hierachy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - slope_lines, dist_x, x_min_main, x_max_main, cy_main, slope_lines_org, y_min_main, y_max_main, cx_main = self.find_features_of_lines(contours_lines) - - slope_lines_org_hor = slope_lines_org[slope_lines == 0] - args = np.array(range(len(slope_lines))) - len_x = seperators_closeup.shape[1] / 4.0 - - args_hor = args[slope_lines == 0] - dist_x_hor = dist_x[slope_lines == 0] - x_min_main_hor = x_min_main[slope_lines == 0] - x_max_main_hor = x_max_main[slope_lines == 0] - cy_main_hor = cy_main[slope_lines == 0] - - args_hor = args_hor[dist_x_hor >= len_x / 2.0] - x_max_main_hor = x_max_main_hor[dist_x_hor >= len_x / 2.0] - x_min_main_hor = x_min_main_hor[dist_x_hor >= len_x / 2.0] - cy_main_hor = cy_main_hor[dist_x_hor >= len_x / 2.0] - slope_lines_org_hor = slope_lines_org_hor[dist_x_hor >= len_x / 2.0] - - slope_lines_org_hor = slope_lines_org_hor[np.abs(slope_lines_org_hor) < 1.2] - slope_mean_hor = np.mean(slope_lines_org_hor) - - if np.abs(slope_mean_hor) > 1.2: - slope_mean_hor = 0 - - # deskewed_new=rotate_image(image_regions_eraly_p[:,:,:],slope_mean_hor) - - args_ver = args[slope_lines == 1] - y_min_main_ver = y_min_main[slope_lines == 1] - y_max_main_ver = y_max_main[slope_lines == 1] - x_min_main_ver = x_min_main[slope_lines == 1] - x_max_main_ver = x_max_main[slope_lines == 1] - cx_main_ver = cx_main[slope_lines == 1] - dist_y_ver = y_max_main_ver - y_min_main_ver - len_y = seperators_closeup.shape[0] / 3.0 - - return slope_mean_hor, cx_main_ver, dist_y_ver - - def return_contours_of_interested_region(self, region_pre_p, pixel, min_area=0.0002): - - # pixels of images are identified by 5 - if len(region_pre_p.shape) == 3: - cnts_images = (region_pre_p[:, :, 0] == pixel) * 1 - else: - cnts_images = (region_pre_p[:, :] == pixel) * 1 - cnts_images = cnts_images.astype(np.uint8) - cnts_images = np.repeat(cnts_images[:, :, np.newaxis], 3, axis=2) - imgray = cv2.cvtColor(cnts_images, cv2.COLOR_BGR2GRAY) - ret, thresh = cv2.threshold(imgray, 0, 255, 0) - - contours_imgs, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - - contours_imgs = self.return_parent_contours(contours_imgs, hiearchy) - contours_imgs = filter_contours_area_of_image_tables(thresh, contours_imgs, hiearchy, max_area=1, min_area=min_area) - - return contours_imgs - - def return_contours_of_interested_region_by_min_size(self, region_pre_p, pixel, min_size=0.00003): - - # pixels of images are identified by 5 - if len(region_pre_p.shape) == 3: - cnts_images = (region_pre_p[:, :, 0] == pixel) * 1 - else: - cnts_images = (region_pre_p[:, :] == pixel) * 1 - cnts_images = cnts_images.astype(np.uint8) - cnts_images = np.repeat(cnts_images[:, :, np.newaxis], 3, axis=2) - imgray = cv2.cvtColor(cnts_images, cv2.COLOR_BGR2GRAY) - ret, thresh = cv2.threshold(imgray, 0, 255, 0) - - contours_imgs, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - - contours_imgs = self.return_parent_contours(contours_imgs, hiearchy) - contours_imgs = filter_contours_area_of_image_tables(thresh, contours_imgs, hiearchy, max_area=1, min_area=min_size) - - return contours_imgs - - def return_contours_of_interested_textline(self, region_pre_p, pixel): - - # pixels of images are identified by 5 - if len(region_pre_p.shape) == 3: - cnts_images = (region_pre_p[:, :, 0] == pixel) * 1 - else: - cnts_images = (region_pre_p[:, :] == pixel) * 1 - cnts_images = cnts_images.astype(np.uint8) - cnts_images = np.repeat(cnts_images[:, :, np.newaxis], 3, axis=2) - imgray = cv2.cvtColor(cnts_images, cv2.COLOR_BGR2GRAY) - ret, thresh = cv2.threshold(imgray, 0, 255, 0) - contours_imgs, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - - contours_imgs = self.return_parent_contours(contours_imgs, hiearchy) - contours_imgs = filter_contours_area_of_image_tables(thresh, contours_imgs, hiearchy, max_area=1, min_area=0.000000003) - return contours_imgs - def find_images_contours_and_replace_table_and_graphic_pixels_by_image(self, region_pre_p): # pixels of images are identified by 5 @@ -767,13 +636,13 @@ class eynollah: ret, thresh = cv2.threshold(imgray, 0, 255, 0) contours_imgs, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - contours_imgs = self.return_parent_contours(contours_imgs, hiearchy) + contours_imgs = return_parent_contours(contours_imgs, hiearchy) # print(len(contours_imgs),'contours_imgs') contours_imgs = filter_contours_area_of_image_tables(thresh, contours_imgs, hiearchy, max_area=1, min_area=0.0003) # print(len(contours_imgs),'contours_imgs') - boxes_imgs = self.return_bonding_box_of_contours(contours_imgs) + boxes_imgs = return_bonding_box_of_contours(contours_imgs) for i in range(len(boxes_imgs)): x1 = int(boxes_imgs[i][0]) @@ -1429,7 +1298,7 @@ class eynollah: else: try: - textline_con, hierachy = self.return_contours_of_image(img_int_p) + textline_con, hierachy = return_contours_of_image(img_int_p) textline_con_fil = filter_contours_area_of_image(img_int_p, textline_con, hierachy, max_area=1, min_area=0.0008) y_diff_mean = self.find_contours_mean_y_diff(textline_con_fil) @@ -1498,7 +1367,7 @@ class eynollah: # plt.show() pixel_img = 1 - cnt_textlines_in_image = self.return_contours_of_interested_textline(textline_region_in_image, pixel_img) + cnt_textlines_in_image = return_contours_of_interested_textline(textline_region_in_image, pixel_img) textlines_cnt_per_region = [] for jjjj in range(len(cnt_textlines_in_image)): @@ -1514,7 +1383,7 @@ class eynollah: 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 = self.return_contours_of_interested_textline(mask_biggest2, pixel_img) + 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]/scale_par) @@ -1585,7 +1454,7 @@ class eynollah: else: try: - textline_con, hierachy = self.return_contours_of_image(img_int_p) + textline_con, hierachy = return_contours_of_image(img_int_p) textline_con_fil = filter_contours_area_of_image(img_int_p, textline_con, hierachy, max_area=1, min_area=0.00008) y_diff_mean = self.find_contours_mean_y_diff(textline_con_fil) @@ -1673,21 +1542,6 @@ class eynollah: return main_contours - def boosting_headers_by_longshot_region_segmentation(self, textregion_pre_p, textregion_pre_np, img_only_text): - textregion_pre_p_org = np.copy(textregion_pre_p) - # 4 is drop capitals - headers_in_longshot = (textregion_pre_np[:, :, 0] == 2) * 1 - # headers_in_longshot= ( (textregion_pre_np[:,:,0]==2) | (textregion_pre_np[:,:,0]==1) )*1 - textregion_pre_p[:, :, 0][(headers_in_longshot[:, :] == 1) & (textregion_pre_p[:, :, 0] != 4)] = 2 - textregion_pre_p[:, :, 0][textregion_pre_p[:, :, 0] == 1] = 0 - # textregion_pre_p[:,:,0][( img_only_text[:,:]==1) & (textregion_pre_p[:,:,0]!=7) & (textregion_pre_p[:,:,0]!=2)]=1 # eralier it was so, but by this manner the drop capitals are alse deleted - textregion_pre_p[:, :, 0][(img_only_text[:, :] == 1) & (textregion_pre_p[:, :, 0] != 7) & (textregion_pre_p[:, :, 0] != 4) & (textregion_pre_p[:, :, 0] != 2)] = 1 - return textregion_pre_p - - def boosting_text_only_regions_by_header(self, textregion_pre_np, img_only_text): - result = ((img_only_text[:, :] == 1) | (textregion_pre_np[:, :, 0] == 2)) * 1 - return result - def get_all_image_patches_coordination(self, image_page): self.all_box_coord = [] for jk in range(len(self.boxes)): @@ -1742,231 +1596,6 @@ class eynollah: gc.collect() return prediction_textline[:, :, 0], prediction_textline_longshot_true_size[:, :, 0] - def get_textlines_for_each_textregions(self, textline_mask_tot, boxes): - textline_mask_tot = cv2.erode(textline_mask_tot, self.kernel, iterations=1) - self.area_of_cropped = [] - self.all_text_region_raw = [] - for jk in range(len(boxes)): - crop_img, crop_coor = crop_image_inside_box(boxes[jk], np.repeat(textline_mask_tot[:, :, np.newaxis], 3, axis=2)) - crop_img = crop_img.astype(np.uint8) - self.all_text_region_raw.append(crop_img[:, :, 0]) - self.area_of_cropped.append(crop_img.shape[0] * crop_img.shape[1]) - - def seperate_lines_new_inside_teils2(self, img_patch, thetha): - - (h, w) = img_patch.shape[:2] - center = (w // 2, h // 2) - M = cv2.getRotationMatrix2D(center, -thetha, 1.0) - x_d = M[0, 2] - y_d = M[1, 2] - - thetha = thetha / 180.0 * np.pi - rotation_matrix = np.array([[np.cos(thetha), -np.sin(thetha)], [np.sin(thetha), np.cos(thetha)]]) - # contour_text_interest_copy = contour_text_interest.copy() - - # x_cont = contour_text_interest[:, 0, 0] - # y_cont = contour_text_interest[:, 0, 1] - # x_cont = x_cont - np.min(x_cont) - # y_cont = y_cont - np.min(y_cont) - - x_min_cont = 0 - x_max_cont = img_patch.shape[1] - y_min_cont = 0 - y_max_cont = img_patch.shape[0] - - xv = np.linspace(x_min_cont, x_max_cont, 1000) - - textline_patch_sum_along_width = img_patch.sum(axis=1) - - first_nonzero = 0 # (next((i for i, x in enumerate(mada_n) if x), None)) - - y = textline_patch_sum_along_width[:] # [first_nonzero:last_nonzero] - y_padded = np.zeros(len(y) + 40) - y_padded[20 : len(y) + 20] = y - x = np.array(range(len(y))) - - peaks_real, _ = find_peaks(gaussian_filter1d(y, 3), height=0) - if 1 > 0: - - try: - - y_padded_smoothed_e = gaussian_filter1d(y_padded, 2) - y_padded_up_to_down_e = -y_padded + np.max(y_padded) - y_padded_up_to_down_padded_e = np.zeros(len(y_padded_up_to_down_e) + 40) - 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.array(range(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))) - arg_diff_cluster = arg_diff[diff_arg_neg_must_be_deleted > 1] - - peaks_new = peaks_e[:] - peaks_neg_new = peaks_neg_e[:] - - clusters_to_be_deleted = [] - 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[len(arg_diff_cluster) - 1] + 1 :]) - - if len(clusters_to_be_deleted) > 0: - peaks_new_extra = [] - for m in range(len(clusters_to_be_deleted)): - min_cluster = np.min(peaks_e[clusters_to_be_deleted[m]]) - max_cluster = np.max(peaks_e[clusters_to_be_deleted[m]]) - peaks_new_extra.append(int((min_cluster + max_cluster) / 2.0)) - for m1 in range(len(clusters_to_be_deleted[m])): - peaks_new = peaks_new[peaks_new != peaks_e[clusters_to_be_deleted[m][m1] - 1]] - peaks_new = peaks_new[peaks_new != peaks_e[clusters_to_be_deleted[m][m1]]] - - peaks_neg_new = peaks_neg_new[peaks_neg_new != peaks_neg_e[clusters_to_be_deleted[m][m1]]] - peaks_new_tot = [] - for i1 in peaks_new: - peaks_new_tot.append(i1) - for i1 in peaks_new_extra: - peaks_new_tot.append(i1) - peaks_new_tot = np.sort(peaks_new_tot) - - else: - peaks_new_tot = peaks_e[:] - - textline_con, hierachy = self.return_contours_of_image(img_patch) - textline_con_fil = filter_contours_area_of_image(img_patch, textline_con, hierachy, max_area=1, min_area=0.0008) - y_diff_mean = np.mean(np.diff(peaks_new_tot)) # self.find_contours_mean_y_diff(textline_con_fil) - - sigma_gaus = int(y_diff_mean * (7.0 / 40.0)) - # print(sigma_gaus,'sigma_gaus') - except: - sigma_gaus = 12 - if sigma_gaus < 3: - sigma_gaus = 3 - # print(sigma_gaus,'sigma') - - y_padded_smoothed = gaussian_filter1d(y_padded, sigma_gaus) - y_padded_up_to_down = -y_padded + np.max(y_padded) - y_padded_up_to_down_padded = np.zeros(len(y_padded_up_to_down) + 40) - y_padded_up_to_down_padded[20 : len(y_padded_up_to_down) + 20] = y_padded_up_to_down - y_padded_up_to_down_padded = gaussian_filter1d(y_padded_up_to_down_padded, sigma_gaus) - - peaks, _ = find_peaks(y_padded_smoothed, height=0) - peaks_neg, _ = find_peaks(y_padded_up_to_down_padded, height=0) - - peaks_new = peaks[:] - peaks_neg_new = peaks_neg[:] - - try: - neg_peaks_max = np.max(y_padded_smoothed[peaks]) - - arg_neg_must_be_deleted = np.array(range(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))) - arg_diff_cluster = arg_diff[diff_arg_neg_must_be_deleted > 1] - - clusters_to_be_deleted = [] - - if len(arg_diff_cluster) >= 2 and 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[len(arg_diff_cluster) - 1] + 1 :]) - elif len(arg_neg_must_be_deleted) >= 2 and len(arg_diff_cluster) == 0: - clusters_to_be_deleted.append(arg_neg_must_be_deleted[:]) - - if len(arg_neg_must_be_deleted) == 1: - clusters_to_be_deleted.append(arg_neg_must_be_deleted) - - if len(clusters_to_be_deleted) > 0: - peaks_new_extra = [] - for m in range(len(clusters_to_be_deleted)): - min_cluster = np.min(peaks[clusters_to_be_deleted[m]]) - max_cluster = np.max(peaks[clusters_to_be_deleted[m]]) - peaks_new_extra.append(int((min_cluster + max_cluster) / 2.0)) - for m1 in range(len(clusters_to_be_deleted[m])): - peaks_new = peaks_new[peaks_new != peaks[clusters_to_be_deleted[m][m1] - 1]] - peaks_new = peaks_new[peaks_new != peaks[clusters_to_be_deleted[m][m1]]] - - peaks_neg_new = peaks_neg_new[peaks_neg_new != peaks_neg[clusters_to_be_deleted[m][m1]]] - peaks_new_tot = [] - for i1 in peaks_new: - peaks_new_tot.append(i1) - for i1 in peaks_new_extra: - peaks_new_tot.append(i1) - peaks_new_tot = np.sort(peaks_new_tot) - - # plt.plot(y_padded_up_to_down_padded) - # plt.plot(peaks_neg,y_padded_up_to_down_padded[peaks_neg],'*') - # plt.show() - - # plt.plot(y_padded_up_to_down_padded) - # plt.plot(peaks_neg_new,y_padded_up_to_down_padded[peaks_neg_new],'*') - # plt.show() - - # plt.plot(y_padded_smoothed) - # plt.plot(peaks,y_padded_smoothed[peaks],'*') - # plt.show() - - # plt.plot(y_padded_smoothed) - # plt.plot(peaks_new_tot,y_padded_smoothed[peaks_new_tot],'*') - # plt.show() - - peaks = peaks_new_tot[:] - peaks_neg = peaks_neg_new[:] - except: - pass - - else: - peaks_new_tot = peaks[:] - peaks = peaks_new_tot[:] - peaks_neg = peaks_neg_new[:] - - mean_value_of_peaks = np.mean(y_padded_smoothed[peaks]) - std_value_of_peaks = np.std(y_padded_smoothed[peaks]) - peaks_values = y_padded_smoothed[peaks] - - ###peaks_neg = peaks_neg - 20 - 20 - ###peaks = peaks - 20 - peaks_neg_true = peaks_neg[:] - peaks_pos_true = peaks[:] - - if len(peaks_neg_true) > 0: - peaks_neg_true = np.array(peaks_neg_true) - - peaks_neg_true = peaks_neg_true - 20 - 20 - - # print(peaks_neg_true) - for i in range(len(peaks_neg_true)): - img_patch[peaks_neg_true[i] - 6 : peaks_neg_true[i] + 6, :] = 0 - - else: - pass - - if len(peaks_pos_true) > 0: - peaks_pos_true = np.array(peaks_pos_true) - peaks_pos_true = peaks_pos_true - 20 - - for i in range(len(peaks_pos_true)): - ##img_patch[peaks_pos_true[i]-8:peaks_pos_true[i]+8,:]=1 - img_patch[peaks_pos_true[i] - 6 : peaks_pos_true[i] + 6, :] = 1 - else: - pass - kernel = np.ones((5, 5), np.uint8) - - # img_patch = cv2.erode(img_patch,kernel,iterations = 3) - #######################img_patch = cv2.erode(img_patch,kernel,iterations = 2) - img_patch = cv2.erode(img_patch, kernel, iterations=1) - return img_patch - def seperate_lines_new_inside_teils(self, img_path, thetha): (h, w) = img_path.shape[:2] center = (w // 2, h // 2) @@ -2031,13 +1660,13 @@ class eynollah: forest.append(peaks_neg[i + 1]) if diff_peaks[i] > cut_off: # print(forest[np.argmin(z[forest]) ] ) - if not self.isNaN(forest[np.argmin(z[forest])]): + if not isNaN(forest[np.argmin(z[forest])]): peaks_neg_true.append(forest[np.argmin(z[forest])]) forest = [] forest.append(peaks_neg[i + 1]) if i == (len(peaks_neg) - 1): # print(print(forest[np.argmin(z[forest]) ] )) - if not self.isNaN(forest[np.argmin(z[forest])]): + if not isNaN(forest[np.argmin(z[forest])]): peaks_neg_true.append(forest[np.argmin(z[forest])]) diff_peaks_pos = np.abs(np.diff(peaks)) @@ -2054,13 +1683,13 @@ class eynollah: forest.append(peaks[i + 1]) if diff_peaks_pos[i] > cut_off: # print(forest[np.argmin(z[forest]) ] ) - if not self.isNaN(forest[np.argmax(z[forest])]): + if not isNaN(forest[np.argmax(z[forest])]): peaks_pos_true.append(forest[np.argmax(z[forest])]) forest = [] forest.append(peaks[i + 1]) if i == (len(peaks) - 1): # print(print(forest[np.argmin(z[forest]) ] )) - if not self.isNaN(forest[np.argmax(z[forest])]): + if not isNaN(forest[np.argmax(z[forest])]): peaks_pos_true.append(forest[np.argmax(z[forest])]) # print(len(peaks_neg_true) ,len(peaks_pos_true) ,'lensss') @@ -2180,14 +1809,14 @@ class eynollah: forest.append(peaks_neg[i + 1]) if diff_peaks[i] > cut_off: # print(forest[np.argmin(z[forest]) ] ) - if not self.isNaN(forest[np.argmin(z[forest])]): + if not isNaN(forest[np.argmin(z[forest])]): # print(len(z),forest) peaks_neg_true.append(forest[np.argmin(z[forest])]) forest = [] forest.append(peaks_neg[i + 1]) if i == (len(peaks_neg) - 1): # print(print(forest[np.argmin(z[forest]) ] )) - if not self.isNaN(forest[np.argmin(z[forest])]): + if not isNaN(forest[np.argmin(z[forest])]): peaks_neg_true.append(forest[np.argmin(z[forest])]) @@ -2463,7 +2092,7 @@ class eynollah: img_line_rotated = rotate_image(img_resized, slopes_tile_wise[i]) img_line_rotated[:, :][img_line_rotated[:, :] != 0] = 1 - img_patch_seperated = self.seperate_lines_new_inside_teils2(img_line_rotated, 0) + img_patch_seperated = seperate_lines_new_inside_teils2(img_line_rotated, 0) img_patch_seperated_returned = rotate_image(img_patch_seperated, -slopes_tile_wise[i]) img_patch_seperated_returned[:, :][img_patch_seperated_returned[:, :] != 0] = 1 @@ -2477,923 +2106,6 @@ class eynollah: # plt.show() return img_patch_ineterst_revised - def seperate_lines(self, img_patch, contour_text_interest, thetha, x_help, y_help): - - (h, w) = img_patch.shape[:2] - center = (w // 2, h // 2) - M = cv2.getRotationMatrix2D(center, -thetha, 1.0) - x_d = M[0, 2] - y_d = M[1, 2] - - thetha = thetha / 180.0 * np.pi - rotation_matrix = np.array([[np.cos(thetha), -np.sin(thetha)], [np.sin(thetha), np.cos(thetha)]]) - contour_text_interest_copy = contour_text_interest.copy() - - x_cont = contour_text_interest[:, 0, 0] - y_cont = contour_text_interest[:, 0, 1] - x_cont = x_cont - np.min(x_cont) - y_cont = y_cont - np.min(y_cont) - - x_min_cont = 0 - x_max_cont = img_patch.shape[1] - y_min_cont = 0 - y_max_cont = img_patch.shape[0] - - xv = np.linspace(x_min_cont, x_max_cont, 1000) - - textline_patch_sum_along_width = img_patch.sum(axis=1) - - first_nonzero = 0 # (next((i for i, x in enumerate(mada_n) if x), None)) - - y = textline_patch_sum_along_width[:] # [first_nonzero:last_nonzero] - y_padded = np.zeros(len(y) + 40) - y_padded[20 : len(y) + 20] = y - x = np.array(range(len(y))) - - peaks_real, _ = find_peaks(gaussian_filter1d(y, 3), height=0) - - if 1 > 0: - - try: - - y_padded_smoothed_e = gaussian_filter1d(y_padded, 2) - y_padded_up_to_down_e = -y_padded + np.max(y_padded) - y_padded_up_to_down_padded_e = np.zeros(len(y_padded_up_to_down_e) + 40) - 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.array(range(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))) - arg_diff_cluster = arg_diff[diff_arg_neg_must_be_deleted > 1] - - peaks_new = peaks_e[:] - peaks_neg_new = peaks_neg_e[:] - - clusters_to_be_deleted = [] - 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[len(arg_diff_cluster) - 1] + 1 :]) - - if len(clusters_to_be_deleted) > 0: - peaks_new_extra = [] - for m in range(len(clusters_to_be_deleted)): - min_cluster = np.min(peaks_e[clusters_to_be_deleted[m]]) - max_cluster = np.max(peaks_e[clusters_to_be_deleted[m]]) - peaks_new_extra.append(int((min_cluster + max_cluster) / 2.0)) - for m1 in range(len(clusters_to_be_deleted[m])): - peaks_new = peaks_new[peaks_new != peaks_e[clusters_to_be_deleted[m][m1] - 1]] - peaks_new = peaks_new[peaks_new != peaks_e[clusters_to_be_deleted[m][m1]]] - - peaks_neg_new = peaks_neg_new[peaks_neg_new != peaks_neg_e[clusters_to_be_deleted[m][m1]]] - peaks_new_tot = [] - for i1 in peaks_new: - peaks_new_tot.append(i1) - for i1 in peaks_new_extra: - peaks_new_tot.append(i1) - peaks_new_tot = np.sort(peaks_new_tot) - - else: - peaks_new_tot = peaks_e[:] - - textline_con, hierachy = self.return_contours_of_image(img_patch) - textline_con_fil = filter_contours_area_of_image(img_patch, textline_con, hierachy, max_area=1, min_area=0.0008) - y_diff_mean = np.mean(np.diff(peaks_new_tot)) # self.find_contours_mean_y_diff(textline_con_fil) - - sigma_gaus = int(y_diff_mean * (7.0 / 40.0)) - # print(sigma_gaus,'sigma_gaus') - except: - sigma_gaus = 12 - if sigma_gaus < 3: - sigma_gaus = 3 - # print(sigma_gaus,'sigma') - - y_padded_smoothed = gaussian_filter1d(y_padded, sigma_gaus) - y_padded_up_to_down = -y_padded + np.max(y_padded) - y_padded_up_to_down_padded = np.zeros(len(y_padded_up_to_down) + 40) - y_padded_up_to_down_padded[20 : len(y_padded_up_to_down) + 20] = y_padded_up_to_down - y_padded_up_to_down_padded = gaussian_filter1d(y_padded_up_to_down_padded, sigma_gaus) - - peaks, _ = find_peaks(y_padded_smoothed, height=0) - peaks_neg, _ = find_peaks(y_padded_up_to_down_padded, height=0) - - try: - neg_peaks_max = np.max(y_padded_smoothed[peaks]) - - arg_neg_must_be_deleted = np.array(range(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))) - arg_diff_cluster = arg_diff[diff_arg_neg_must_be_deleted > 1] - except: - arg_neg_must_be_deleted = [] - arg_diff_cluster = [] - - try: - peaks_new = peaks[:] - peaks_neg_new = peaks_neg[:] - clusters_to_be_deleted = [] - - if len(arg_diff_cluster) >= 2 and 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[len(arg_diff_cluster) - 1] + 1 :]) - elif len(arg_neg_must_be_deleted) >= 2 and len(arg_diff_cluster) == 0: - clusters_to_be_deleted.append(arg_neg_must_be_deleted[:]) - - if len(arg_neg_must_be_deleted) == 1: - clusters_to_be_deleted.append(arg_neg_must_be_deleted) - - if len(clusters_to_be_deleted) > 0: - peaks_new_extra = [] - for m in range(len(clusters_to_be_deleted)): - min_cluster = np.min(peaks[clusters_to_be_deleted[m]]) - max_cluster = np.max(peaks[clusters_to_be_deleted[m]]) - peaks_new_extra.append(int((min_cluster + max_cluster) / 2.0)) - for m1 in range(len(clusters_to_be_deleted[m])): - peaks_new = peaks_new[peaks_new != peaks[clusters_to_be_deleted[m][m1] - 1]] - peaks_new = peaks_new[peaks_new != peaks[clusters_to_be_deleted[m][m1]]] - - peaks_neg_new = peaks_neg_new[peaks_neg_new != peaks_neg[clusters_to_be_deleted[m][m1]]] - peaks_new_tot = [] - for i1 in peaks_new: - peaks_new_tot.append(i1) - for i1 in peaks_new_extra: - peaks_new_tot.append(i1) - peaks_new_tot = np.sort(peaks_new_tot) - - ##plt.plot(y_padded_up_to_down_padded) - ##plt.plot(peaks_neg,y_padded_up_to_down_padded[peaks_neg],'*') - ##plt.show() - - ##plt.plot(y_padded_up_to_down_padded) - ##plt.plot(peaks_neg_new,y_padded_up_to_down_padded[peaks_neg_new],'*') - ##plt.show() - - ##plt.plot(y_padded_smoothed) - ##plt.plot(peaks,y_padded_smoothed[peaks],'*') - ##plt.show() - - ##plt.plot(y_padded_smoothed) - ##plt.plot(peaks_new_tot,y_padded_smoothed[peaks_new_tot],'*') - ##plt.show() - - peaks = peaks_new_tot[:] - peaks_neg = peaks_neg_new[:] - - else: - peaks_new_tot = peaks[:] - peaks = peaks_new_tot[:] - peaks_neg = peaks_neg_new[:] - except: - pass - - mean_value_of_peaks = np.mean(y_padded_smoothed[peaks]) - std_value_of_peaks = np.std(y_padded_smoothed[peaks]) - peaks_values = y_padded_smoothed[peaks] - - peaks_neg = peaks_neg - 20 - 20 - peaks = peaks - 20 - - for jj in range(len(peaks_neg)): - if peaks_neg[jj] > len(x) - 1: - peaks_neg[jj] = len(x) - 1 - - for jj in range(len(peaks)): - if peaks[jj] > len(x) - 1: - peaks[jj] = len(x) - 1 - - textline_boxes = [] - textline_boxes_rot = [] - - if len(peaks_neg) == len(peaks) + 1 and len(peaks) >= 3: - for jj in range(len(peaks)): - - if jj == (len(peaks) - 1): - 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.3 * dis_to_next_up) ##+int(dis_to_next_up*1./4.0) - point_down = y_max_cont - 1 ##peaks[jj] + first_nonzero + int(1.3 * 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) - else: - point_up = peaks[jj] + first_nonzero - int(1.4 * dis_to_next_up) ##+int(dis_to_next_up*1./4.0) - point_down = y_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) - 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) - 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_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, (xv[mj], peaks[jj] + first_nonzero), True) for mj in range(len(xv))] - distances = np.array(distances) - - xvinside = xv[distances >= 0] - - if len(xvinside) == 0: - x_min = x_min_cont - x_max = x_max_cont - else: - x_min = np.min(xvinside) # max(x_min_interest,x_min_cont) - x_max = np.max(xvinside) # min(x_max_interest,x_max_cont) - - p1 = np.dot(rotation_matrix, [int(x_min), int(point_up)]) - p2 = np.dot(rotation_matrix, [int(x_max), int(point_up)]) - p3 = np.dot(rotation_matrix, [int(x_max), int(point_down)]) - p4 = np.dot(rotation_matrix, [int(x_min), int(point_down)]) - - x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d - x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d - x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d - x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d - - if x_min_rot1 < 0: - x_min_rot1 = 0 - if x_min_rot4 < 0: - x_min_rot4 = 0 - if point_up_rot1 < 0: - point_up_rot1 = 0 - if point_up_rot2 < 0: - point_up_rot2 = 0 - - x_min_rot1 = x_min_rot1 - x_help - x_max_rot2 = x_max_rot2 - x_help - x_max_rot3 = x_max_rot3 - x_help - x_min_rot4 = x_min_rot4 - x_help - - point_up_rot1 = point_up_rot1 - y_help - point_up_rot2 = point_up_rot2 - y_help - point_down_rot3 = point_down_rot3 - y_help - point_down_rot4 = point_down_rot4 - y_help - - textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) - - textline_boxes.append(np.array([[int(x_min), int(point_up)], [int(x_max), int(point_up)], [int(x_max), int(point_down)], [int(x_min), int(point_down)]])) - - elif len(peaks) < 1: - pass - - elif len(peaks) == 1: - - distances = [cv2.pointPolygonTest(contour_text_interest_copy, (xv[mj], peaks[0] + first_nonzero), True) for mj in range(len(xv))] - distances = np.array(distances) - - xvinside = xv[distances >= 0] - - if len(xvinside) == 0: - x_min = x_min_cont - x_max = x_max_cont - else: - x_min = np.min(xvinside) # max(x_min_interest,x_min_cont) - x_max = np.max(xvinside) # min(x_max_interest,x_max_cont) - # x_min = x_min_cont - # x_max = x_max_cont - - y_min = y_min_cont - y_max = y_max_cont - - p1 = np.dot(rotation_matrix, [int(x_min), int(y_min)]) - p2 = np.dot(rotation_matrix, [int(x_max), int(y_min)]) - p3 = np.dot(rotation_matrix, [int(x_max), int(y_max)]) - p4 = np.dot(rotation_matrix, [int(x_min), int(y_max)]) - - x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d - x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d - x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d - x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d - - if x_min_rot1 < 0: - x_min_rot1 = 0 - if x_min_rot4 < 0: - x_min_rot4 = 0 - if point_up_rot1 < 0: - point_up_rot1 = 0 - if point_up_rot2 < 0: - point_up_rot2 = 0 - - x_min_rot1 = x_min_rot1 - x_help - x_max_rot2 = x_max_rot2 - x_help - x_max_rot3 = x_max_rot3 - x_help - x_min_rot4 = x_min_rot4 - x_help - - point_up_rot1 = point_up_rot1 - y_help - point_up_rot2 = point_up_rot2 - y_help - point_down_rot3 = point_down_rot3 - y_help - point_down_rot4 = point_down_rot4 - y_help - - textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) - - textline_boxes.append(np.array([[int(x_min), int(y_min)], [int(x_max), int(y_min)], [int(x_max), int(y_max)], [int(x_min), int(y_max)]])) - - elif len(peaks) == 2: - dis_to_next = np.abs(peaks[1] - peaks[0]) - for jj in range(len(peaks)): - if jj == 0: - point_up = 0 # peaks[jj] + first_nonzero - int(1. / 1.7 * dis_to_next) - if point_up < 0: - point_up = 1 - point_down = peaks[jj] + first_nonzero + int(1.0 / 1.8 * dis_to_next) - elif jj == 1: - point_down = peaks[jj] + first_nonzero + int(1.0 / 1.8 * dis_to_next) - if point_down >= img_patch.shape[0]: - point_down = img_patch.shape[0] - 2 - point_up = peaks[jj] + first_nonzero - int(1.0 / 1.8 * dis_to_next) - - distances = [cv2.pointPolygonTest(contour_text_interest_copy, (xv[mj], peaks[jj] + first_nonzero), True) for mj in range(len(xv))] - distances = np.array(distances) - - xvinside = xv[distances >= 0] - - if len(xvinside) == 0: - x_min = x_min_cont - x_max = x_max_cont - else: - x_min = np.min(xvinside) - x_max = np.max(xvinside) - - p1 = np.dot(rotation_matrix, [int(x_min), int(point_up)]) - p2 = np.dot(rotation_matrix, [int(x_max), int(point_up)]) - p3 = np.dot(rotation_matrix, [int(x_max), int(point_down)]) - p4 = np.dot(rotation_matrix, [int(x_min), int(point_down)]) - - x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d - x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d - x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d - x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d - - if x_min_rot1 < 0: - x_min_rot1 = 0 - if x_min_rot4 < 0: - x_min_rot4 = 0 - if point_up_rot1 < 0: - point_up_rot1 = 0 - if point_up_rot2 < 0: - point_up_rot2 = 0 - - x_min_rot1 = x_min_rot1 - x_help - x_max_rot2 = x_max_rot2 - x_help - x_max_rot3 = x_max_rot3 - x_help - x_min_rot4 = x_min_rot4 - x_help - - point_up_rot1 = point_up_rot1 - y_help - point_up_rot2 = point_up_rot2 - y_help - point_down_rot3 = point_down_rot3 - y_help - point_down_rot4 = point_down_rot4 - y_help - - textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) - - textline_boxes.append(np.array([[int(x_min), int(point_up)], [int(x_max), int(point_up)], [int(x_max), int(point_down)], [int(x_min), int(point_down)]])) - else: - for jj in range(len(peaks)): - - if jj == 0: - dis_to_next = peaks[jj + 1] - peaks[jj] - # point_up=peaks[jj]+first_nonzero-int(1./3*dis_to_next) - point_up = peaks[jj] + first_nonzero - int(1.0 / 1.9 * dis_to_next) - if point_up < 0: - point_up = 1 - # point_down=peaks[jj]+first_nonzero+int(1./3*dis_to_next) - point_down = peaks[jj] + first_nonzero + int(1.0 / 1.9 * dis_to_next) - elif jj == len(peaks) - 1: - dis_to_next = peaks[jj] - peaks[jj - 1] - # point_down=peaks[jj]+first_nonzero+int(1./3*dis_to_next) - point_down = peaks[jj] + first_nonzero + int(1.0 / 1.7 * dis_to_next) - if point_down >= img_patch.shape[0]: - point_down = img_patch.shape[0] - 2 - # point_up=peaks[jj]+first_nonzero-int(1./3*dis_to_next) - point_up = peaks[jj] + first_nonzero - int(1.0 / 1.9 * dis_to_next) - else: - dis_to_next_down = peaks[jj + 1] - peaks[jj] - dis_to_next_up = peaks[jj] - peaks[jj - 1] - - point_up = peaks[jj] + first_nonzero - int(1.0 / 1.9 * dis_to_next_up) - point_down = peaks[jj] + first_nonzero + int(1.0 / 1.9 * dis_to_next_down) - - distances = [cv2.pointPolygonTest(contour_text_interest_copy, (xv[mj], peaks[jj] + first_nonzero), True) for mj in range(len(xv))] - distances = np.array(distances) - - xvinside = xv[distances >= 0] - - if len(xvinside) == 0: - x_min = x_min_cont - x_max = x_max_cont - else: - x_min = np.min(xvinside) # max(x_min_interest,x_min_cont) - x_max = np.max(xvinside) # min(x_max_interest,x_max_cont) - - p1 = np.dot(rotation_matrix, [int(x_min), int(point_up)]) - p2 = np.dot(rotation_matrix, [int(x_max), int(point_up)]) - p3 = np.dot(rotation_matrix, [int(x_max), int(point_down)]) - p4 = np.dot(rotation_matrix, [int(x_min), int(point_down)]) - - x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d - x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d - x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d - x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d - - if x_min_rot1 < 0: - x_min_rot1 = 0 - if x_min_rot4 < 0: - x_min_rot4 = 0 - if point_up_rot1 < 0: - point_up_rot1 = 0 - if point_up_rot2 < 0: - point_up_rot2 = 0 - - x_min_rot1 = x_min_rot1 - x_help - x_max_rot2 = x_max_rot2 - x_help - x_max_rot3 = x_max_rot3 - x_help - x_min_rot4 = x_min_rot4 - x_help - - point_up_rot1 = point_up_rot1 - y_help - point_up_rot2 = point_up_rot2 - y_help - point_down_rot3 = point_down_rot3 - y_help - point_down_rot4 = point_down_rot4 - y_help - - textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) - - textline_boxes.append(np.array([[int(x_min), int(point_up)], [int(x_max), int(point_up)], [int(x_max), int(point_down)], [int(x_min), int(point_down)]])) - - return peaks, textline_boxes_rot - - def return_rotated_contours(self, slope, img_patch): - dst = rotate_image(img_patch, slope) - dst = dst.astype(np.uint8) - dst = dst[:, :, 0] - dst[dst != 0] = 1 - - imgray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY) - _, thresh = cv2.threshold(imgray, 0, 255, 0) - thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel) - thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) - contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) - return contours - - def seperate_lines_vertical_cont(self, img_patch, contour_text_interest, thetha, box_ind, add_boxes_coor_into_textlines): - kernel = np.ones((5, 5), np.uint8) - pixel = 255 - min_area = 0 - max_area = 1 - - if len(img_patch.shape) == 3: - cnts_images = (img_patch[:, :, 0] == pixel) * 1 - else: - cnts_images = (img_patch[:, :] == pixel) * 1 - cnts_images = cnts_images.astype(np.uint8) - cnts_images = np.repeat(cnts_images[:, :, np.newaxis], 3, axis=2) - imgray = cv2.cvtColor(cnts_images, cv2.COLOR_BGR2GRAY) - ret, thresh = cv2.threshold(imgray, 0, 255, 0) - contours_imgs, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - - contours_imgs = self.return_parent_contours(contours_imgs, hiearchy) - contours_imgs = filter_contours_area_of_image_tables(thresh, contours_imgs, hiearchy, max_area=max_area, min_area=min_area) - - cont_final = [] - ###print(add_boxes_coor_into_textlines,'ikki') - for i in range(len(contours_imgs)): - img_contour = np.zeros((cnts_images.shape[0], cnts_images.shape[1], 3)) - img_contour = cv2.fillPoly(img_contour, pts=[contours_imgs[i]], color=(255, 255, 255)) - - img_contour = img_contour.astype(np.uint8) - - img_contour = cv2.dilate(img_contour, kernel, iterations=4) - imgrayrot = cv2.cvtColor(img_contour, cv2.COLOR_BGR2GRAY) - _, threshrot = cv2.threshold(imgrayrot, 0, 255, 0) - contours_text_rot, _ = cv2.findContours(threshrot.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - - ##contour_text_copy[:, 0, 0] = contour_text_copy[:, 0, 0] - box_ind[ - ##0] - ##contour_text_copy[:, 0, 1] = contour_text_copy[:, 0, 1] - box_ind[1] - ##if add_boxes_coor_into_textlines: - ##print(np.shape(contours_text_rot[0]),'sjppo') - ##contours_text_rot[0][:, 0, 0]=contours_text_rot[0][:, 0, 0] + box_ind[0] - ##contours_text_rot[0][:, 0, 1]=contours_text_rot[0][:, 0, 1] + box_ind[1] - cont_final.append(contours_text_rot[0]) - - ##print(cont_final,'nadizzzz') - return None, cont_final - - def seperate_lines_vertical(self, img_patch, contour_text_interest, thetha): - - thetha = thetha + 90 - - (h, w) = img_patch.shape[:2] - center = (w // 2, h // 2) - M = cv2.getRotationMatrix2D(center, -thetha, 1.0) - x_d = M[0, 2] - y_d = M[1, 2] - - thetha = thetha / 180.0 * np.pi - rotation_matrix = np.array([[np.cos(thetha), -np.sin(thetha)], [np.sin(thetha), np.cos(thetha)]]) - contour_text_interest_copy = contour_text_interest.copy() - - x_cont = contour_text_interest[:, 0, 0] - y_cont = contour_text_interest[:, 0, 1] - x_cont = x_cont - np.min(x_cont) - y_cont = y_cont - np.min(y_cont) - - x_min_cont = 0 - x_max_cont = img_patch.shape[1] - y_min_cont = 0 - y_max_cont = img_patch.shape[0] - - xv = np.linspace(x_min_cont, x_max_cont, 1000) - - textline_patch_sum_along_width = img_patch.sum(axis=0) - - first_nonzero = 0 # (next((i for i, x in enumerate(mada_n) if x), None)) - - y = textline_patch_sum_along_width[:] # [first_nonzero:last_nonzero] - y_padded = np.zeros(len(y) + 40) - y_padded[20 : len(y) + 20] = y - x = np.array(range(len(y))) - - peaks_real, _ = find_peaks(gaussian_filter1d(y, 3), height=0) - if 1 > 0: - - try: - - y_padded_smoothed_e = gaussian_filter1d(y_padded, 2) - y_padded_up_to_down_e = -y_padded + np.max(y_padded) - y_padded_up_to_down_padded_e = np.zeros(len(y_padded_up_to_down_e) + 40) - 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.array(range(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))) - arg_diff_cluster = arg_diff[diff_arg_neg_must_be_deleted > 1] - - peaks_new = peaks_e[:] - peaks_neg_new = peaks_neg_e[:] - - clusters_to_be_deleted = [] - 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[len(arg_diff_cluster) - 1] + 1 :]) - - if len(clusters_to_be_deleted) > 0: - peaks_new_extra = [] - for m in range(len(clusters_to_be_deleted)): - min_cluster = np.min(peaks_e[clusters_to_be_deleted[m]]) - max_cluster = np.max(peaks_e[clusters_to_be_deleted[m]]) - peaks_new_extra.append(int((min_cluster + max_cluster) / 2.0)) - for m1 in range(len(clusters_to_be_deleted[m])): - peaks_new = peaks_new[peaks_new != peaks_e[clusters_to_be_deleted[m][m1] - 1]] - peaks_new = peaks_new[peaks_new != peaks_e[clusters_to_be_deleted[m][m1]]] - - peaks_neg_new = peaks_neg_new[peaks_neg_new != peaks_neg_e[clusters_to_be_deleted[m][m1]]] - peaks_new_tot = [] - for i1 in peaks_new: - peaks_new_tot.append(i1) - for i1 in peaks_new_extra: - peaks_new_tot.append(i1) - peaks_new_tot = np.sort(peaks_new_tot) - - else: - peaks_new_tot = peaks_e[:] - - textline_con, hierachy = self.return_contours_of_image(img_patch) - textline_con_fil = filter_contours_area_of_image(img_patch, textline_con, hierachy, max_area=1, min_area=0.0008) - y_diff_mean = np.mean(np.diff(peaks_new_tot)) # self.find_contours_mean_y_diff(textline_con_fil) - - sigma_gaus = int(y_diff_mean * (7.0 / 40.0)) - # print(sigma_gaus,'sigma_gaus') - except: - sigma_gaus = 12 - if sigma_gaus < 3: - sigma_gaus = 3 - # print(sigma_gaus,'sigma') - - y_padded_smoothed = gaussian_filter1d(y_padded, sigma_gaus) - y_padded_up_to_down = -y_padded + np.max(y_padded) - y_padded_up_to_down_padded = np.zeros(len(y_padded_up_to_down) + 40) - y_padded_up_to_down_padded[20 : len(y_padded_up_to_down) + 20] = y_padded_up_to_down - y_padded_up_to_down_padded = gaussian_filter1d(y_padded_up_to_down_padded, sigma_gaus) - - peaks, _ = find_peaks(y_padded_smoothed, height=0) - peaks_neg, _ = find_peaks(y_padded_up_to_down_padded, height=0) - - # plt.plot(y_padded_up_to_down_padded) - # plt.plot(peaks_neg,y_padded_up_to_down_padded[peaks_neg],'*') - # plt.title('negs') - # plt.show() - - # plt.plot(y_padded_smoothed) - # plt.plot(peaks,y_padded_smoothed[peaks],'*') - # plt.title('poss') - # plt.show() - - neg_peaks_max = np.max(y_padded_up_to_down_padded[peaks_neg]) - - arg_neg_must_be_deleted = np.array(range(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))) - arg_diff_cluster = arg_diff[diff_arg_neg_must_be_deleted > 1] - - peaks_new = peaks[:] - peaks_neg_new = peaks_neg[:] - clusters_to_be_deleted = [] - - if len(arg_diff_cluster) >= 2 and 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[len(arg_diff_cluster) - 1] + 1 :]) - elif len(arg_neg_must_be_deleted) >= 2 and len(arg_diff_cluster) == 0: - clusters_to_be_deleted.append(arg_neg_must_be_deleted[:]) - - if len(arg_neg_must_be_deleted) == 1: - clusters_to_be_deleted.append(arg_neg_must_be_deleted) - - if len(clusters_to_be_deleted) > 0: - peaks_new_extra = [] - for m in range(len(clusters_to_be_deleted)): - min_cluster = np.min(peaks[clusters_to_be_deleted[m]]) - max_cluster = np.max(peaks[clusters_to_be_deleted[m]]) - peaks_new_extra.append(int((min_cluster + max_cluster) / 2.0)) - for m1 in range(len(clusters_to_be_deleted[m])): - peaks_new = peaks_new[peaks_new != peaks[clusters_to_be_deleted[m][m1] - 1]] - peaks_new = peaks_new[peaks_new != peaks[clusters_to_be_deleted[m][m1]]] - - peaks_neg_new = peaks_neg_new[peaks_neg_new != peaks_neg[clusters_to_be_deleted[m][m1]]] - peaks_new_tot = [] - for i1 in peaks_new: - peaks_new_tot.append(i1) - for i1 in peaks_new_extra: - peaks_new_tot.append(i1) - peaks_new_tot = np.sort(peaks_new_tot) - - peaks = peaks_new_tot[:] - peaks_neg = peaks_neg_new[:] - - else: - peaks_new_tot = peaks[:] - peaks = peaks_new_tot[:] - peaks_neg = peaks_neg_new[:] - - mean_value_of_peaks = np.mean(y_padded_smoothed[peaks]) - std_value_of_peaks = np.std(y_padded_smoothed[peaks]) - peaks_values = y_padded_smoothed[peaks] - - peaks_neg = peaks_neg - 20 - 20 - peaks = peaks - 20 - - for jj in range(len(peaks_neg)): - if peaks_neg[jj] > len(x) - 1: - peaks_neg[jj] = len(x) - 1 - - for jj in range(len(peaks)): - if peaks[jj] > len(x) - 1: - peaks[jj] = len(x) - 1 - - textline_boxes = [] - textline_boxes_rot = [] - - if len(peaks_neg) == len(peaks) + 1 and len(peaks) >= 3: - # print('11') - for jj in range(len(peaks)): - - if jj == (len(peaks) - 1): - 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.3 * dis_to_next_up) ##+int(dis_to_next_up*1./4.0) - point_down = x_max_cont - 1 ##peaks[jj] + first_nonzero + int(1.3 * 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) - else: - 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) - 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) - 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_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, (xv[mj], peaks[jj] + first_nonzero), True) for mj in range(len(xv))] - distances = np.array(distances) - - xvinside = xv[distances >= 0] - - if len(xvinside) == 0: - x_min = x_min_cont - x_max = x_max_cont - else: - x_min = np.min(xvinside) # max(x_min_interest,x_min_cont) - x_max = np.max(xvinside) # min(x_max_interest,x_max_cont) - - p1 = np.dot(rotation_matrix, [int(point_up), int(y_min_cont)]) - p2 = np.dot(rotation_matrix, [int(point_down), int(y_min_cont)]) - p3 = np.dot(rotation_matrix, [int(point_down), int(y_max_cont)]) - p4 = np.dot(rotation_matrix, [int(point_up), int(y_max_cont)]) - - x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d - x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d - x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d - x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d - - if x_min_rot1 < 0: - x_min_rot1 = 0 - if x_min_rot4 < 0: - x_min_rot4 = 0 - if point_up_rot1 < 0: - point_up_rot1 = 0 - if point_up_rot2 < 0: - point_up_rot2 = 0 - - textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) - - textline_boxes.append(np.array([[int(x_min), int(point_up)], [int(x_max), int(point_up)], [int(x_max), int(point_down)], [int(x_min), int(point_down)]])) - - elif len(peaks) < 1: - pass - - elif len(peaks) == 1: - x_min = x_min_cont - x_max = x_max_cont - - y_min = y_min_cont - y_max = y_max_cont - - p1 = np.dot(rotation_matrix, [int(point_up), int(y_min_cont)]) - p2 = np.dot(rotation_matrix, [int(point_down), int(y_min_cont)]) - p3 = np.dot(rotation_matrix, [int(point_down), int(y_max_cont)]) - p4 = np.dot(rotation_matrix, [int(point_up), int(y_max_cont)]) - - x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d - x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d - x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d - x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d - - if x_min_rot1 < 0: - x_min_rot1 = 0 - if x_min_rot4 < 0: - x_min_rot4 = 0 - if point_up_rot1 < 0: - point_up_rot1 = 0 - if point_up_rot2 < 0: - point_up_rot2 = 0 - - textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) - - textline_boxes.append(np.array([[int(x_min), int(y_min)], [int(x_max), int(y_min)], [int(x_max), int(y_max)], [int(x_min), int(y_max)]])) - - elif len(peaks) == 2: - dis_to_next = np.abs(peaks[1] - peaks[0]) - for jj in range(len(peaks)): - if jj == 0: - point_up = 0 # peaks[jj] + first_nonzero - int(1. / 1.7 * dis_to_next) - if point_up < 0: - point_up = 1 - point_down = peaks[jj] + first_nonzero + int(1.0 / 1.8 * dis_to_next) - elif jj == 1: - point_down = peaks[jj] + first_nonzero + int(1.0 / 1.8 * dis_to_next) - if point_down >= img_patch.shape[0]: - point_down = img_patch.shape[0] - 2 - point_up = peaks[jj] + first_nonzero - int(1.0 / 1.8 * dis_to_next) - - distances = [cv2.pointPolygonTest(contour_text_interest_copy, (xv[mj], peaks[jj] + first_nonzero), True) for mj in range(len(xv))] - distances = np.array(distances) - - xvinside = xv[distances >= 0] - - if len(xvinside) == 0: - x_min = x_min_cont - x_max = x_max_cont - else: - x_min = np.min(xvinside) - x_max = np.max(xvinside) - - p1 = np.dot(rotation_matrix, [int(point_up), int(y_min_cont)]) - p2 = np.dot(rotation_matrix, [int(point_down), int(y_min_cont)]) - p3 = np.dot(rotation_matrix, [int(point_down), int(y_max_cont)]) - p4 = np.dot(rotation_matrix, [int(point_up), int(y_max_cont)]) - - x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d - x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d - x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d - x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d - - if x_min_rot1 < 0: - x_min_rot1 = 0 - if x_min_rot4 < 0: - x_min_rot4 = 0 - if point_up_rot1 < 0: - point_up_rot1 = 0 - if point_up_rot2 < 0: - point_up_rot2 = 0 - - textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) - - textline_boxes.append(np.array([[int(x_min), int(point_up)], [int(x_max), int(point_up)], [int(x_max), int(point_down)], [int(x_min), int(point_down)]])) - else: - for jj in range(len(peaks)): - - if jj == 0: - dis_to_next = peaks[jj + 1] - peaks[jj] - # point_up=peaks[jj]+first_nonzero-int(1./3*dis_to_next) - point_up = peaks[jj] + first_nonzero - int(1.0 / 1.9 * dis_to_next) - if point_up < 0: - point_up = 1 - # point_down=peaks[jj]+first_nonzero+int(1./3*dis_to_next) - point_down = peaks[jj] + first_nonzero + int(1.0 / 1.9 * dis_to_next) - elif jj == len(peaks) - 1: - dis_to_next = peaks[jj] - peaks[jj - 1] - # point_down=peaks[jj]+first_nonzero+int(1./3*dis_to_next) - point_down = peaks[jj] + first_nonzero + int(1.0 / 1.7 * dis_to_next) - if point_down >= img_patch.shape[0]: - point_down = img_patch.shape[0] - 2 - # point_up=peaks[jj]+first_nonzero-int(1./3*dis_to_next) - point_up = peaks[jj] + first_nonzero - int(1.0 / 1.9 * dis_to_next) - else: - dis_to_next_down = peaks[jj + 1] - peaks[jj] - dis_to_next_up = peaks[jj] - peaks[jj - 1] - - point_up = peaks[jj] + first_nonzero - int(1.0 / 1.9 * dis_to_next_up) - point_down = peaks[jj] + first_nonzero + int(1.0 / 1.9 * dis_to_next_down) - - distances = [cv2.pointPolygonTest(contour_text_interest_copy, (xv[mj], peaks[jj] + first_nonzero), True) for mj in range(len(xv))] - distances = np.array(distances) - - xvinside = xv[distances >= 0] - - if len(xvinside) == 0: - x_min = x_min_cont - x_max = x_max_cont - else: - x_min = np.min(xvinside) # max(x_min_interest,x_min_cont) - x_max = np.max(xvinside) # min(x_max_interest,x_max_cont) - - p1 = np.dot(rotation_matrix, [int(point_up), int(y_min_cont)]) - p2 = np.dot(rotation_matrix, [int(point_down), int(y_min_cont)]) - p3 = np.dot(rotation_matrix, [int(point_down), int(y_max_cont)]) - p4 = np.dot(rotation_matrix, [int(point_up), int(y_max_cont)]) - - x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d - x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d - x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d - x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d - - if x_min_rot1 < 0: - x_min_rot1 = 0 - if x_min_rot4 < 0: - x_min_rot4 = 0 - if point_up_rot1 < 0: - point_up_rot1 = 0 - if point_up_rot2 < 0: - point_up_rot2 = 0 - - textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) - - textline_boxes.append(np.array([[int(x_min), int(point_up)], [int(x_max), int(point_up)], [int(x_max), int(point_down)], [int(x_min), int(point_down)]])) - - return peaks, textline_boxes_rot def textline_contours_postprocessing(self, textline_mask, slope, contour_text_interest, box_ind, slope_first, add_boxes_coor_into_textlines=False): @@ -3475,9 +2187,9 @@ class eynollah: # print('juzaa') if abs(slope) > 45: # print(add_boxes_coor_into_textlines,'avval') - _, contours_rotated_clean = self.seperate_lines_vertical_cont(textline_mask, contours_text_rot[ind_big_con], box_ind, slope, add_boxes_coor_into_textlines=add_boxes_coor_into_textlines) + _, contours_rotated_clean = seperate_lines_vertical_cont(textline_mask, contours_text_rot[ind_big_con], box_ind, slope, add_boxes_coor_into_textlines=add_boxes_coor_into_textlines) else: - _, contours_rotated_clean = self.seperate_lines(dst, contours_text_rot[ind_big_con], slope, x_help, y_help) + _, contours_rotated_clean = seperate_lines(dst, contours_text_rot[ind_big_con], slope, x_help, y_help) except: @@ -3508,7 +2220,7 @@ class eynollah: textline_maskt = textline_mask[:, :, 0] textline_maskt[textline_maskt != 0] = 1 - peaks_point, _ = self.seperate_lines(textline_maskt, contour_interest, slope_new) + peaks_point, _ = seperate_lines(textline_maskt, contour_interest, slope_new) mean_dis = np.mean(np.diff(peaks_point)) @@ -3551,26 +2263,11 @@ class eynollah: return slope - def return_contours_of_image(self, image): - - if len(image.shape) == 2: - image = np.repeat(image[:, :, np.newaxis], 3, axis=2) - image = image.astype(np.uint8) - else: - image = image.astype(np.uint8) - imgray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) - ret, thresh = cv2.threshold(imgray, 0, 255, 0) - contours, hierachy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - return contours, hierachy - def find_contours_mean_y_diff(self, contours_main): M_main = [cv2.moments(contours_main[j]) for j in range(len(contours_main))] cy_main = [(M_main[j]["m01"] / (M_main[j]["m00"] + 1e-32)) for j in range(len(M_main))] return np.mean(np.diff(np.sort(np.array(cy_main)))) - def isNaN(self, num): - return num != num - def find_num_col_olddd(self, regions_without_seperators, sigma_, multiplier=3.8): regions_without_seperators_0 = regions_without_seperators[:, :].sum(axis=1) @@ -3812,7 +2509,7 @@ class eynollah: res_me = VERY_LARGE_NUMBER res_num = 0 var_spectrum = 0 - if self.isNaN(res_me): + if isNaN(res_me): pass else: res.append(res_me) @@ -3856,7 +2553,7 @@ class eynollah: res_me = VERY_LARGE_NUMBER res_num = 0 var_spectrum = 0 - if self.isNaN(res_me): + if isNaN(res_me): pass else: res.append(res_me) @@ -3907,7 +2604,7 @@ class eynollah: res_me = VERY_LARGE_NUMBER res_num = 0 var_spectrum = 0 - if self.isNaN(res_me): + if isNaN(res_me): pass else: res.append(res_me) @@ -3966,7 +2663,7 @@ class eynollah: res_me = VERY_LARGE_NUMBER res_num = 0 var_spectrum = 0 - if self.isNaN(res_me): + if isNaN(res_me): pass else: res.append(res_me) @@ -4012,7 +2709,7 @@ class eynollah: res_me = VERY_LARGE_NUMBER res_num = 0 var_spectrum = 0 - if self.isNaN(res_me): + if isNaN(res_me): pass else: res.append(res_me) @@ -4060,7 +2757,7 @@ class eynollah: res_me = VERY_LARGE_NUMBER res_num = 0 var_spectrum = 0 - if self.isNaN(res_me): + if isNaN(res_me): pass else: res.append(res_me) @@ -4109,7 +2806,7 @@ class eynollah: res_me = VERY_LARGE_NUMBER res_num = 0 var_spectrum = 0 - if self.isNaN(res_me): + if isNaN(res_me): pass else: res.append(res_me) @@ -4155,7 +2852,7 @@ class eynollah: res_me = VERY_LARGE_NUMBER res_num = 0 var_spectrum = 0 - if self.isNaN(res_me): + if isNaN(res_me): pass else: res.append(res_me) @@ -4220,7 +2917,7 @@ class eynollah: res_me = VERY_LARGE_NUMBER res_num = 0 var_spectrum = 0 - if self.isNaN(res_me): + if isNaN(res_me): pass else: res.append(res_me) @@ -4268,7 +2965,7 @@ class eynollah: res_me = VERY_LARGE_NUMBER res_num = 0 var_spectrum = 0 - if self.isNaN(res_me): + if isNaN(res_me): pass else: res.append(res_me) @@ -4299,7 +2996,7 @@ class eynollah: crop_img = cv2.erode(crop_img, self.kernel, iterations=2) try: - textline_con, hierachy = self.return_contours_of_image(crop_img) + textline_con, hierachy = return_contours_of_image(crop_img) textline_con_fil = filter_contours_area_of_image(crop_img, textline_con, hierachy, max_area=1, min_area=0.0008) y_diff_mean = self.find_contours_mean_y_diff(textline_con_fil) @@ -5554,122 +4251,6 @@ class eynollah: tree.write(os.path.join(dir_of_image, self.f_name) + ".xml") # cv2.imwrite(os.path.join(dir_of_image, self.f_name) + ".tif",self.image_org) - def deskew_region_prediction(self, regions_prediction, slope): - image_regions_deskewd = np.zeros(regions_prediction[:, :].shape) - for ind in np.unique(regions_prediction[:, :]): - interest_reg = (regions_prediction[:, :] == ind) * 1 - interest_reg = interest_reg.astype(np.uint8) - deskewed_new = rotate_image(interest_reg, slope) - deskewed_new = deskewed_new[:, :] - deskewed_new[deskewed_new != 0] = ind - - image_regions_deskewd = image_regions_deskewd + deskewed_new - return image_regions_deskewd - - def deskew_erarly(self, textline_mask): - textline_mask_org = np.copy(textline_mask) - # print(textline_mask.shape,np.unique(textline_mask),'hizzzzz') - # slope_new=0#deskew_images(img_patch) - - 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) - - imgray = cv2.cvtColor(textline_mask, cv2.COLOR_BGR2GRAY) - - ret, thresh = cv2.threshold(imgray, 0, 255, 0) - - contours, hirarchy = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - - # print(hirarchy) - - commenst_contours = filter_contours_area_of_image(thresh, contours, hirarchy, max_area=0.01, min_area=0.003) - main_contours = filter_contours_area_of_image(thresh, contours, hirarchy, max_area=1, min_area=0.003) - interior_contours = filter_contours_area_of_image_interiors(thresh, contours, hirarchy, max_area=1, min_area=0) - - img_comm = np.zeros(thresh.shape) - img_comm_in = cv2.fillPoly(img_comm, pts=main_contours, color=(255, 255, 255)) - ###img_comm_in=cv2.fillPoly(img_comm, pts =interior_contours, color=(0,0,0)) - - img_comm_in = np.repeat(img_comm_in[:, :, np.newaxis], 3, axis=2) - img_comm_in = img_comm_in.astype(np.uint8) - - imgray = cv2.cvtColor(img_comm_in, cv2.COLOR_BGR2GRAY) - ##imgray = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) - - ##mask = cv2.inRange(imgray, lower_blue, upper_blue) - ret, thresh = cv2.threshold(imgray, 0, 255, 0) - # print(np.unique(mask)) - ##ret, thresh = cv2.threshold(imgray, 0, 255, 0) - - ##plt.imshow(thresh) - ##plt.show() - - contours, hirarchy = cv2.findContours(thresh.copy(), cv2.cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - - areas = [cv2.contourArea(contours[jj]) for jj in range(len(contours))] - - median_area = np.mean(areas) - contours_slope = contours # self.find_polugons_size_filter(contours,median_area=median_area,scaler_up=100,scaler_down=0.5) - - if len(contours_slope) > 0: - for jv in range(len(contours_slope)): - new_poly = list(contours_slope[jv]) - if jv == 0: - merged_all = new_poly - else: - merged_all = merged_all + new_poly - - merge = np.array(merged_all) - - img_in = np.zeros(textline_mask.shape) - img_p_in = cv2.fillPoly(img_in, pts=[merge], color=(255, 255, 255)) - - ##plt.imshow(img_p_in) - ##plt.show() - - rect = cv2.minAreaRect(merge) - - box = cv2.boxPoints(rect) - - box = np.int0(box) - - indexes = [0, 1, 2, 3] - x_list = box[:, 0] - y_list = box[:, 1] - - index_y_sort = np.argsort(y_list) - - index_upper_left = index_y_sort[np.argmin(x_list[index_y_sort[0:2]])] - index_upper_right = index_y_sort[np.argmax(x_list[index_y_sort[0:2]])] - - index_lower_left = index_y_sort[np.argmin(x_list[index_y_sort[2:]]) + 2] - index_lower_right = index_y_sort[np.argmax(x_list[index_y_sort[2:]]) + 2] - - alpha1 = float(box[index_upper_right][1] - box[index_upper_left][1]) / (float(box[index_upper_right][0] - box[index_upper_left][0])) - alpha2 = float(box[index_lower_right][1] - box[index_lower_left][1]) / (float(box[index_lower_right][0] - box[index_lower_left][0])) - - slope_true = (alpha1 + alpha2) / 2.0 - - # slope=0#slope_true/np.pi*180 - - # if abs(slope)>=1: - # slope=0 - - # dst=rotate_image(textline_mask,slope_true) - # dst=dst[:,:,0] - # dst[dst!=0]=1 - image_regions_deskewd = np.zeros(textline_mask_org[:, :].shape) - for ind in np.unique(textline_mask_org[:, :]): - interest_reg = (textline_mask_org[:, :] == ind) * 1 - interest_reg = interest_reg.astype(np.uint8) - deskewed_new = rotate_image(interest_reg, slope_true) - deskewed_new = deskewed_new[:, :] - deskewed_new[deskewed_new != 0] = ind - - image_regions_deskewd = image_regions_deskewd + deskewed_new - return image_regions_deskewd, slope_true def return_regions_without_seperators(self, regions_pre): kernel = np.ones((5, 5), np.uint8) @@ -5803,13 +4384,13 @@ class eynollah: forest.append(peaks_neg_fin[i + 1]) if diff_peaks[i] > cut_off: # print(forest[np.argmin(z[forest]) ] ) - if not self.isNaN(forest[np.argmin(z[forest])]): + if not isNaN(forest[np.argmin(z[forest])]): peaks_neg_true.append(forest[np.argmin(z[forest])]) forest = [] forest.append(peaks_neg_fin[i + 1]) if i == (len(peaks_neg_fin) - 1): # print(print(forest[np.argmin(z[forest]) ] )) - if not self.isNaN(forest[np.argmin(z[forest])]): + if not isNaN(forest[np.argmin(z[forest])]): peaks_neg_true.append(forest[np.argmin(z[forest])]) num_col = (len(peaks_neg_true)) + 1 @@ -6112,13 +4693,13 @@ class eynollah: forest.append(peaks_neg_fin[i + 1]) if diff_peaks[i] > cut_off: # print(forest[np.argmin(z[forest]) ] ) - if not self.isNaN(forest[np.argmin(z[forest])]): + if not isNaN(forest[np.argmin(z[forest])]): peaks_neg_true.append(forest[np.argmin(z[forest])]) forest = [] forest.append(peaks_neg_fin[i + 1]) if i == (len(peaks_neg_fin) - 1): # print(print(forest[np.argmin(z[forest]) ] )) - if not self.isNaN(forest[np.argmin(z[forest])]): + if not isNaN(forest[np.argmin(z[forest])]): peaks_neg_true.append(forest[np.argmin(z[forest])]) num_col = (len(peaks_neg_true)) + 1 @@ -6589,7 +5170,7 @@ class eynollah: imgray = cv2.cvtColor(seperators_closeup_n, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(imgray, 0, 255, 0) contours_lines, hierachy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - slope_lines, dist_x, x_min_main, x_max_main, cy_main, slope_lines_org, y_min_main, y_max_main, cx_main = self.find_features_of_lines(contours_lines) + slope_lines, dist_x, x_min_main, x_max_main, cy_main, slope_lines_org, y_min_main, y_max_main, cx_main = find_features_of_lines(contours_lines) dist_y = np.abs(y_max_main - y_min_main) @@ -6697,7 +5278,7 @@ class eynollah: contours_lines, hierachy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - slope_lines, dist_x, x_min_main, x_max_main, cy_main, slope_lines_org, y_min_main, y_max_main, cx_main = self.find_features_of_lines(contours_lines) + slope_lines, dist_x, x_min_main, x_max_main, cy_main, slope_lines_org, y_min_main, y_max_main, cx_main = find_features_of_lines(contours_lines) dist_y = np.abs(y_max_main - y_min_main) @@ -6787,7 +5368,7 @@ class eynollah: contours_lines_ver, hierachy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - slope_lines_ver, dist_x_ver, x_min_main_ver, x_max_main_ver, cy_main_ver, slope_lines_org_ver, y_min_main_ver, y_max_main_ver, cx_main_ver = self.find_features_of_lines(contours_lines_ver) + slope_lines_ver, dist_x_ver, x_min_main_ver, x_max_main_ver, cy_main_ver, slope_lines_org_ver, y_min_main_ver, y_max_main_ver, cx_main_ver = find_features_of_lines(contours_lines_ver) for i in range(len(x_min_main_ver)): img_p_in_ver[int(y_min_main_ver[i]) : int(y_min_main_ver[i]) + 30, int(cx_main_ver[i]) - 25 : int(cx_main_ver[i]) + 25, 0] = 0 @@ -6802,7 +5383,7 @@ class eynollah: contours_lines_hor, hierachy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - slope_lines_hor, dist_x_hor, x_min_main_hor, x_max_main_hor, cy_main_hor, slope_lines_org_hor, y_min_main_hor, y_max_main_hor, cx_main_hor = self.find_features_of_lines(contours_lines_hor) + slope_lines_hor, dist_x_hor, x_min_main_hor, x_max_main_hor, cy_main_hor, slope_lines_org_hor, y_min_main_hor, y_max_main_hor, cx_main_hor = find_features_of_lines(contours_lines_hor) args_hor = np.array(range(len(slope_lines_hor))) all_args_uniq = self.contours_in_same_horizon(cy_main_hor) @@ -7753,7 +6334,7 @@ class eynollah: # img_comm=np.repeat(img_comm[:, :, np.newaxis], 3, axis=2) img_comm = img_comm.astype(np.uint8) - if not self.isNaN(slope_mean_hor): + if not isNaN(slope_mean_hor): image_revised_last = np.zeros((image_regions_eraly_p.shape[0], image_regions_eraly_p.shape[1], 3)) for i in range(len(boxes)): @@ -7761,7 +6342,7 @@ class eynollah: image_box_tabels_1 = (image_box[:, :, 0] == 7) * 1 - contours_tab, _ = self.return_contours_of_image(image_box_tabels_1) + contours_tab, _ = return_contours_of_image(image_box_tabels_1) contours_tab = filter_contours_area_of_image_tables(image_box_tabels_1, contours_tab, _, 1, 0.001) @@ -7773,7 +6354,7 @@ class eynollah: image_box_tabels_1 = image_box_tabels_1.astype(np.uint8) image_box_tabels_1 = cv2.dilate(image_box_tabels_1, self.kernel, iterations=5) - contours_table_m_text, _ = self.return_contours_of_image(image_box_tabels_and_m_text) + contours_table_m_text, _ = return_contours_of_image(image_box_tabels_and_m_text) image_box_tabels = np.repeat(image_box_tabels_1[:, :, np.newaxis], 3, axis=2) @@ -7873,13 +6454,13 @@ class eynollah: ret, thresh = cv2.threshold(imgray, 0, 255, 0) contours_head_patch_con, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - contours_head_patch_con = self.return_parent_contours(contours_head_patch_con, hiearchy) + contours_head_patch_con = return_parent_contours(contours_head_patch_con, hiearchy) imgray = cv2.cvtColor(main_patch_con, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(imgray, 0, 255, 0) contours_main_patch_con, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - contours_main_patch_con = self.return_parent_contours(contours_main_patch_con, hiearchy) + contours_main_patch_con = return_parent_contours(contours_main_patch_con, hiearchy) y_patch_head_min, y_patch_head_max, _ = self.find_features_of_contours(contours_head_patch_con) y_patch_main_min, y_patch_main_max, _ = self.find_features_of_contours(contours_main_patch_con) @@ -7905,13 +6486,13 @@ class eynollah: ret, thresh = cv2.threshold(imgray, 0, 255, 0) contours_head_patch_con, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - contours_head_patch_con = self.return_parent_contours(contours_head_patch_con, hiearchy) + contours_head_patch_con = return_parent_contours(contours_head_patch_con, hiearchy) imgray = cv2.cvtColor(main_patch_con, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(imgray, 0, 255, 0) contours_main_patch_con, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - contours_main_patch_con = self.return_parent_contours(contours_main_patch_con, hiearchy) + contours_main_patch_con = return_parent_contours(contours_main_patch_con, hiearchy) _, _, areas_head = self.find_features_of_contours(contours_head_patch_con) _, _, areas_main = self.find_features_of_contours(contours_main_patch_con) @@ -7940,13 +6521,13 @@ class eynollah: ret, thresh = cv2.threshold(imgray, 0, 255, 0) contours_head_patch_con, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - contours_head_patch_con = self.return_parent_contours(contours_head_patch_con, hiearchy) + contours_head_patch_con = return_parent_contours(contours_head_patch_con, hiearchy) imgray = cv2.cvtColor(main_patch_con, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(imgray, 0, 255, 0) contours_main_patch_con, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - contours_main_patch_con = self.return_parent_contours(contours_main_patch_con, hiearchy) + contours_main_patch_con = return_parent_contours(contours_main_patch_con, hiearchy) _, _, areas_head = self.find_features_of_contours(contours_head_patch_con) _, _, areas_main = self.find_features_of_contours(contours_main_patch_con) @@ -8226,7 +6807,7 @@ class eynollah: ret, thresh = cv2.threshold(imgray, 0, 255, 0) contours_imgs, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - contours_imgs = self.return_parent_contours(contours_imgs, hiearchy) + contours_imgs = return_parent_contours(contours_imgs, hiearchy) contours_imgs = filter_contours_area_of_image_tables(thresh, contours_imgs, hiearchy, max_area=1, min_area=0.0003) boxes = [] @@ -8340,7 +6921,7 @@ class eynollah: ret, thresh = cv2.threshold(imgray, 0, 255, 0) contours_line_vers, hierachy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - slope_lines, dist_x, x_min_main, x_max_main, cy_main, slope_lines_org, y_min_main, y_max_main, cx_main = self.find_features_of_lines(contours_line_vers) + slope_lines, dist_x, x_min_main, x_max_main, cy_main, slope_lines_org, y_min_main, y_max_main, cx_main = find_features_of_lines(contours_line_vers) # print(slope_lines,'vertical') args = np.array(range(len(slope_lines))) args_ver = args[slope_lines == 1] @@ -8362,7 +6943,7 @@ class eynollah: ret, thresh = cv2.threshold(imgray, 0, 255, 0) contours_line_hors, hierachy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - slope_lines, dist_x, x_min_main, x_max_main, cy_main, slope_lines_org, y_min_main, y_max_main, cx_main = self.find_features_of_lines(contours_line_hors) + slope_lines, dist_x, x_min_main, x_max_main, cy_main, slope_lines_org, y_min_main, y_max_main, cx_main = find_features_of_lines(contours_line_hors) slope_lines_org_hor = slope_lines_org[slope_lines == 0] args = np.array(range(len(slope_lines))) @@ -8420,7 +7001,7 @@ class eynollah: matrix_of_lines_ch[len(cy_main_hor) :, 9] = 1 if contours_h is not None: - slope_lines_head, dist_x_head, x_min_main_head, x_max_main_head, cy_main_head, slope_lines_org_head, y_min_main_head, y_max_main_head, cx_main_head = self.find_features_of_lines(contours_h) + slope_lines_head, dist_x_head, x_min_main_head, x_max_main_head, cy_main_head, slope_lines_org_head, y_min_main_head, y_max_main_head, cx_main_head = find_features_of_lines(contours_h) matrix_l_n = np.zeros((matrix_of_lines_ch.shape[0] + len(cy_main_head), matrix_of_lines_ch.shape[1])) matrix_l_n[: matrix_of_lines_ch.shape[0], :] = np.copy(matrix_of_lines_ch[:, :]) args_head = np.array(range(len(cy_main_head))) + len(cy_main_hor) @@ -8450,7 +7031,7 @@ class eynollah: contours_lines,hierachy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) - slope_lines,dist_x, x_min_main ,x_max_main ,cy_main,slope_lines_org,y_min_main, y_max_main, cx_main=self.find_features_of_lines(contours_lines) + slope_lines,dist_x, x_min_main ,x_max_main ,cy_main,slope_lines_org,y_min_main, y_max_main, cx_main=find_features_of_lines(contours_lines) slope_lines_org_hor=slope_lines_org[slope_lines==0] args=np.array( range(len(slope_lines) )) @@ -8595,7 +7176,7 @@ class eynollah: ret, thresh = cv2.threshold(imgray, 0, 255, 0) contours_imgs, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - contours_imgs = self.return_parent_contours(contours_imgs, hiearchy) + contours_imgs = return_parent_contours(contours_imgs, hiearchy) contours_imgs = filter_contours_area_of_image_tables(thresh, contours_imgs, hiearchy, max_area=max_area, min_area=min_area) img_ret = np.zeros((region_pre_p.shape[0], region_pre_p.shape[1], 3)) @@ -8673,7 +7254,7 @@ class eynollah: # mask_texts_longshot = cv2.dilate(mask_texts_longshot[:,:], self.kernel, iterations=2) pixel_img = 1 - polygons_of_only_texts_longshot = self.return_contours_of_interested_region(mask_texts_longshot, pixel_img) + polygons_of_only_texts_longshot = return_contours_of_interested_region(mask_texts_longshot, pixel_img) longshot_true = np.zeros(mask_texts_longshot.shape) # text_regions_p_true[:,:]=text_regions_p_1[:,:] @@ -8868,11 +7449,11 @@ class eynollah: mask_lines_only = (text_region2_1st_channel[:, :] == 3) * 1 pixel_img = 1 - polygons_of_only_texts = self.return_contours_of_interested_region(mask_texts_only, pixel_img) + polygons_of_only_texts = return_contours_of_interested_region(mask_texts_only, pixel_img) - polygons_of_only_images = self.return_contours_of_interested_region(mask_images_only, pixel_img) + polygons_of_only_images = return_contours_of_interested_region(mask_images_only, pixel_img) - polygons_of_only_lines = self.return_contours_of_interested_region(mask_lines_only, pixel_img) + polygons_of_only_lines = return_contours_of_interested_region(mask_lines_only, pixel_img) text_regions_p_true = np.zeros(text_region2_1st_channel.shape) # text_regions_p_true[:,:]=text_regions_p_1[:,:] @@ -9331,11 +7912,11 @@ class eynollah: pixel_img = 1 min_area_text = 0.00001 - polygons_of_only_texts = self.return_contours_of_interested_region(mask_texts_only, pixel_img, min_area_text) + polygons_of_only_texts = return_contours_of_interested_region(mask_texts_only, pixel_img, min_area_text) - polygons_of_only_images = self.return_contours_of_interested_region(mask_images_only, pixel_img) + polygons_of_only_images = return_contours_of_interested_region(mask_images_only, pixel_img) - polygons_of_only_lines = self.return_contours_of_interested_region(mask_lines_only, pixel_img, min_area_text) + polygons_of_only_lines = return_contours_of_interested_region(mask_lines_only, pixel_img, min_area_text) text_regions_p_true = np.zeros(prediction_regions_org.shape) # text_regions_p_true[:,:]=text_regions_p_1[:,:] @@ -9366,41 +7947,6 @@ class eynollah: return text_regions_p_true - def get_textregion_contours_in_org_image(self, cnts, img, slope_first): - - cnts_org = [] - # print(cnts,'cnts') - for i in range(len(cnts)): - img_copy = np.zeros(img.shape) - img_copy = cv2.fillPoly(img_copy, pts=[cnts[i]], color=(1, 1, 1)) - - # plt.imshow(img_copy) - # plt.show() - - # print(img.shape,'img') - img_copy = rotation_image_new(img_copy, -slope_first) - ##print(img_copy.shape,'img_copy') - # plt.imshow(img_copy) - # plt.show() - - img_copy = img_copy.astype(np.uint8) - imgray = cv2.cvtColor(img_copy, cv2.COLOR_BGR2GRAY) - ret, thresh = cv2.threshold(imgray, 0, 255, 0) - - cont_int, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - - cont_int[0][:, 0, 0] = cont_int[0][:, 0, 0] + np.abs(img_copy.shape[1] - img.shape[1]) - cont_int[0][:, 0, 1] = cont_int[0][:, 0, 1] + np.abs(img_copy.shape[0] - img.shape[0]) - # print(np.shape(cont_int[0])) - cnts_org.append(cont_int[0]) - - # print(cnts_org,'cnts_org') - - # sys.exit() - self.y_shift = np.abs(img_copy.shape[0] - img.shape[0]) - self.x_shift = np.abs(img_copy.shape[1] - img.shape[1]) - return cnts_org - def write_images_into_directory(self, img_contoures, dir_of_cropped_imgs, image_page): index = 0 for cont_ind in img_contoures: @@ -9566,7 +8112,7 @@ class eynollah: pixel_img = 4 min_area_text = 0.00001 - polygons_of_marginals = self.return_contours_of_interested_region(text_regions, pixel_img, min_area_text) + 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 = self.find_new_features_of_contoures(polygons_of_marginals) @@ -9670,7 +8216,7 @@ class eynollah: # plt.show() pixel_img = 1 - cnt_textlines_in_image = self.return_contours_of_interested_textline(textline_region_in_image, pixel_img) + cnt_textlines_in_image = return_contours_of_interested_textline(textline_region_in_image, pixel_img) textlines_cnt_per_region = [] for jjjj in range(len(cnt_textlines_in_image)): @@ -9683,7 +8229,7 @@ class eynollah: mask_biggest2 = cv2.dilate(mask_biggest2, self.kernel, iterations=4) pixel_img = 1 - cnt_textlines_in_image_ind = self.return_contours_of_interested_textline(mask_biggest2, pixel_img) + 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] / scale_par) @@ -9834,10 +8380,10 @@ class eynollah: def check_any_text_region_in_model_one_is_main_or_header(self, regions_model_1, regions_model_full, contours_only_text_parent, all_box_coord, all_found_texline_polygons, slopes, contours_only_text_parent_d_ordered): text_only = (regions_model_1[:, :] == 1) * 1 - contours_only_text, hir_on_text = self.return_contours_of_image(text_only) + contours_only_text, hir_on_text = return_contours_of_image(text_only) """ - contours_only_text_parent=self.return_parent_contours( contours_only_text,hir_on_text) + contours_only_text_parent=return_parent_contours( contours_only_text,hir_on_text) areas_cnt_text=np.array([cv2.contourArea(contours_only_text_parent[j]) for j in range(len(contours_only_text_parent))]) areas_cnt_text=areas_cnt_text/float(text_only.shape[0]*text_only.shape[1]) @@ -9905,8 +8451,8 @@ class eynollah: def putt_bb_of_drop_capitals_of_model_in_patches_in_layout(self, layout_in_patch): drop_only = (layout_in_patch[:, :, 0] == 4) * 1 - contours_drop, hir_on_drop = self.return_contours_of_image(drop_only) - contours_drop_parent = self.return_parent_contours(contours_drop, hir_on_drop) + contours_drop, hir_on_drop = return_contours_of_image(drop_only) + contours_drop_parent = return_parent_contours(contours_drop, hir_on_drop) 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]) @@ -9923,47 +8469,11 @@ class eynollah: return layout_in_patch - def filter_small_drop_capitals_from_no_patch_layout(self, layout_no_patch, layout1): - - drop_only = (layout_no_patch[:, :, 0] == 4) * 1 - contours_drop, hir_on_drop = self.return_contours_of_image(drop_only) - contours_drop_parent = self.return_parent_contours(contours_drop, hir_on_drop) - - 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] - - areas_cnt_text = [areas_cnt_text[jz] for jz in range(len(areas_cnt_text)) if areas_cnt_text[jz] > 0.001] - - contours_drop_parent_final = [] - - for jj in range(len(contours_drop_parent)): - 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 - height_to_weight_ratio = h / float(w) - weigh_to_height_ratio = w / float(h) - - if iou_of_box_and_contoure > 60 and weigh_to_height_ratio < 1.2 and height_to_weight_ratio < 2: - 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: - contours_drop_parent_final.append(contours_drop_parent[jj]) - - layout_no_patch[:, :, 0][layout_no_patch[:, :, 0] == 4] = 0 - - layout_no_patch = cv2.fillPoly(layout_no_patch, pts=contours_drop_parent_final, color=(4, 4, 4)) - - return layout_no_patch - def put_drop_out_from_only_drop_model(self, layout_no_patch, layout1): drop_only = (layout_no_patch[:, :, 0] == 4) * 1 - contours_drop, hir_on_drop = self.return_contours_of_image(drop_only) - contours_drop_parent = self.return_parent_contours(contours_drop, hir_on_drop) + contours_drop, hir_on_drop = return_contours_of_image(drop_only) + contours_drop_parent = return_parent_contours(contours_drop, hir_on_drop) 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]) @@ -10666,8 +9176,8 @@ class eynollah: ######contours_new,hierachy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) - #####contours_new,hir_new=self.return_contours_of_image(img_con) - #####contours_new_parent=self.return_parent_contours( contours_new,hir_new) + #####contours_new,hir_new=return_contours_of_image(img_con) + #####contours_new_parent=return_parent_contours( contours_new,hir_new) ######plt.imshow(img_con) ######plt.show() #####try: @@ -11057,7 +9567,7 @@ class eynollah: pixel_img = 4 min_area_mar = 0.00001 - polygons_of_marginals = self.return_contours_of_interested_region(text_regions_p, pixel_img, min_area_mar) + polygons_of_marginals = return_contours_of_interested_region(text_regions_p, pixel_img, min_area_mar) if self.full_layout: # set first model with second model @@ -11099,9 +9609,9 @@ class eynollah: if num_col_classifier > 2: regions_fully_np[:, :, 0][regions_fully_np[:, :, 0] == 4] = 0 else: - regions_fully_np = self.filter_small_drop_capitals_from_no_patch_layout(regions_fully_np, text_regions_p) + regions_fully_np = filter_small_drop_capitals_from_no_patch_layout(regions_fully_np, text_regions_p) - # regions_fully_np=self.filter_small_drop_capitals_from_no_patch_layout(regions_fully_np,text_regions_p) + # regions_fully_np=filter_small_drop_capitals_from_no_patch_layout(regions_fully_np,text_regions_p) # plt.imshow(regions_fully_np[:,:,0]) # plt.show() @@ -11111,7 +9621,7 @@ class eynollah: # plt.imshow(regions_fully[:,:,0]) # plt.show() - regions_fully = self.boosting_headers_by_longshot_region_segmentation(regions_fully, regions_fully_np, img_only_regions) + regions_fully = boosting_headers_by_longshot_region_segmentation(regions_fully, regions_fully_np, img_only_regions) # plt.imshow(regions_fully[:,:,0]) # plt.show() @@ -11145,7 +9655,7 @@ class eynollah: # sys.exit() pixel_img = 5 - polygons_of_images = self.return_contours_of_interested_region(img_revised_tab, pixel_img) + polygons_of_images = return_contours_of_interested_region(img_revised_tab, pixel_img) # plt.imshow(img_revised_tab) # plt.show() @@ -11171,8 +9681,8 @@ class eynollah: if np.abs(slope_deskew) >= SLOPE_THRESHOLD: - contours_only_text, hir_on_text = self.return_contours_of_image(text_only) - contours_only_text_parent = self.return_parent_contours(contours_only_text, hir_on_text) + contours_only_text, hir_on_text = return_contours_of_image(text_only) + contours_only_text_parent = return_parent_contours(contours_only_text, hir_on_text) areas_cnt_text = np.array([cv2.contourArea(contours_only_text_parent[j]) for j in range(len(contours_only_text_parent))]) @@ -11189,8 +9699,8 @@ class eynollah: cx_bigest_big, cy_biggest_big, _, _, _, _, _ = self.find_new_features_of_contoures([contours_biggest]) cx_bigest, cy_biggest, _, _, _, _, _ = self.find_new_features_of_contoures(contours_only_text_parent) - contours_only_text_d, hir_on_text_d = self.return_contours_of_image(text_only_d) - contours_only_text_parent_d = self.return_parent_contours(contours_only_text_d, hir_on_text_d) + contours_only_text_d, hir_on_text_d = return_contours_of_image(text_only_d) + contours_only_text_parent_d = return_parent_contours(contours_only_text_d, hir_on_text_d) areas_cnt_text_d = np.array([cv2.contourArea(contours_only_text_parent_d[j]) for j in range(len(contours_only_text_parent_d))]) @@ -11242,8 +9752,8 @@ class eynollah: # plt.show() else: - contours_only_text, hir_on_text = self.return_contours_of_image(text_only) - contours_only_text_parent = self.return_parent_contours(contours_only_text, hir_on_text) + contours_only_text, hir_on_text = return_contours_of_image(text_only) + contours_only_text_parent = return_parent_contours(contours_only_text, hir_on_text) areas_cnt_text = np.array([cv2.contourArea(contours_only_text_parent[j]) for j in range(len(contours_only_text_parent))]) @@ -11269,7 +9779,7 @@ class eynollah: # print(len(contours_only_text_parent),len(contours_only_text_parent_d),'vizzz') - txt_con_org = self.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,_=self.get_text_region_boxes_by_given_contours(contours_only_text_parent) boxes_text, _ = self.get_text_region_boxes_by_given_contours(contours_only_text_parent) @@ -11346,7 +9856,7 @@ class eynollah: polygons_of_tabels = [] pixel_img = 4 - polygons_of_drop_capitals = self.return_contours_of_interested_region_by_min_size(text_regions_p, pixel_img) + polygons_of_drop_capitals = return_contours_of_interested_region_by_min_size(text_regions_p, pixel_img) # polygons_of_drop_capitals=[] all_found_texline_polygons = self.adhere_drop_capital_region_into_cprresponding_textline(text_regions_p, polygons_of_drop_capitals, contours_only_text_parent, contours_only_text_parent_h, all_box_coord, all_box_coord_h, all_found_texline_polygons, all_found_texline_polygons_h) diff --git a/sbb_newspapers_org_image/unused.py b/sbb_newspapers_org_image/unused.py index 8c8c314..022ccce 100644 --- a/sbb_newspapers_org_image/unused.py +++ b/sbb_newspapers_org_image/unused.py @@ -72,7 +72,7 @@ def color_images(seg, n_classes): seg_img[:, :, 2] = segl * c return seg_img -def cleaning_probs(self, probs: np.ndarray, sigma: float) -> np.ndarray: +def cleaning_probs(probs: np.ndarray, sigma: float) -> np.ndarray: # Smooth if sigma > 0.0: return cv2.GaussianBlur(probs, (int(3 * sigma) * 2 + 1, int(3 * sigma) * 2 + 1), sigma) @@ -81,3 +81,194 @@ def cleaning_probs(self, probs: np.ndarray, sigma: float) -> np.ndarray: else: # Negative sigma, do not do anything return probs + +def early_deskewing_slope_calculation_based_on_lines(region_pre_p): + # lines are labels by 6 in this model + seperators_closeup = ((region_pre_p[:, :, :] == 6)) * 1 + + seperators_closeup = seperators_closeup.astype(np.uint8) + imgray = cv2.cvtColor(seperators_closeup, cv2.COLOR_BGR2GRAY) + ret, thresh = cv2.threshold(imgray, 0, 255, 0) + + contours_lines, hierachy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + slope_lines, dist_x, x_min_main, x_max_main, cy_main, slope_lines_org, y_min_main, y_max_main, cx_main = find_features_of_lines(contours_lines) + + slope_lines_org_hor = slope_lines_org[slope_lines == 0] + args = np.array(range(len(slope_lines))) + len_x = seperators_closeup.shape[1] / 4.0 + + args_hor = args[slope_lines == 0] + dist_x_hor = dist_x[slope_lines == 0] + x_min_main_hor = x_min_main[slope_lines == 0] + x_max_main_hor = x_max_main[slope_lines == 0] + cy_main_hor = cy_main[slope_lines == 0] + + args_hor = args_hor[dist_x_hor >= len_x / 2.0] + x_max_main_hor = x_max_main_hor[dist_x_hor >= len_x / 2.0] + x_min_main_hor = x_min_main_hor[dist_x_hor >= len_x / 2.0] + cy_main_hor = cy_main_hor[dist_x_hor >= len_x / 2.0] + slope_lines_org_hor = slope_lines_org_hor[dist_x_hor >= len_x / 2.0] + + slope_lines_org_hor = slope_lines_org_hor[np.abs(slope_lines_org_hor) < 1.2] + slope_mean_hor = np.mean(slope_lines_org_hor) + + if np.abs(slope_mean_hor) > 1.2: + slope_mean_hor = 0 + + # deskewed_new=rotate_image(image_regions_eraly_p[:,:,:],slope_mean_hor) + + args_ver = args[slope_lines == 1] + y_min_main_ver = y_min_main[slope_lines == 1] + y_max_main_ver = y_max_main[slope_lines == 1] + x_min_main_ver = x_min_main[slope_lines == 1] + x_max_main_ver = x_max_main[slope_lines == 1] + cx_main_ver = cx_main[slope_lines == 1] + dist_y_ver = y_max_main_ver - y_min_main_ver + len_y = seperators_closeup.shape[0] / 3.0 + + return slope_mean_hor, cx_main_ver, dist_y_ver + +def boosting_text_only_regions_by_header(textregion_pre_np, img_only_text): + result = ((img_only_text[:, :] == 1) | (textregion_pre_np[:, :, 0] == 2)) * 1 + return result + +def return_rotated_contours(slope, img_patch): + dst = rotate_image(img_patch, slope) + dst = dst.astype(np.uint8) + dst = dst[:, :, 0] + dst[dst != 0] = 1 + + imgray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY) + _, thresh = cv2.threshold(imgray, 0, 255, 0) + thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel) + thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) + contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + return contours + +def get_textlines_for_each_textregions(self, textline_mask_tot, boxes): + textline_mask_tot = cv2.erode(textline_mask_tot, self.kernel, iterations=1) + self.area_of_cropped = [] + self.all_text_region_raw = [] + for jk in range(len(boxes)): + crop_img, crop_coor = crop_image_inside_box(boxes[jk], np.repeat(textline_mask_tot[:, :, np.newaxis], 3, axis=2)) + crop_img = crop_img.astype(np.uint8) + self.all_text_region_raw.append(crop_img[:, :, 0]) + self.area_of_cropped.append(crop_img.shape[0] * crop_img.shape[1]) + +def deskew_region_prediction(regions_prediction, slope): + image_regions_deskewd = np.zeros(regions_prediction[:, :].shape) + for ind in np.unique(regions_prediction[:, :]): + interest_reg = (regions_prediction[:, :] == ind) * 1 + interest_reg = interest_reg.astype(np.uint8) + deskewed_new = rotate_image(interest_reg, slope) + deskewed_new = deskewed_new[:, :] + deskewed_new[deskewed_new != 0] = ind + + image_regions_deskewd = image_regions_deskewd + deskewed_new + return image_regions_deskewd + +def deskew_erarly(textline_mask): + textline_mask_org = np.copy(textline_mask) + # print(textline_mask.shape,np.unique(textline_mask),'hizzzzz') + # slope_new=0#deskew_images(img_patch) + + 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) + + imgray = cv2.cvtColor(textline_mask, cv2.COLOR_BGR2GRAY) + + ret, thresh = cv2.threshold(imgray, 0, 255, 0) + + contours, hirarchy = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + + # print(hirarchy) + + commenst_contours = filter_contours_area_of_image(thresh, contours, hirarchy, max_area=0.01, min_area=0.003) + main_contours = filter_contours_area_of_image(thresh, contours, hirarchy, max_area=1, min_area=0.003) + interior_contours = filter_contours_area_of_image_interiors(thresh, contours, hirarchy, max_area=1, min_area=0) + + img_comm = np.zeros(thresh.shape) + img_comm_in = cv2.fillPoly(img_comm, pts=main_contours, color=(255, 255, 255)) + ###img_comm_in=cv2.fillPoly(img_comm, pts =interior_contours, color=(0,0,0)) + + img_comm_in = np.repeat(img_comm_in[:, :, np.newaxis], 3, axis=2) + img_comm_in = img_comm_in.astype(np.uint8) + + imgray = cv2.cvtColor(img_comm_in, cv2.COLOR_BGR2GRAY) + ##imgray = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) + + ##mask = cv2.inRange(imgray, lower_blue, upper_blue) + ret, thresh = cv2.threshold(imgray, 0, 255, 0) + # print(np.unique(mask)) + ##ret, thresh = cv2.threshold(imgray, 0, 255, 0) + + ##plt.imshow(thresh) + ##plt.show() + + contours, hirarchy = cv2.findContours(thresh.copy(), cv2.cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + + areas = [cv2.contourArea(contours[jj]) for jj in range(len(contours))] + + median_area = np.mean(areas) + contours_slope = contours # self.find_polugons_size_filter(contours,median_area=median_area,scaler_up=100,scaler_down=0.5) + + if len(contours_slope) > 0: + for jv in range(len(contours_slope)): + new_poly = list(contours_slope[jv]) + if jv == 0: + merged_all = new_poly + else: + merged_all = merged_all + new_poly + + merge = np.array(merged_all) + + img_in = np.zeros(textline_mask.shape) + img_p_in = cv2.fillPoly(img_in, pts=[merge], color=(255, 255, 255)) + + ##plt.imshow(img_p_in) + ##plt.show() + + rect = cv2.minAreaRect(merge) + + box = cv2.boxPoints(rect) + + box = np.int0(box) + + indexes = [0, 1, 2, 3] + x_list = box[:, 0] + y_list = box[:, 1] + + index_y_sort = np.argsort(y_list) + + index_upper_left = index_y_sort[np.argmin(x_list[index_y_sort[0:2]])] + index_upper_right = index_y_sort[np.argmax(x_list[index_y_sort[0:2]])] + + index_lower_left = index_y_sort[np.argmin(x_list[index_y_sort[2:]]) + 2] + index_lower_right = index_y_sort[np.argmax(x_list[index_y_sort[2:]]) + 2] + + alpha1 = float(box[index_upper_right][1] - box[index_upper_left][1]) / (float(box[index_upper_right][0] - box[index_upper_left][0])) + alpha2 = float(box[index_lower_right][1] - box[index_lower_left][1]) / (float(box[index_lower_right][0] - box[index_lower_left][0])) + + slope_true = (alpha1 + alpha2) / 2.0 + + # slope=0#slope_true/np.pi*180 + + # if abs(slope)>=1: + # slope=0 + + # dst=rotate_image(textline_mask,slope_true) + # dst=dst[:,:,0] + # dst[dst!=0]=1 + image_regions_deskewd = np.zeros(textline_mask_org[:, :].shape) + for ind in np.unique(textline_mask_org[:, :]): + interest_reg = (textline_mask_org[:, :] == ind) * 1 + interest_reg = interest_reg.astype(np.uint8) + deskewed_new = rotate_image(interest_reg, slope_true) + deskewed_new = deskewed_new[:, :] + deskewed_new[deskewed_new != 0] = ind + + image_regions_deskewd = image_regions_deskewd + deskewed_new + return image_regions_deskewd, slope_true + diff --git a/sbb_newspapers_org_image/utils.py b/sbb_newspapers_org_image/utils.py index b9864f1..b2d9bd7 100644 --- a/sbb_newspapers_org_image/utils.py +++ b/sbb_newspapers_org_image/utils.py @@ -142,3 +142,1318 @@ def otsu_copy_binary(img): img_r = img_r / float(np.max(img_r)) * 255 return img_r + +def return_bonding_box_of_contours(cnts): + boxes_tot = [] + for i in range(len(cnts)): + x, y, w, h = cv2.boundingRect(cnts[i]) + + box = [x, y, w, h] + boxes_tot.append(box) + return boxes_tot + +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))] + cx_main = [(M_main[j]["m10"] / (M_main[j]["m00"] + 1e-32)) for j in range(len(M_main))] + cy_main = [(M_main[j]["m01"] / (M_main[j]["m00"] + 1e-32)) for j in range(len(M_main))] + x_min_main = np.array([np.min(contours_main[j][:, 0, 0]) for j in range(len(contours_main))]) + x_max_main = np.array([np.max(contours_main[j][:, 0, 0]) for j in range(len(contours_main))]) + + y_min_main = np.array([np.min(contours_main[j][:, 0, 1]) for j in range(len(contours_main))]) + y_max_main = np.array([np.max(contours_main[j][:, 0, 1]) for j in range(len(contours_main))]) + + slope_lines = [] + + for kk in range(len(contours_main)): + [vx, vy, x, y] = cv2.fitLine(contours_main[kk], cv2.DIST_L2, 0, 0.01, 0.01) + slope_lines.append(((vy / vx) / np.pi * 180)[0]) + + slope_lines_org = slope_lines + slope_lines = np.array(slope_lines) + slope_lines[(slope_lines < 10) & (slope_lines > -10)] = 0 + + slope_lines[(slope_lines < -200) | (slope_lines > 200)] = 1 + slope_lines[(slope_lines != 0) & (slope_lines != 1)] = 2 + + dis_x = np.abs(x_max_main - x_min_main) + return slope_lines, dis_x, x_min_main, x_max_main, np.array(cy_main), np.array(slope_lines_org), y_min_main, y_max_main, np.array(cx_main) + +def isNaN(num): + return num != num + +def return_parent_contours(contours, hierarchy): + contours_parent = [contours[i] for i in range(len(contours)) if hierarchy[0][i][3] == -1] + return contours_parent + +def return_contours_of_interested_region(region_pre_p, pixel, min_area=0.0002): + + # pixels of images are identified by 5 + if len(region_pre_p.shape) == 3: + cnts_images = (region_pre_p[:, :, 0] == pixel) * 1 + else: + cnts_images = (region_pre_p[:, :] == pixel) * 1 + cnts_images = cnts_images.astype(np.uint8) + cnts_images = np.repeat(cnts_images[:, :, np.newaxis], 3, axis=2) + imgray = cv2.cvtColor(cnts_images, cv2.COLOR_BGR2GRAY) + ret, thresh = cv2.threshold(imgray, 0, 255, 0) + + contours_imgs, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + + contours_imgs = return_parent_contours(contours_imgs, hiearchy) + contours_imgs = filter_contours_area_of_image_tables(thresh, contours_imgs, hiearchy, max_area=1, min_area=min_area) + + return contours_imgs + +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 + headers_in_longshot = (textregion_pre_np[:, :, 0] == 2) * 1 + # headers_in_longshot= ( (textregion_pre_np[:,:,0]==2) | (textregion_pre_np[:,:,0]==1) )*1 + textregion_pre_p[:, :, 0][(headers_in_longshot[:, :] == 1) & (textregion_pre_p[:, :, 0] != 4)] = 2 + textregion_pre_p[:, :, 0][textregion_pre_p[:, :, 0] == 1] = 0 + # textregion_pre_p[:,:,0][( img_only_text[:,:]==1) & (textregion_pre_p[:,:,0]!=7) & (textregion_pre_p[:,:,0]!=2)]=1 # eralier it was so, but by this manner the drop capitals are alse deleted + textregion_pre_p[:, :, 0][(img_only_text[:, :] == 1) & (textregion_pre_p[:, :, 0] != 7) & (textregion_pre_p[:, :, 0] != 4) & (textregion_pre_p[:, :, 0] != 2)] = 1 + return textregion_pre_p + +def return_contours_of_image(image): + + if len(image.shape) == 2: + image = np.repeat(image[:, :, np.newaxis], 3, axis=2) + image = image.astype(np.uint8) + else: + image = image.astype(np.uint8) + imgray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + ret, thresh = cv2.threshold(imgray, 0, 255, 0) + contours, hierachy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + return contours, hierachy + +def return_contours_of_interested_region_by_min_size(region_pre_p, pixel, min_size=0.00003): + + # pixels of images are identified by 5 + if len(region_pre_p.shape) == 3: + cnts_images = (region_pre_p[:, :, 0] == pixel) * 1 + else: + cnts_images = (region_pre_p[:, :] == pixel) * 1 + cnts_images = cnts_images.astype(np.uint8) + cnts_images = np.repeat(cnts_images[:, :, np.newaxis], 3, axis=2) + imgray = cv2.cvtColor(cnts_images, cv2.COLOR_BGR2GRAY) + ret, thresh = cv2.threshold(imgray, 0, 255, 0) + + contours_imgs, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + + contours_imgs = return_parent_contours(contours_imgs, hiearchy) + contours_imgs = filter_contours_area_of_image_tables(thresh, contours_imgs, hiearchy, max_area=1, min_area=min_size) + + return contours_imgs + +def get_textregion_contours_in_org_image(cnts, img, slope_first): + + cnts_org = [] + # print(cnts,'cnts') + for i in range(len(cnts)): + img_copy = np.zeros(img.shape) + img_copy = cv2.fillPoly(img_copy, pts=[cnts[i]], color=(1, 1, 1)) + + # plt.imshow(img_copy) + # plt.show() + + # print(img.shape,'img') + img_copy = rotation_image_new(img_copy, -slope_first) + ##print(img_copy.shape,'img_copy') + # plt.imshow(img_copy) + # plt.show() + + img_copy = img_copy.astype(np.uint8) + imgray = cv2.cvtColor(img_copy, cv2.COLOR_BGR2GRAY) + ret, thresh = cv2.threshold(imgray, 0, 255, 0) + + cont_int, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + + cont_int[0][:, 0, 0] = cont_int[0][:, 0, 0] + np.abs(img_copy.shape[1] - img.shape[1]) + cont_int[0][:, 0, 1] = cont_int[0][:, 0, 1] + np.abs(img_copy.shape[0] - img.shape[0]) + # print(np.shape(cont_int[0])) + cnts_org.append(cont_int[0]) + + # print(cnts_org,'cnts_org') + + # sys.exit() + # self.y_shift = np.abs(img_copy.shape[0] - img.shape[0]) + # self.x_shift = np.abs(img_copy.shape[1] - img.shape[1]) + return cnts_org + +def return_contours_of_interested_textline(region_pre_p, pixel): + + # pixels of images are identified by 5 + if len(region_pre_p.shape) == 3: + cnts_images = (region_pre_p[:, :, 0] == pixel) * 1 + else: + cnts_images = (region_pre_p[:, :] == pixel) * 1 + cnts_images = cnts_images.astype(np.uint8) + cnts_images = np.repeat(cnts_images[:, :, np.newaxis], 3, axis=2) + imgray = cv2.cvtColor(cnts_images, cv2.COLOR_BGR2GRAY) + ret, thresh = cv2.threshold(imgray, 0, 255, 0) + contours_imgs, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + + contours_imgs = return_parent_contours(contours_imgs, hiearchy) + contours_imgs = filter_contours_area_of_image_tables(thresh, contours_imgs, hiearchy, max_area=1, min_area=0.000000003) + return contours_imgs + +def seperate_lines_vertical_cont(img_patch, contour_text_interest, thetha, box_ind, add_boxes_coor_into_textlines): + kernel = np.ones((5, 5), np.uint8) + pixel = 255 + min_area = 0 + max_area = 1 + + if len(img_patch.shape) == 3: + cnts_images = (img_patch[:, :, 0] == pixel) * 1 + else: + cnts_images = (img_patch[:, :] == pixel) * 1 + cnts_images = cnts_images.astype(np.uint8) + cnts_images = np.repeat(cnts_images[:, :, np.newaxis], 3, axis=2) + imgray = cv2.cvtColor(cnts_images, cv2.COLOR_BGR2GRAY) + ret, thresh = cv2.threshold(imgray, 0, 255, 0) + contours_imgs, hiearchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + + contours_imgs = return_parent_contours(contours_imgs, hiearchy) + contours_imgs = filter_contours_area_of_image_tables(thresh, contours_imgs, hiearchy, max_area=max_area, min_area=min_area) + + cont_final = [] + ###print(add_boxes_coor_into_textlines,'ikki') + for i in range(len(contours_imgs)): + img_contour = np.zeros((cnts_images.shape[0], cnts_images.shape[1], 3)) + img_contour = cv2.fillPoly(img_contour, pts=[contours_imgs[i]], color=(255, 255, 255)) + + img_contour = img_contour.astype(np.uint8) + + img_contour = cv2.dilate(img_contour, kernel, iterations=4) + imgrayrot = cv2.cvtColor(img_contour, cv2.COLOR_BGR2GRAY) + _, threshrot = cv2.threshold(imgrayrot, 0, 255, 0) + contours_text_rot, _ = cv2.findContours(threshrot.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + + ##contour_text_copy[:, 0, 0] = contour_text_copy[:, 0, 0] - box_ind[ + ##0] + ##contour_text_copy[:, 0, 1] = contour_text_copy[:, 0, 1] - box_ind[1] + ##if add_boxes_coor_into_textlines: + ##print(np.shape(contours_text_rot[0]),'sjppo') + ##contours_text_rot[0][:, 0, 0]=contours_text_rot[0][:, 0, 0] + box_ind[0] + ##contours_text_rot[0][:, 0, 1]=contours_text_rot[0][:, 0, 1] + box_ind[1] + cont_final.append(contours_text_rot[0]) + + ##print(cont_final,'nadizzzz') + return None, cont_final + + +def seperate_lines(img_patch, contour_text_interest, thetha, x_help, y_help): + + (h, w) = img_patch.shape[:2] + center = (w // 2, h // 2) + M = cv2.getRotationMatrix2D(center, -thetha, 1.0) + x_d = M[0, 2] + y_d = M[1, 2] + + thetha = thetha / 180.0 * np.pi + rotation_matrix = np.array([[np.cos(thetha), -np.sin(thetha)], [np.sin(thetha), np.cos(thetha)]]) + contour_text_interest_copy = contour_text_interest.copy() + + x_cont = contour_text_interest[:, 0, 0] + y_cont = contour_text_interest[:, 0, 1] + x_cont = x_cont - np.min(x_cont) + y_cont = y_cont - np.min(y_cont) + + x_min_cont = 0 + x_max_cont = img_patch.shape[1] + y_min_cont = 0 + y_max_cont = img_patch.shape[0] + + xv = np.linspace(x_min_cont, x_max_cont, 1000) + + textline_patch_sum_along_width = img_patch.sum(axis=1) + + first_nonzero = 0 # (next((i for i, x in enumerate(mada_n) if x), None)) + + y = textline_patch_sum_along_width[:] # [first_nonzero:last_nonzero] + y_padded = np.zeros(len(y) + 40) + y_padded[20 : len(y) + 20] = y + x = np.array(range(len(y))) + + peaks_real, _ = find_peaks(gaussian_filter1d(y, 3), height=0) + + if 1 > 0: + + try: + + y_padded_smoothed_e = gaussian_filter1d(y_padded, 2) + y_padded_up_to_down_e = -y_padded + np.max(y_padded) + y_padded_up_to_down_padded_e = np.zeros(len(y_padded_up_to_down_e) + 40) + 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.array(range(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))) + arg_diff_cluster = arg_diff[diff_arg_neg_must_be_deleted > 1] + + peaks_new = peaks_e[:] + peaks_neg_new = peaks_neg_e[:] + + clusters_to_be_deleted = [] + 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[len(arg_diff_cluster) - 1] + 1 :]) + + if len(clusters_to_be_deleted) > 0: + peaks_new_extra = [] + for m in range(len(clusters_to_be_deleted)): + min_cluster = np.min(peaks_e[clusters_to_be_deleted[m]]) + max_cluster = np.max(peaks_e[clusters_to_be_deleted[m]]) + peaks_new_extra.append(int((min_cluster + max_cluster) / 2.0)) + for m1 in range(len(clusters_to_be_deleted[m])): + peaks_new = peaks_new[peaks_new != peaks_e[clusters_to_be_deleted[m][m1] - 1]] + peaks_new = peaks_new[peaks_new != peaks_e[clusters_to_be_deleted[m][m1]]] + + peaks_neg_new = peaks_neg_new[peaks_neg_new != peaks_neg_e[clusters_to_be_deleted[m][m1]]] + peaks_new_tot = [] + for i1 in peaks_new: + peaks_new_tot.append(i1) + for i1 in peaks_new_extra: + peaks_new_tot.append(i1) + peaks_new_tot = np.sort(peaks_new_tot) + + else: + peaks_new_tot = peaks_e[:] + + textline_con, hierachy = return_contours_of_image(img_patch) + textline_con_fil = filter_contours_area_of_image(img_patch, textline_con, hierachy, max_area=1, min_area=0.0008) + y_diff_mean = np.mean(np.diff(peaks_new_tot)) # self.find_contours_mean_y_diff(textline_con_fil) + + sigma_gaus = int(y_diff_mean * (7.0 / 40.0)) + # print(sigma_gaus,'sigma_gaus') + except: + sigma_gaus = 12 + if sigma_gaus < 3: + sigma_gaus = 3 + # print(sigma_gaus,'sigma') + + y_padded_smoothed = gaussian_filter1d(y_padded, sigma_gaus) + y_padded_up_to_down = -y_padded + np.max(y_padded) + y_padded_up_to_down_padded = np.zeros(len(y_padded_up_to_down) + 40) + y_padded_up_to_down_padded[20 : len(y_padded_up_to_down) + 20] = y_padded_up_to_down + y_padded_up_to_down_padded = gaussian_filter1d(y_padded_up_to_down_padded, sigma_gaus) + + peaks, _ = find_peaks(y_padded_smoothed, height=0) + peaks_neg, _ = find_peaks(y_padded_up_to_down_padded, height=0) + + try: + neg_peaks_max = np.max(y_padded_smoothed[peaks]) + + arg_neg_must_be_deleted = np.array(range(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))) + arg_diff_cluster = arg_diff[diff_arg_neg_must_be_deleted > 1] + except: + arg_neg_must_be_deleted = [] + arg_diff_cluster = [] + + try: + peaks_new = peaks[:] + peaks_neg_new = peaks_neg[:] + clusters_to_be_deleted = [] + + if len(arg_diff_cluster) >= 2 and 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[len(arg_diff_cluster) - 1] + 1 :]) + elif len(arg_neg_must_be_deleted) >= 2 and len(arg_diff_cluster) == 0: + clusters_to_be_deleted.append(arg_neg_must_be_deleted[:]) + + if len(arg_neg_must_be_deleted) == 1: + clusters_to_be_deleted.append(arg_neg_must_be_deleted) + + if len(clusters_to_be_deleted) > 0: + peaks_new_extra = [] + for m in range(len(clusters_to_be_deleted)): + min_cluster = np.min(peaks[clusters_to_be_deleted[m]]) + max_cluster = np.max(peaks[clusters_to_be_deleted[m]]) + peaks_new_extra.append(int((min_cluster + max_cluster) / 2.0)) + for m1 in range(len(clusters_to_be_deleted[m])): + peaks_new = peaks_new[peaks_new != peaks[clusters_to_be_deleted[m][m1] - 1]] + peaks_new = peaks_new[peaks_new != peaks[clusters_to_be_deleted[m][m1]]] + + peaks_neg_new = peaks_neg_new[peaks_neg_new != peaks_neg[clusters_to_be_deleted[m][m1]]] + peaks_new_tot = [] + for i1 in peaks_new: + peaks_new_tot.append(i1) + for i1 in peaks_new_extra: + peaks_new_tot.append(i1) + peaks_new_tot = np.sort(peaks_new_tot) + + ##plt.plot(y_padded_up_to_down_padded) + ##plt.plot(peaks_neg,y_padded_up_to_down_padded[peaks_neg],'*') + ##plt.show() + + ##plt.plot(y_padded_up_to_down_padded) + ##plt.plot(peaks_neg_new,y_padded_up_to_down_padded[peaks_neg_new],'*') + ##plt.show() + + ##plt.plot(y_padded_smoothed) + ##plt.plot(peaks,y_padded_smoothed[peaks],'*') + ##plt.show() + + ##plt.plot(y_padded_smoothed) + ##plt.plot(peaks_new_tot,y_padded_smoothed[peaks_new_tot],'*') + ##plt.show() + + peaks = peaks_new_tot[:] + peaks_neg = peaks_neg_new[:] + + else: + peaks_new_tot = peaks[:] + peaks = peaks_new_tot[:] + peaks_neg = peaks_neg_new[:] + except: + pass + + mean_value_of_peaks = np.mean(y_padded_smoothed[peaks]) + std_value_of_peaks = np.std(y_padded_smoothed[peaks]) + peaks_values = y_padded_smoothed[peaks] + + peaks_neg = peaks_neg - 20 - 20 + peaks = peaks - 20 + + for jj in range(len(peaks_neg)): + if peaks_neg[jj] > len(x) - 1: + peaks_neg[jj] = len(x) - 1 + + for jj in range(len(peaks)): + if peaks[jj] > len(x) - 1: + peaks[jj] = len(x) - 1 + + textline_boxes = [] + textline_boxes_rot = [] + + if len(peaks_neg) == len(peaks) + 1 and len(peaks) >= 3: + for jj in range(len(peaks)): + + if jj == (len(peaks) - 1): + 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.3 * dis_to_next_up) ##+int(dis_to_next_up*1./4.0) + point_down = y_max_cont - 1 ##peaks[jj] + first_nonzero + int(1.3 * 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) + else: + point_up = peaks[jj] + first_nonzero - int(1.4 * dis_to_next_up) ##+int(dis_to_next_up*1./4.0) + point_down = y_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) + 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) + 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_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, (xv[mj], peaks[jj] + first_nonzero), True) for mj in range(len(xv))] + distances = np.array(distances) + + xvinside = xv[distances >= 0] + + if len(xvinside) == 0: + x_min = x_min_cont + x_max = x_max_cont + else: + x_min = np.min(xvinside) # max(x_min_interest,x_min_cont) + x_max = np.max(xvinside) # min(x_max_interest,x_max_cont) + + p1 = np.dot(rotation_matrix, [int(x_min), int(point_up)]) + p2 = np.dot(rotation_matrix, [int(x_max), int(point_up)]) + p3 = np.dot(rotation_matrix, [int(x_max), int(point_down)]) + p4 = np.dot(rotation_matrix, [int(x_min), int(point_down)]) + + x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d + x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d + x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d + x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d + + if x_min_rot1 < 0: + x_min_rot1 = 0 + if x_min_rot4 < 0: + x_min_rot4 = 0 + if point_up_rot1 < 0: + point_up_rot1 = 0 + if point_up_rot2 < 0: + point_up_rot2 = 0 + + x_min_rot1 = x_min_rot1 - x_help + x_max_rot2 = x_max_rot2 - x_help + x_max_rot3 = x_max_rot3 - x_help + x_min_rot4 = x_min_rot4 - x_help + + point_up_rot1 = point_up_rot1 - y_help + point_up_rot2 = point_up_rot2 - y_help + point_down_rot3 = point_down_rot3 - y_help + point_down_rot4 = point_down_rot4 - y_help + + textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) + + textline_boxes.append(np.array([[int(x_min), int(point_up)], [int(x_max), int(point_up)], [int(x_max), int(point_down)], [int(x_min), int(point_down)]])) + + elif len(peaks) < 1: + pass + + elif len(peaks) == 1: + + distances = [cv2.pointPolygonTest(contour_text_interest_copy, (xv[mj], peaks[0] + first_nonzero), True) for mj in range(len(xv))] + distances = np.array(distances) + + xvinside = xv[distances >= 0] + + if len(xvinside) == 0: + x_min = x_min_cont + x_max = x_max_cont + else: + x_min = np.min(xvinside) # max(x_min_interest,x_min_cont) + x_max = np.max(xvinside) # min(x_max_interest,x_max_cont) + # x_min = x_min_cont + # x_max = x_max_cont + + y_min = y_min_cont + y_max = y_max_cont + + p1 = np.dot(rotation_matrix, [int(x_min), int(y_min)]) + p2 = np.dot(rotation_matrix, [int(x_max), int(y_min)]) + p3 = np.dot(rotation_matrix, [int(x_max), int(y_max)]) + p4 = np.dot(rotation_matrix, [int(x_min), int(y_max)]) + + x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d + x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d + x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d + x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d + + if x_min_rot1 < 0: + x_min_rot1 = 0 + if x_min_rot4 < 0: + x_min_rot4 = 0 + if point_up_rot1 < 0: + point_up_rot1 = 0 + if point_up_rot2 < 0: + point_up_rot2 = 0 + + x_min_rot1 = x_min_rot1 - x_help + x_max_rot2 = x_max_rot2 - x_help + x_max_rot3 = x_max_rot3 - x_help + x_min_rot4 = x_min_rot4 - x_help + + point_up_rot1 = point_up_rot1 - y_help + point_up_rot2 = point_up_rot2 - y_help + point_down_rot3 = point_down_rot3 - y_help + point_down_rot4 = point_down_rot4 - y_help + + textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) + + textline_boxes.append(np.array([[int(x_min), int(y_min)], [int(x_max), int(y_min)], [int(x_max), int(y_max)], [int(x_min), int(y_max)]])) + + elif len(peaks) == 2: + dis_to_next = np.abs(peaks[1] - peaks[0]) + for jj in range(len(peaks)): + if jj == 0: + point_up = 0 # peaks[jj] + first_nonzero - int(1. / 1.7 * dis_to_next) + if point_up < 0: + point_up = 1 + point_down = peaks[jj] + first_nonzero + int(1.0 / 1.8 * dis_to_next) + elif jj == 1: + point_down = peaks[jj] + first_nonzero + int(1.0 / 1.8 * dis_to_next) + if point_down >= img_patch.shape[0]: + point_down = img_patch.shape[0] - 2 + point_up = peaks[jj] + first_nonzero - int(1.0 / 1.8 * dis_to_next) + + distances = [cv2.pointPolygonTest(contour_text_interest_copy, (xv[mj], peaks[jj] + first_nonzero), True) for mj in range(len(xv))] + distances = np.array(distances) + + xvinside = xv[distances >= 0] + + if len(xvinside) == 0: + x_min = x_min_cont + x_max = x_max_cont + else: + x_min = np.min(xvinside) + x_max = np.max(xvinside) + + p1 = np.dot(rotation_matrix, [int(x_min), int(point_up)]) + p2 = np.dot(rotation_matrix, [int(x_max), int(point_up)]) + p3 = np.dot(rotation_matrix, [int(x_max), int(point_down)]) + p4 = np.dot(rotation_matrix, [int(x_min), int(point_down)]) + + x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d + x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d + x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d + x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d + + if x_min_rot1 < 0: + x_min_rot1 = 0 + if x_min_rot4 < 0: + x_min_rot4 = 0 + if point_up_rot1 < 0: + point_up_rot1 = 0 + if point_up_rot2 < 0: + point_up_rot2 = 0 + + x_min_rot1 = x_min_rot1 - x_help + x_max_rot2 = x_max_rot2 - x_help + x_max_rot3 = x_max_rot3 - x_help + x_min_rot4 = x_min_rot4 - x_help + + point_up_rot1 = point_up_rot1 - y_help + point_up_rot2 = point_up_rot2 - y_help + point_down_rot3 = point_down_rot3 - y_help + point_down_rot4 = point_down_rot4 - y_help + + textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) + + textline_boxes.append(np.array([[int(x_min), int(point_up)], [int(x_max), int(point_up)], [int(x_max), int(point_down)], [int(x_min), int(point_down)]])) + else: + for jj in range(len(peaks)): + + if jj == 0: + dis_to_next = peaks[jj + 1] - peaks[jj] + # point_up=peaks[jj]+first_nonzero-int(1./3*dis_to_next) + point_up = peaks[jj] + first_nonzero - int(1.0 / 1.9 * dis_to_next) + if point_up < 0: + point_up = 1 + # point_down=peaks[jj]+first_nonzero+int(1./3*dis_to_next) + point_down = peaks[jj] + first_nonzero + int(1.0 / 1.9 * dis_to_next) + elif jj == len(peaks) - 1: + dis_to_next = peaks[jj] - peaks[jj - 1] + # point_down=peaks[jj]+first_nonzero+int(1./3*dis_to_next) + point_down = peaks[jj] + first_nonzero + int(1.0 / 1.7 * dis_to_next) + if point_down >= img_patch.shape[0]: + point_down = img_patch.shape[0] - 2 + # point_up=peaks[jj]+first_nonzero-int(1./3*dis_to_next) + point_up = peaks[jj] + first_nonzero - int(1.0 / 1.9 * dis_to_next) + else: + dis_to_next_down = peaks[jj + 1] - peaks[jj] + dis_to_next_up = peaks[jj] - peaks[jj - 1] + + point_up = peaks[jj] + first_nonzero - int(1.0 / 1.9 * dis_to_next_up) + point_down = peaks[jj] + first_nonzero + int(1.0 / 1.9 * dis_to_next_down) + + distances = [cv2.pointPolygonTest(contour_text_interest_copy, (xv[mj], peaks[jj] + first_nonzero), True) for mj in range(len(xv))] + distances = np.array(distances) + + xvinside = xv[distances >= 0] + + if len(xvinside) == 0: + x_min = x_min_cont + x_max = x_max_cont + else: + x_min = np.min(xvinside) # max(x_min_interest,x_min_cont) + x_max = np.max(xvinside) # min(x_max_interest,x_max_cont) + + p1 = np.dot(rotation_matrix, [int(x_min), int(point_up)]) + p2 = np.dot(rotation_matrix, [int(x_max), int(point_up)]) + p3 = np.dot(rotation_matrix, [int(x_max), int(point_down)]) + p4 = np.dot(rotation_matrix, [int(x_min), int(point_down)]) + + x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d + x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d + x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d + x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d + + if x_min_rot1 < 0: + x_min_rot1 = 0 + if x_min_rot4 < 0: + x_min_rot4 = 0 + if point_up_rot1 < 0: + point_up_rot1 = 0 + if point_up_rot2 < 0: + point_up_rot2 = 0 + + x_min_rot1 = x_min_rot1 - x_help + x_max_rot2 = x_max_rot2 - x_help + x_max_rot3 = x_max_rot3 - x_help + x_min_rot4 = x_min_rot4 - x_help + + point_up_rot1 = point_up_rot1 - y_help + point_up_rot2 = point_up_rot2 - y_help + point_down_rot3 = point_down_rot3 - y_help + point_down_rot4 = point_down_rot4 - y_help + + textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) + + textline_boxes.append(np.array([[int(x_min), int(point_up)], [int(x_max), int(point_up)], [int(x_max), int(point_down)], [int(x_min), int(point_down)]])) + + return peaks, textline_boxes_rot + +def seperate_lines_vertical(img_patch, contour_text_interest, thetha): + + thetha = thetha + 90 + + (h, w) = img_patch.shape[:2] + center = (w // 2, h // 2) + M = cv2.getRotationMatrix2D(center, -thetha, 1.0) + x_d = M[0, 2] + y_d = M[1, 2] + + thetha = thetha / 180.0 * np.pi + rotation_matrix = np.array([[np.cos(thetha), -np.sin(thetha)], [np.sin(thetha), np.cos(thetha)]]) + contour_text_interest_copy = contour_text_interest.copy() + + x_cont = contour_text_interest[:, 0, 0] + y_cont = contour_text_interest[:, 0, 1] + x_cont = x_cont - np.min(x_cont) + y_cont = y_cont - np.min(y_cont) + + x_min_cont = 0 + x_max_cont = img_patch.shape[1] + y_min_cont = 0 + y_max_cont = img_patch.shape[0] + + xv = np.linspace(x_min_cont, x_max_cont, 1000) + + textline_patch_sum_along_width = img_patch.sum(axis=0) + + first_nonzero = 0 # (next((i for i, x in enumerate(mada_n) if x), None)) + + y = textline_patch_sum_along_width[:] # [first_nonzero:last_nonzero] + y_padded = np.zeros(len(y) + 40) + y_padded[20 : len(y) + 20] = y + x = np.array(range(len(y))) + + peaks_real, _ = find_peaks(gaussian_filter1d(y, 3), height=0) + if 1 > 0: + + try: + + y_padded_smoothed_e = gaussian_filter1d(y_padded, 2) + y_padded_up_to_down_e = -y_padded + np.max(y_padded) + y_padded_up_to_down_padded_e = np.zeros(len(y_padded_up_to_down_e) + 40) + 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.array(range(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))) + arg_diff_cluster = arg_diff[diff_arg_neg_must_be_deleted > 1] + + peaks_new = peaks_e[:] + peaks_neg_new = peaks_neg_e[:] + + clusters_to_be_deleted = [] + 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[len(arg_diff_cluster) - 1] + 1 :]) + + if len(clusters_to_be_deleted) > 0: + peaks_new_extra = [] + for m in range(len(clusters_to_be_deleted)): + min_cluster = np.min(peaks_e[clusters_to_be_deleted[m]]) + max_cluster = np.max(peaks_e[clusters_to_be_deleted[m]]) + peaks_new_extra.append(int((min_cluster + max_cluster) / 2.0)) + for m1 in range(len(clusters_to_be_deleted[m])): + peaks_new = peaks_new[peaks_new != peaks_e[clusters_to_be_deleted[m][m1] - 1]] + peaks_new = peaks_new[peaks_new != peaks_e[clusters_to_be_deleted[m][m1]]] + + peaks_neg_new = peaks_neg_new[peaks_neg_new != peaks_neg_e[clusters_to_be_deleted[m][m1]]] + peaks_new_tot = [] + for i1 in peaks_new: + peaks_new_tot.append(i1) + for i1 in peaks_new_extra: + peaks_new_tot.append(i1) + peaks_new_tot = np.sort(peaks_new_tot) + + else: + peaks_new_tot = peaks_e[:] + + textline_con, hierachy = return_contours_of_image(img_patch) + textline_con_fil = filter_contours_area_of_image(img_patch, textline_con, hierachy, max_area=1, min_area=0.0008) + y_diff_mean = np.mean(np.diff(peaks_new_tot)) # self.find_contours_mean_y_diff(textline_con_fil) + + sigma_gaus = int(y_diff_mean * (7.0 / 40.0)) + # print(sigma_gaus,'sigma_gaus') + except: + sigma_gaus = 12 + if sigma_gaus < 3: + sigma_gaus = 3 + # print(sigma_gaus,'sigma') + + y_padded_smoothed = gaussian_filter1d(y_padded, sigma_gaus) + y_padded_up_to_down = -y_padded + np.max(y_padded) + y_padded_up_to_down_padded = np.zeros(len(y_padded_up_to_down) + 40) + y_padded_up_to_down_padded[20 : len(y_padded_up_to_down) + 20] = y_padded_up_to_down + y_padded_up_to_down_padded = gaussian_filter1d(y_padded_up_to_down_padded, sigma_gaus) + + peaks, _ = find_peaks(y_padded_smoothed, height=0) + peaks_neg, _ = find_peaks(y_padded_up_to_down_padded, height=0) + + # plt.plot(y_padded_up_to_down_padded) + # plt.plot(peaks_neg,y_padded_up_to_down_padded[peaks_neg],'*') + # plt.title('negs') + # plt.show() + + # plt.plot(y_padded_smoothed) + # plt.plot(peaks,y_padded_smoothed[peaks],'*') + # plt.title('poss') + # plt.show() + + neg_peaks_max = np.max(y_padded_up_to_down_padded[peaks_neg]) + + arg_neg_must_be_deleted = np.array(range(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))) + arg_diff_cluster = arg_diff[diff_arg_neg_must_be_deleted > 1] + + peaks_new = peaks[:] + peaks_neg_new = peaks_neg[:] + clusters_to_be_deleted = [] + + if len(arg_diff_cluster) >= 2 and 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[len(arg_diff_cluster) - 1] + 1 :]) + elif len(arg_neg_must_be_deleted) >= 2 and len(arg_diff_cluster) == 0: + clusters_to_be_deleted.append(arg_neg_must_be_deleted[:]) + + if len(arg_neg_must_be_deleted) == 1: + clusters_to_be_deleted.append(arg_neg_must_be_deleted) + + if len(clusters_to_be_deleted) > 0: + peaks_new_extra = [] + for m in range(len(clusters_to_be_deleted)): + min_cluster = np.min(peaks[clusters_to_be_deleted[m]]) + max_cluster = np.max(peaks[clusters_to_be_deleted[m]]) + peaks_new_extra.append(int((min_cluster + max_cluster) / 2.0)) + for m1 in range(len(clusters_to_be_deleted[m])): + peaks_new = peaks_new[peaks_new != peaks[clusters_to_be_deleted[m][m1] - 1]] + peaks_new = peaks_new[peaks_new != peaks[clusters_to_be_deleted[m][m1]]] + + peaks_neg_new = peaks_neg_new[peaks_neg_new != peaks_neg[clusters_to_be_deleted[m][m1]]] + peaks_new_tot = [] + for i1 in peaks_new: + peaks_new_tot.append(i1) + for i1 in peaks_new_extra: + peaks_new_tot.append(i1) + peaks_new_tot = np.sort(peaks_new_tot) + + peaks = peaks_new_tot[:] + peaks_neg = peaks_neg_new[:] + + else: + peaks_new_tot = peaks[:] + peaks = peaks_new_tot[:] + peaks_neg = peaks_neg_new[:] + + mean_value_of_peaks = np.mean(y_padded_smoothed[peaks]) + std_value_of_peaks = np.std(y_padded_smoothed[peaks]) + peaks_values = y_padded_smoothed[peaks] + + peaks_neg = peaks_neg - 20 - 20 + peaks = peaks - 20 + + for jj in range(len(peaks_neg)): + if peaks_neg[jj] > len(x) - 1: + peaks_neg[jj] = len(x) - 1 + + for jj in range(len(peaks)): + if peaks[jj] > len(x) - 1: + peaks[jj] = len(x) - 1 + + textline_boxes = [] + textline_boxes_rot = [] + + if len(peaks_neg) == len(peaks) + 1 and len(peaks) >= 3: + # print('11') + for jj in range(len(peaks)): + + if jj == (len(peaks) - 1): + 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.3 * dis_to_next_up) ##+int(dis_to_next_up*1./4.0) + point_down = x_max_cont - 1 ##peaks[jj] + first_nonzero + int(1.3 * 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) + else: + 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) + 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) + 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_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, (xv[mj], peaks[jj] + first_nonzero), True) for mj in range(len(xv))] + distances = np.array(distances) + + xvinside = xv[distances >= 0] + + if len(xvinside) == 0: + x_min = x_min_cont + x_max = x_max_cont + else: + x_min = np.min(xvinside) # max(x_min_interest,x_min_cont) + x_max = np.max(xvinside) # min(x_max_interest,x_max_cont) + + p1 = np.dot(rotation_matrix, [int(point_up), int(y_min_cont)]) + p2 = np.dot(rotation_matrix, [int(point_down), int(y_min_cont)]) + p3 = np.dot(rotation_matrix, [int(point_down), int(y_max_cont)]) + p4 = np.dot(rotation_matrix, [int(point_up), int(y_max_cont)]) + + x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d + x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d + x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d + x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d + + if x_min_rot1 < 0: + x_min_rot1 = 0 + if x_min_rot4 < 0: + x_min_rot4 = 0 + if point_up_rot1 < 0: + point_up_rot1 = 0 + if point_up_rot2 < 0: + point_up_rot2 = 0 + + textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) + + textline_boxes.append(np.array([[int(x_min), int(point_up)], [int(x_max), int(point_up)], [int(x_max), int(point_down)], [int(x_min), int(point_down)]])) + + elif len(peaks) < 1: + pass + + elif len(peaks) == 1: + x_min = x_min_cont + x_max = x_max_cont + + y_min = y_min_cont + y_max = y_max_cont + + p1 = np.dot(rotation_matrix, [int(point_up), int(y_min_cont)]) + p2 = np.dot(rotation_matrix, [int(point_down), int(y_min_cont)]) + p3 = np.dot(rotation_matrix, [int(point_down), int(y_max_cont)]) + p4 = np.dot(rotation_matrix, [int(point_up), int(y_max_cont)]) + + x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d + x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d + x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d + x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d + + if x_min_rot1 < 0: + x_min_rot1 = 0 + if x_min_rot4 < 0: + x_min_rot4 = 0 + if point_up_rot1 < 0: + point_up_rot1 = 0 + if point_up_rot2 < 0: + point_up_rot2 = 0 + + textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) + + textline_boxes.append(np.array([[int(x_min), int(y_min)], [int(x_max), int(y_min)], [int(x_max), int(y_max)], [int(x_min), int(y_max)]])) + + elif len(peaks) == 2: + dis_to_next = np.abs(peaks[1] - peaks[0]) + for jj in range(len(peaks)): + if jj == 0: + point_up = 0 # peaks[jj] + first_nonzero - int(1. / 1.7 * dis_to_next) + if point_up < 0: + point_up = 1 + point_down = peaks[jj] + first_nonzero + int(1.0 / 1.8 * dis_to_next) + elif jj == 1: + point_down = peaks[jj] + first_nonzero + int(1.0 / 1.8 * dis_to_next) + if point_down >= img_patch.shape[0]: + point_down = img_patch.shape[0] - 2 + point_up = peaks[jj] + first_nonzero - int(1.0 / 1.8 * dis_to_next) + + distances = [cv2.pointPolygonTest(contour_text_interest_copy, (xv[mj], peaks[jj] + first_nonzero), True) for mj in range(len(xv))] + distances = np.array(distances) + + xvinside = xv[distances >= 0] + + if len(xvinside) == 0: + x_min = x_min_cont + x_max = x_max_cont + else: + x_min = np.min(xvinside) + x_max = np.max(xvinside) + + p1 = np.dot(rotation_matrix, [int(point_up), int(y_min_cont)]) + p2 = np.dot(rotation_matrix, [int(point_down), int(y_min_cont)]) + p3 = np.dot(rotation_matrix, [int(point_down), int(y_max_cont)]) + p4 = np.dot(rotation_matrix, [int(point_up), int(y_max_cont)]) + + x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d + x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d + x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d + x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d + + if x_min_rot1 < 0: + x_min_rot1 = 0 + if x_min_rot4 < 0: + x_min_rot4 = 0 + if point_up_rot1 < 0: + point_up_rot1 = 0 + if point_up_rot2 < 0: + point_up_rot2 = 0 + + textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) + + textline_boxes.append(np.array([[int(x_min), int(point_up)], [int(x_max), int(point_up)], [int(x_max), int(point_down)], [int(x_min), int(point_down)]])) + else: + for jj in range(len(peaks)): + + if jj == 0: + dis_to_next = peaks[jj + 1] - peaks[jj] + # point_up=peaks[jj]+first_nonzero-int(1./3*dis_to_next) + point_up = peaks[jj] + first_nonzero - int(1.0 / 1.9 * dis_to_next) + if point_up < 0: + point_up = 1 + # point_down=peaks[jj]+first_nonzero+int(1./3*dis_to_next) + point_down = peaks[jj] + first_nonzero + int(1.0 / 1.9 * dis_to_next) + elif jj == len(peaks) - 1: + dis_to_next = peaks[jj] - peaks[jj - 1] + # point_down=peaks[jj]+first_nonzero+int(1./3*dis_to_next) + point_down = peaks[jj] + first_nonzero + int(1.0 / 1.7 * dis_to_next) + if point_down >= img_patch.shape[0]: + point_down = img_patch.shape[0] - 2 + # point_up=peaks[jj]+first_nonzero-int(1./3*dis_to_next) + point_up = peaks[jj] + first_nonzero - int(1.0 / 1.9 * dis_to_next) + else: + dis_to_next_down = peaks[jj + 1] - peaks[jj] + dis_to_next_up = peaks[jj] - peaks[jj - 1] + + point_up = peaks[jj] + first_nonzero - int(1.0 / 1.9 * dis_to_next_up) + point_down = peaks[jj] + first_nonzero + int(1.0 / 1.9 * dis_to_next_down) + + distances = [cv2.pointPolygonTest(contour_text_interest_copy, (xv[mj], peaks[jj] + first_nonzero), True) for mj in range(len(xv))] + distances = np.array(distances) + + xvinside = xv[distances >= 0] + + if len(xvinside) == 0: + x_min = x_min_cont + x_max = x_max_cont + else: + x_min = np.min(xvinside) # max(x_min_interest,x_min_cont) + x_max = np.max(xvinside) # min(x_max_interest,x_max_cont) + + p1 = np.dot(rotation_matrix, [int(point_up), int(y_min_cont)]) + p2 = np.dot(rotation_matrix, [int(point_down), int(y_min_cont)]) + p3 = np.dot(rotation_matrix, [int(point_down), int(y_max_cont)]) + p4 = np.dot(rotation_matrix, [int(point_up), int(y_max_cont)]) + + x_min_rot1, point_up_rot1 = p1[0] + x_d, p1[1] + y_d + x_max_rot2, point_up_rot2 = p2[0] + x_d, p2[1] + y_d + x_max_rot3, point_down_rot3 = p3[0] + x_d, p3[1] + y_d + x_min_rot4, point_down_rot4 = p4[0] + x_d, p4[1] + y_d + + if x_min_rot1 < 0: + x_min_rot1 = 0 + if x_min_rot4 < 0: + x_min_rot4 = 0 + if point_up_rot1 < 0: + point_up_rot1 = 0 + if point_up_rot2 < 0: + point_up_rot2 = 0 + + textline_boxes_rot.append(np.array([[int(x_min_rot1), int(point_up_rot1)], [int(x_max_rot2), int(point_up_rot2)], [int(x_max_rot3), int(point_down_rot3)], [int(x_min_rot4), int(point_down_rot4)]])) + + textline_boxes.append(np.array([[int(x_min), int(point_up)], [int(x_max), int(point_up)], [int(x_max), int(point_down)], [int(x_min), int(point_down)]])) + + return peaks, textline_boxes_rot + +def seperate_lines_new_inside_teils2(img_patch, thetha): + + (h, w) = img_patch.shape[:2] + center = (w // 2, h // 2) + M = cv2.getRotationMatrix2D(center, -thetha, 1.0) + x_d = M[0, 2] + y_d = M[1, 2] + + thetha = thetha / 180.0 * np.pi + rotation_matrix = np.array([[np.cos(thetha), -np.sin(thetha)], [np.sin(thetha), np.cos(thetha)]]) + # contour_text_interest_copy = contour_text_interest.copy() + + # x_cont = contour_text_interest[:, 0, 0] + # y_cont = contour_text_interest[:, 0, 1] + # x_cont = x_cont - np.min(x_cont) + # y_cont = y_cont - np.min(y_cont) + + x_min_cont = 0 + x_max_cont = img_patch.shape[1] + y_min_cont = 0 + y_max_cont = img_patch.shape[0] + + xv = np.linspace(x_min_cont, x_max_cont, 1000) + + textline_patch_sum_along_width = img_patch.sum(axis=1) + + first_nonzero = 0 # (next((i for i, x in enumerate(mada_n) if x), None)) + + y = textline_patch_sum_along_width[:] # [first_nonzero:last_nonzero] + y_padded = np.zeros(len(y) + 40) + y_padded[20 : len(y) + 20] = y + x = np.array(range(len(y))) + + peaks_real, _ = find_peaks(gaussian_filter1d(y, 3), height=0) + if 1 > 0: + + try: + + y_padded_smoothed_e = gaussian_filter1d(y_padded, 2) + y_padded_up_to_down_e = -y_padded + np.max(y_padded) + y_padded_up_to_down_padded_e = np.zeros(len(y_padded_up_to_down_e) + 40) + 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.array(range(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))) + arg_diff_cluster = arg_diff[diff_arg_neg_must_be_deleted > 1] + + peaks_new = peaks_e[:] + peaks_neg_new = peaks_neg_e[:] + + clusters_to_be_deleted = [] + 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[len(arg_diff_cluster) - 1] + 1 :]) + + if len(clusters_to_be_deleted) > 0: + peaks_new_extra = [] + for m in range(len(clusters_to_be_deleted)): + min_cluster = np.min(peaks_e[clusters_to_be_deleted[m]]) + max_cluster = np.max(peaks_e[clusters_to_be_deleted[m]]) + peaks_new_extra.append(int((min_cluster + max_cluster) / 2.0)) + for m1 in range(len(clusters_to_be_deleted[m])): + peaks_new = peaks_new[peaks_new != peaks_e[clusters_to_be_deleted[m][m1] - 1]] + peaks_new = peaks_new[peaks_new != peaks_e[clusters_to_be_deleted[m][m1]]] + + peaks_neg_new = peaks_neg_new[peaks_neg_new != peaks_neg_e[clusters_to_be_deleted[m][m1]]] + peaks_new_tot = [] + for i1 in peaks_new: + peaks_new_tot.append(i1) + for i1 in peaks_new_extra: + peaks_new_tot.append(i1) + peaks_new_tot = np.sort(peaks_new_tot) + + else: + peaks_new_tot = peaks_e[:] + + textline_con, hierachy = return_contours_of_image(img_patch) + textline_con_fil = filter_contours_area_of_image(img_patch, textline_con, hierachy, max_area=1, min_area=0.0008) + y_diff_mean = np.mean(np.diff(peaks_new_tot)) # self.find_contours_mean_y_diff(textline_con_fil) + + sigma_gaus = int(y_diff_mean * (7.0 / 40.0)) + # print(sigma_gaus,'sigma_gaus') + except: + sigma_gaus = 12 + if sigma_gaus < 3: + sigma_gaus = 3 + # print(sigma_gaus,'sigma') + + y_padded_smoothed = gaussian_filter1d(y_padded, sigma_gaus) + y_padded_up_to_down = -y_padded + np.max(y_padded) + y_padded_up_to_down_padded = np.zeros(len(y_padded_up_to_down) + 40) + y_padded_up_to_down_padded[20 : len(y_padded_up_to_down) + 20] = y_padded_up_to_down + y_padded_up_to_down_padded = gaussian_filter1d(y_padded_up_to_down_padded, sigma_gaus) + + peaks, _ = find_peaks(y_padded_smoothed, height=0) + peaks_neg, _ = find_peaks(y_padded_up_to_down_padded, height=0) + + peaks_new = peaks[:] + peaks_neg_new = peaks_neg[:] + + try: + neg_peaks_max = np.max(y_padded_smoothed[peaks]) + + arg_neg_must_be_deleted = np.array(range(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))) + arg_diff_cluster = arg_diff[diff_arg_neg_must_be_deleted > 1] + + clusters_to_be_deleted = [] + + if len(arg_diff_cluster) >= 2 and 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[len(arg_diff_cluster) - 1] + 1 :]) + elif len(arg_neg_must_be_deleted) >= 2 and len(arg_diff_cluster) == 0: + clusters_to_be_deleted.append(arg_neg_must_be_deleted[:]) + + if len(arg_neg_must_be_deleted) == 1: + clusters_to_be_deleted.append(arg_neg_must_be_deleted) + + if len(clusters_to_be_deleted) > 0: + peaks_new_extra = [] + for m in range(len(clusters_to_be_deleted)): + min_cluster = np.min(peaks[clusters_to_be_deleted[m]]) + max_cluster = np.max(peaks[clusters_to_be_deleted[m]]) + peaks_new_extra.append(int((min_cluster + max_cluster) / 2.0)) + for m1 in range(len(clusters_to_be_deleted[m])): + peaks_new = peaks_new[peaks_new != peaks[clusters_to_be_deleted[m][m1] - 1]] + peaks_new = peaks_new[peaks_new != peaks[clusters_to_be_deleted[m][m1]]] + + peaks_neg_new = peaks_neg_new[peaks_neg_new != peaks_neg[clusters_to_be_deleted[m][m1]]] + peaks_new_tot = [] + for i1 in peaks_new: + peaks_new_tot.append(i1) + for i1 in peaks_new_extra: + peaks_new_tot.append(i1) + peaks_new_tot = np.sort(peaks_new_tot) + + # plt.plot(y_padded_up_to_down_padded) + # plt.plot(peaks_neg,y_padded_up_to_down_padded[peaks_neg],'*') + # plt.show() + + # plt.plot(y_padded_up_to_down_padded) + # plt.plot(peaks_neg_new,y_padded_up_to_down_padded[peaks_neg_new],'*') + # plt.show() + + # plt.plot(y_padded_smoothed) + # plt.plot(peaks,y_padded_smoothed[peaks],'*') + # plt.show() + + # plt.plot(y_padded_smoothed) + # plt.plot(peaks_new_tot,y_padded_smoothed[peaks_new_tot],'*') + # plt.show() + + peaks = peaks_new_tot[:] + peaks_neg = peaks_neg_new[:] + except: + pass + + else: + peaks_new_tot = peaks[:] + peaks = peaks_new_tot[:] + peaks_neg = peaks_neg_new[:] + + mean_value_of_peaks = np.mean(y_padded_smoothed[peaks]) + std_value_of_peaks = np.std(y_padded_smoothed[peaks]) + peaks_values = y_padded_smoothed[peaks] + + ###peaks_neg = peaks_neg - 20 - 20 + ###peaks = peaks - 20 + peaks_neg_true = peaks_neg[:] + peaks_pos_true = peaks[:] + + if len(peaks_neg_true) > 0: + peaks_neg_true = np.array(peaks_neg_true) + + peaks_neg_true = peaks_neg_true - 20 - 20 + + # print(peaks_neg_true) + for i in range(len(peaks_neg_true)): + img_patch[peaks_neg_true[i] - 6 : peaks_neg_true[i] + 6, :] = 0 + + else: + pass + + if len(peaks_pos_true) > 0: + peaks_pos_true = np.array(peaks_pos_true) + peaks_pos_true = peaks_pos_true - 20 + + for i in range(len(peaks_pos_true)): + ##img_patch[peaks_pos_true[i]-8:peaks_pos_true[i]+8,:]=1 + img_patch[peaks_pos_true[i] - 6 : peaks_pos_true[i] + 6, :] = 1 + else: + pass + kernel = np.ones((5, 5), np.uint8) + + # img_patch = cv2.erode(img_patch,kernel,iterations = 3) + #######################img_patch = cv2.erode(img_patch,kernel,iterations = 2) + img_patch = cv2.erode(img_patch, kernel, iterations=1) + return img_patch + +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) + + 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] + + areas_cnt_text = [areas_cnt_text[jz] for jz in range(len(areas_cnt_text)) if areas_cnt_text[jz] > 0.001] + + contours_drop_parent_final = [] + + for jj in range(len(contours_drop_parent)): + 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 + height_to_weight_ratio = h / float(w) + weigh_to_height_ratio = w / float(h) + + if iou_of_box_and_contoure > 60 and weigh_to_height_ratio < 1.2 and height_to_weight_ratio < 2: + 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: + contours_drop_parent_final.append(contours_drop_parent[jj]) + + layout_no_patch[:, :, 0][layout_no_patch[:, :, 0] == 4] = 0 + + layout_no_patch = cv2.fillPoly(layout_no_patch, pts=contours_drop_parent_final, color=(4, 4, 4)) + + return layout_no_patch +