mirror of
https://github.com/qurator-spk/eynollah.git
synced 2025-11-17 01:44:14 +01:00
Merge e428e7ad78 into 38c028c6b5
This commit is contained in:
commit
850221d9ea
7 changed files with 1086 additions and 1414 deletions
|
|
@ -79,18 +79,28 @@ def machine_based_reading_order(input, dir_in, out, model, log_level):
|
||||||
type=click.Path(file_okay=True, dir_okay=True),
|
type=click.Path(file_okay=True, dir_okay=True),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
|
@click.option(
|
||||||
|
"--overwrite",
|
||||||
|
"-O",
|
||||||
|
help="overwrite (instead of skipping) if output xml exists",
|
||||||
|
is_flag=True,
|
||||||
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
"--log_level",
|
"--log_level",
|
||||||
"-l",
|
"-l",
|
||||||
type=click.Choice(['OFF', 'DEBUG', 'INFO', 'WARN', 'ERROR']),
|
type=click.Choice(['OFF', 'DEBUG', 'INFO', 'WARN', 'ERROR']),
|
||||||
help="Override log level globally to this",
|
help="Override log level globally to this",
|
||||||
)
|
)
|
||||||
def binarization(patches, model_dir, input_image, dir_in, output, log_level):
|
def binarization(patches, model_dir, input_image, dir_in, output, overwrite, log_level):
|
||||||
assert bool(input_image) != bool(dir_in), "Either -i (single input) or -di (directory) must be provided, but not both."
|
assert bool(input_image) != bool(dir_in), "Either -i (single input) or -di (directory) must be provided, but not both."
|
||||||
binarizer = SbbBinarizer(model_dir)
|
binarizer = SbbBinarizer(model_dir)
|
||||||
if log_level:
|
if log_level:
|
||||||
binarizer.log.setLevel(getLevelName(log_level))
|
binarizer.logger.setLevel(getLevelName(log_level))
|
||||||
binarizer.run(image_path=input_image, use_patches=patches, output=output, dir_in=dir_in)
|
binarizer.run(overwrite=overwrite,
|
||||||
|
use_patches=patches,
|
||||||
|
image_path=input_image,
|
||||||
|
output=output,
|
||||||
|
dir_in=dir_in)
|
||||||
|
|
||||||
|
|
||||||
@main.command()
|
@main.command()
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -70,7 +70,7 @@ class SbbBinarizeProcessor(Processor):
|
||||||
|
|
||||||
if oplevel == 'page':
|
if oplevel == 'page':
|
||||||
self.logger.info("Binarizing on 'page' level in page '%s'", page_id)
|
self.logger.info("Binarizing on 'page' level in page '%s'", page_id)
|
||||||
page_image_bin = cv2pil(self.binarizer.run(image=pil2cv(page_image), use_patches=True))
|
page_image_bin = cv2pil(self.binarizer.run_single(image=pil2cv(page_image), use_patches=True))
|
||||||
# update PAGE (reference the image file):
|
# update PAGE (reference the image file):
|
||||||
page_image_ref = AlternativeImageType(comments=page_xywh['features'] + ',binarized,clipped')
|
page_image_ref = AlternativeImageType(comments=page_xywh['features'] + ',binarized,clipped')
|
||||||
page.add_AlternativeImage(page_image_ref)
|
page.add_AlternativeImage(page_image_ref)
|
||||||
|
|
@ -83,7 +83,7 @@ class SbbBinarizeProcessor(Processor):
|
||||||
for region in regions:
|
for region in regions:
|
||||||
region_image, region_xywh = self.workspace.image_from_segment(
|
region_image, region_xywh = self.workspace.image_from_segment(
|
||||||
region, page_image, page_xywh, feature_filter='binarized')
|
region, page_image, page_xywh, feature_filter='binarized')
|
||||||
region_image_bin = cv2pil(self.binarizer.run(image=pil2cv(region_image), use_patches=True))
|
region_image_bin = cv2pil(self.binarizer.run_single(image=pil2cv(region_image), use_patches=True))
|
||||||
# update PAGE (reference the image file):
|
# update PAGE (reference the image file):
|
||||||
region_image_ref = AlternativeImageType(comments=region_xywh['features'] + ',binarized')
|
region_image_ref = AlternativeImageType(comments=region_xywh['features'] + ',binarized')
|
||||||
region.add_AlternativeImage(region_image_ref)
|
region.add_AlternativeImage(region_image_ref)
|
||||||
|
|
@ -95,7 +95,7 @@ class SbbBinarizeProcessor(Processor):
|
||||||
self.logger.warning("Page '%s' contains no text lines", page_id)
|
self.logger.warning("Page '%s' contains no text lines", page_id)
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line_image, line_xywh = self.workspace.image_from_segment(line, page_image, page_xywh, feature_filter='binarized')
|
line_image, line_xywh = self.workspace.image_from_segment(line, page_image, page_xywh, feature_filter='binarized')
|
||||||
line_image_bin = cv2pil(self.binarizer.run(image=pil2cv(line_image), use_patches=True))
|
line_image_bin = cv2pil(self.binarizer.run_single(image=pil2cv(line_image), use_patches=True))
|
||||||
# update PAGE (reference the image file):
|
# update PAGE (reference the image file):
|
||||||
line_image_ref = AlternativeImageType(comments=line_xywh['features'] + ',binarized')
|
line_image_ref = AlternativeImageType(comments=line_xywh['features'] + ',binarized')
|
||||||
line.add_AlternativeImage(region_image_ref)
|
line.add_AlternativeImage(region_image_ref)
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class SbbBinarizer:
|
||||||
|
|
||||||
def __init__(self, model_dir, logger=None):
|
def __init__(self, model_dir, logger=None):
|
||||||
self.model_dir = model_dir
|
self.model_dir = model_dir
|
||||||
self.log = logger if logger else logging.getLogger('SbbBinarizer')
|
self.logger = logger if logger else logging.getLogger('SbbBinarizer')
|
||||||
|
|
||||||
self.start_new_session()
|
self.start_new_session()
|
||||||
|
|
||||||
|
|
@ -315,47 +315,30 @@ class SbbBinarizer:
|
||||||
prediction_true = prediction_true.astype(np.uint8)
|
prediction_true = prediction_true.astype(np.uint8)
|
||||||
return prediction_true[:,:,0]
|
return prediction_true[:,:,0]
|
||||||
|
|
||||||
def run(self, image=None, image_path=None, output=None, use_patches=False, dir_in=None):
|
def run(self, image_path=None, output=None, dir_in=None, use_patches=False, overwrite=False):
|
||||||
# print(dir_in,'dir_in')
|
if dir_in:
|
||||||
if not dir_in:
|
ls_imgs = [(os.path.join(dir_in, image_filename),
|
||||||
if (image is not None and image_path is not None) or \
|
os.path.join(output, os.path.splitext(image_filename)[0] + '.png'))
|
||||||
(image is None and image_path is None):
|
for image_filename in filter(is_image_filename,
|
||||||
raise ValueError("Must pass either a opencv2 image or an image_path")
|
os.listdir(dir_in))]
|
||||||
if image_path is not None:
|
|
||||||
image = cv2.imread(image_path)
|
|
||||||
img_last = 0
|
|
||||||
for n, (model, model_file) in enumerate(zip(self.models, self.model_files)):
|
|
||||||
self.log.info('Predicting with model %s [%s/%s]' % (model_file, n + 1, len(self.model_files)))
|
|
||||||
|
|
||||||
res = self.predict(model, image, use_patches)
|
|
||||||
|
|
||||||
img_fin = np.zeros((res.shape[0], res.shape[1], 3))
|
|
||||||
res[:, :][res[:, :] == 0] = 2
|
|
||||||
res = res - 1
|
|
||||||
res = res * 255
|
|
||||||
img_fin[:, :, 0] = res
|
|
||||||
img_fin[:, :, 1] = res
|
|
||||||
img_fin[:, :, 2] = res
|
|
||||||
|
|
||||||
img_fin = img_fin.astype(np.uint8)
|
|
||||||
img_fin = (res[:, :] == 0) * 255
|
|
||||||
img_last = img_last + img_fin
|
|
||||||
|
|
||||||
kernel = np.ones((5, 5), np.uint8)
|
|
||||||
img_last[:, :][img_last[:, :] > 0] = 255
|
|
||||||
img_last = (img_last[:, :] == 0) * 255
|
|
||||||
if output:
|
|
||||||
cv2.imwrite(output, img_last)
|
|
||||||
return img_last
|
|
||||||
else:
|
else:
|
||||||
ls_imgs = list(filter(is_image_filename, os.listdir(dir_in)))
|
ls_imgs = [(image_path, output)]
|
||||||
for image_name in ls_imgs:
|
|
||||||
image_stem = image_name.split('.')[0]
|
for input_path, output_path in ls_imgs:
|
||||||
print(image_name,'image_name')
|
print(input_path, 'image_name')
|
||||||
image = cv2.imread(os.path.join(dir_in,image_name) )
|
if os.path.exists(output_path):
|
||||||
|
if overwrite:
|
||||||
|
self.logger.warning("will overwrite existing output file '%s'", output_path)
|
||||||
|
else:
|
||||||
|
self.logger.warning("will skip input for existing output file '%s'", output_path)
|
||||||
|
image = cv2.imread(input_path)
|
||||||
|
result = self.run_single(image, use_patches)
|
||||||
|
cv2.imwrite(output_path, result)
|
||||||
|
|
||||||
|
def run_single(self, image: np.ndarray, use_patches=False):
|
||||||
img_last = 0
|
img_last = 0
|
||||||
for n, (model, model_file) in enumerate(zip(self.models, self.model_files)):
|
for n, (model, model_file) in enumerate(zip(self.models, self.model_files)):
|
||||||
self.log.info('Predicting with model %s [%s/%s]' % (model_file, n + 1, len(self.model_files)))
|
self.logger.info('Predicting with model %s [%s/%s]' % (model_file, n + 1, len(self.model_files)))
|
||||||
|
|
||||||
res = self.predict(model, image, use_patches)
|
res = self.predict(model, image, use_patches)
|
||||||
|
|
||||||
|
|
@ -374,5 +357,4 @@ class SbbBinarizer:
|
||||||
kernel = np.ones((5, 5), np.uint8)
|
kernel = np.ones((5, 5), np.uint8)
|
||||||
img_last[:, :][img_last[:, :] > 0] = 255
|
img_last[:, :][img_last[:, :] > 0] = 255
|
||||||
img_last = (img_last[:, :] == 0) * 255
|
img_last = (img_last[:, :] == 0) * 255
|
||||||
|
return img_last
|
||||||
cv2.imwrite(os.path.join(output, image_stem + '.png'), img_last)
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -14,21 +14,16 @@ from shapely.ops import unary_union, nearest_points
|
||||||
from .rotate import rotate_image, rotation_image_new
|
from .rotate import rotate_image, rotation_image_new
|
||||||
|
|
||||||
def contours_in_same_horizon(cy_main_hor):
|
def contours_in_same_horizon(cy_main_hor):
|
||||||
X1 = np.zeros((len(cy_main_hor), len(cy_main_hor)))
|
"""
|
||||||
X2 = np.zeros((len(cy_main_hor), len(cy_main_hor)))
|
Takes an array of y coords, identifies all pairs among them
|
||||||
|
which are close to each other, and returns all such pairs
|
||||||
X1[0::1, :] = cy_main_hor[:]
|
by index into the array.
|
||||||
X2 = X1.T
|
"""
|
||||||
|
sort = np.argsort(cy_main_hor)
|
||||||
X_dif = np.abs(X2 - X1)
|
same = np.diff(cy_main_hor[sort] <= 20)
|
||||||
args_help = np.array(range(len(cy_main_hor)))
|
# groups = np.split(sort, np.arange(len(cy_main_hor) - 1)[~same] + 1)
|
||||||
all_args = []
|
same = np.flatnonzero(same)
|
||||||
for i in range(len(cy_main_hor)):
|
return np.stack((sort[:-1][same], sort[1:][same])).T
|
||||||
list_h = list(args_help[X_dif[i, :] <= 20])
|
|
||||||
list_h.append(i)
|
|
||||||
if len(list_h) > 1:
|
|
||||||
all_args.append(list(set(list_h)))
|
|
||||||
return np.unique(np.array(all_args, dtype=object))
|
|
||||||
|
|
||||||
def find_contours_mean_y_diff(contours_main):
|
def find_contours_mean_y_diff(contours_main):
|
||||||
M_main = [cv2.moments(contours_main[j]) for j in range(len(contours_main))]
|
M_main = [cv2.moments(contours_main[j]) for j in range(len(contours_main))]
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ class EynollahXmlWriter:
|
||||||
|
|
||||||
def build_pagexml_no_full_layout(
|
def build_pagexml_no_full_layout(
|
||||||
self, found_polygons_text_region,
|
self, found_polygons_text_region,
|
||||||
page_coord, order_of_texts, id_of_texts,
|
page_coord, order_of_texts,
|
||||||
all_found_textline_polygons,
|
all_found_textline_polygons,
|
||||||
all_box_coord,
|
all_box_coord,
|
||||||
found_polygons_text_region_img,
|
found_polygons_text_region_img,
|
||||||
|
|
@ -102,7 +102,7 @@ class EynollahXmlWriter:
|
||||||
**kwargs):
|
**kwargs):
|
||||||
return self.build_pagexml_full_layout(
|
return self.build_pagexml_full_layout(
|
||||||
found_polygons_text_region, [],
|
found_polygons_text_region, [],
|
||||||
page_coord, order_of_texts, id_of_texts,
|
page_coord, order_of_texts,
|
||||||
all_found_textline_polygons, [],
|
all_found_textline_polygons, [],
|
||||||
all_box_coord, [],
|
all_box_coord, [],
|
||||||
found_polygons_text_region_img, found_polygons_tables, [],
|
found_polygons_text_region_img, found_polygons_tables, [],
|
||||||
|
|
@ -116,7 +116,7 @@ class EynollahXmlWriter:
|
||||||
def build_pagexml_full_layout(
|
def build_pagexml_full_layout(
|
||||||
self,
|
self,
|
||||||
found_polygons_text_region, found_polygons_text_region_h,
|
found_polygons_text_region, found_polygons_text_region_h,
|
||||||
page_coord, order_of_texts, id_of_texts,
|
page_coord, order_of_texts,
|
||||||
all_found_textline_polygons, all_found_textline_polygons_h,
|
all_found_textline_polygons, all_found_textline_polygons_h,
|
||||||
all_box_coord, all_box_coord_h,
|
all_box_coord, all_box_coord_h,
|
||||||
found_polygons_text_region_img, found_polygons_tables, found_polygons_drop_capitals,
|
found_polygons_text_region_img, found_polygons_tables, found_polygons_drop_capitals,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue