mirror of
https://github.com/qurator-spk/eynollah.git
synced 2026-04-30 19:22:03 +02:00
do_work_of_slopes_new_curved (if angle >45°): simplify, improve…
- use new `rotate_image_enlarge` instead of custom (insufficient) padding w/ `rotate_image` - get external contours instead of tree (without checking hierarchy afterwards) - use largest textline contours by area instead of longest polygon path - always use `separate_lines` (but without its incorrect angle/offset calculations) instead of `separate_lines_vertical_cont` - calculate coordinate transformation (shift, angle) for all cases (including >45°) - simplify
This commit is contained in:
parent
dbdb6d0d53
commit
b792324c5b
1 changed files with 58 additions and 74 deletions
|
|
@ -5,8 +5,16 @@ import numpy as np
|
|||
import cv2
|
||||
from scipy.signal import find_peaks
|
||||
from scipy.ndimage import gaussian_filter1d
|
||||
from .rotate import rotate_image
|
||||
from scipy.stats import linregress
|
||||
from ocrd_utils import (
|
||||
shift_coordinates,
|
||||
rotate_coordinates,
|
||||
transform_coordinates,
|
||||
)
|
||||
from .rotate import (
|
||||
rotate_image,
|
||||
rotate_image_enlarge,
|
||||
)
|
||||
from .resize import resize_image
|
||||
from .contour import (
|
||||
return_parent_contours,
|
||||
|
|
@ -1296,95 +1304,71 @@ def separate_lines_new_inside_tiles(img_path, thetha):
|
|||
img_path = cv2.erode(img_path, kernel, iterations=2)
|
||||
return img_path
|
||||
|
||||
def separate_lines_vertical_cont(img_patch, contour_text_interest, thetha, box_ind, add_boxes_coor_into_textlines):
|
||||
def separate_lines_vertical_cont(textline_mask, box_ind):
|
||||
kernel = np.ones((5, 5), np.uint8)
|
||||
label = 255
|
||||
min_area = 0
|
||||
max_area = 1
|
||||
|
||||
if img_patch.ndim == 3:
|
||||
cnts_images = (img_patch[:, :, 0] == label) * 1
|
||||
else:
|
||||
cnts_images = (img_patch[:, :] == label) * 1
|
||||
_, thresh = cv2.threshold(cnts_images.astype(np.uint8), 0, 255, 0)
|
||||
contours_imgs, hierarchy = cv2.findContours(thresh.astype(np.uint8), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
||||
_, thresh = cv2.threshold(textline_mask.astype(np.uint8), 0, 255, 0)
|
||||
contours, hierarchy = cv2.findContours(thresh.astype(np.uint8), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
||||
contours = return_parent_contours(contours, hierarchy)
|
||||
contours = filter_contours_area_of_image_tables(thresh,
|
||||
contours, hierarchy,
|
||||
max_area=max_area,
|
||||
min_area=min_area)
|
||||
contours_final = []
|
||||
for contour in contours:
|
||||
img = np.zeros_like(textline_mask, dtype=np.uint8)
|
||||
img = cv2.fillPoly(img, pts=[contour], color=255)
|
||||
img = cv2.dilate(img, kernel, iterations=4)
|
||||
_, thresh = cv2.threshold(img, 0, 255, 0)
|
||||
contours_text_rot, _ = cv2.findContours(thresh.astype(np.uint8), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
||||
|
||||
contours_imgs = return_parent_contours(contours_imgs, hierarchy)
|
||||
contours_imgs = filter_contours_area_of_image_tables(thresh,
|
||||
contours_imgs, hierarchy,
|
||||
max_area=max_area, min_area=min_area)
|
||||
cont_final = []
|
||||
for i in range(len(contours_imgs)):
|
||||
img_contour = np.zeros(cnts_images.shape[:2], dtype=np.uint8)
|
||||
img_contour = cv2.fillPoly(img_contour, pts=[contours_imgs[i]], color=255)
|
||||
contours_final.append(contours_text_rot[0])
|
||||
|
||||
img_contour = cv2.dilate(img_contour, kernel, iterations=4)
|
||||
_, threshrot = cv2.threshold(img_contour, 0, 255, 0)
|
||||
contours_text_rot, _ = cv2.findContours(threshrot.astype(np.uint8), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
||||
return None, contours_final
|
||||
|
||||
##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:
|
||||
##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])
|
||||
|
||||
return None, cont_final
|
||||
|
||||
def textline_contours_postprocessing(textline_mask, slope,
|
||||
contour_text_interest, box_ind,
|
||||
add_boxes_coor_into_textlines=False):
|
||||
textline_mask = textline_mask * 255
|
||||
def textline_contours_postprocessing(textline_mask, angle, contour_parent, box_ind):
|
||||
x, y, w, h = box_ind
|
||||
label = 255
|
||||
textline_mask = textline_mask * label
|
||||
kernel = np.ones((5, 5), np.uint8)
|
||||
textline_mask = cv2.morphologyEx(textline_mask, cv2.MORPH_OPEN, kernel)
|
||||
textline_mask = cv2.morphologyEx(textline_mask, cv2.MORPH_CLOSE, kernel)
|
||||
textline_mask = cv2.erode(textline_mask, kernel, iterations=2)
|
||||
# textline_mask = cv2.erode(textline_mask, kernel, iterations=1)
|
||||
|
||||
x_help = 30
|
||||
y_help = 2
|
||||
textline_mask_d = rotate_image_enlarge(textline_mask, angle)
|
||||
#textline_mask_d[textline_mask_d != 0] = 1
|
||||
|
||||
textline_mask_help = np.zeros((textline_mask.shape[0] + int(2 * y_help),
|
||||
textline_mask.shape[1] + int(2 * x_help)))
|
||||
textline_mask_help[y_help : y_help + textline_mask.shape[0],
|
||||
x_help : x_help + textline_mask.shape[1]] = np.copy(textline_mask[:, :])
|
||||
# if np.abs(angle)>.5 and textline_mask.shape[0]/float(textline_mask.shape[1])>3:
|
||||
|
||||
dst = rotate_image(textline_mask_help, slope)
|
||||
dst[dst != 0] = 1
|
||||
contour_parent = contour_parent - [x, y]
|
||||
img = np.zeros((h, w), dtype=np.uint8)
|
||||
img = cv2.fillPoly(img, pts=[contour_parent], color=255)
|
||||
img_d = rotate_image_enlarge(img, angle)
|
||||
|
||||
# if np.abs(slope)>.5 and textline_mask.shape[0]/float(textline_mask.shape[1])>3:
|
||||
# plt.imshow(dst)
|
||||
# plt.show()
|
||||
_, thresh = cv2.threshold(img_d, 0, 255, 0)
|
||||
contours_parent_d, _ = cv2.findContours(thresh.astype(np.uint8),
|
||||
cv2.RETR_EXTERNAL,
|
||||
cv2.CHAIN_APPROX_SIMPLE)
|
||||
contour_parent_d = contours_parent_d[
|
||||
np.argmax(map(cv2.contourArea, contours_parent_d))]
|
||||
|
||||
contour_text_copy = contour_text_interest.copy()
|
||||
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]
|
||||
|
||||
img_contour = np.zeros((box_ind[3], box_ind[2]))
|
||||
img_contour = cv2.fillPoly(img_contour, pts=[contour_text_copy], color=255)
|
||||
|
||||
img_contour_help = np.zeros((img_contour.shape[0] + int(2 * y_help),
|
||||
img_contour.shape[1] + int(2 * x_help)))
|
||||
img_contour_help[y_help : y_help + img_contour.shape[0],
|
||||
x_help : x_help + img_contour.shape[1]] = np.copy(img_contour[:, :])
|
||||
|
||||
img_contour_rot = rotate_image(img_contour_help, slope)
|
||||
|
||||
_, threshrot = cv2.threshold(img_contour_rot, 0, 255, 0)
|
||||
contours_text_rot, _ = cv2.findContours(threshrot.astype(np.uint8), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
||||
|
||||
len_con_text_rot = [len(contours_text_rot[ib]) for ib in range(len(contours_text_rot))]
|
||||
ind_big_con = np.argmax(len_con_text_rot)
|
||||
|
||||
if abs(slope) > 45:
|
||||
_, contours_rotated_clean = separate_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 = separate_lines(
|
||||
dst, contours_text_rot[ind_big_con], slope, x_help, y_help)
|
||||
_, contours_rotated_clean = separate_lines(
|
||||
textline_mask_d, contour_parent_d,
|
||||
# already deskewed!
|
||||
#angle, x_off, y_off)
|
||||
0, 0, 0)
|
||||
|
||||
# undo relative coordinates
|
||||
transform = rotate_coordinates(np.eye(3), -angle, 0.5 * np.array([h, w]))
|
||||
transform = shift_coordinates(transform, [x, y])
|
||||
contours_rotated_clean = [np.round(transform_coordinates(contour[:, 0],
|
||||
transform)[:, np.newaxis])
|
||||
.astype(int)
|
||||
for contour in contours_rotated_clean
|
||||
if len(contour) > 3]
|
||||
return contours_rotated_clean
|
||||
|
||||
def separate_lines_new2(img_crop, thetha, num_col, slope_region, logger=None, plotter=None):
|
||||
|
|
@ -1689,8 +1673,8 @@ def do_work_of_slopes_new_curved(
|
|||
logger.error(why)
|
||||
else:
|
||||
textlines_cnt_per_region = textline_contours_postprocessing(all_text_region_raw,
|
||||
slope_for_all, contour_par,
|
||||
box_text, True)
|
||||
slope, contour_par,
|
||||
box_text)
|
||||
|
||||
return textlines_cnt_per_region[::-1], crop_coor, slope
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue