From 88d64de67b63fccc41d2d569927b8d790f7837d8 Mon Sep 17 00:00:00 2001 From: Robert Sachunsky Date: Tue, 11 Oct 2022 07:20:38 +0000 Subject: [PATCH 1/9] pil2cv: reduce transparency to white --- sbb_binarize/ocrd_cli.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sbb_binarize/ocrd_cli.py b/sbb_binarize/ocrd_cli.py index 57438d3..9737bad 100644 --- a/sbb_binarize/ocrd_cli.py +++ b/sbb_binarize/ocrd_cli.py @@ -30,6 +30,10 @@ def cv2pil(img): def pil2cv(img): # from ocrd/workspace.py + if img.mode in ('LA', 'RGBA'): + newimg = Image.new(img.mode[:-1], img.size, 'white') + newimg.paste(img, mask=img.getchannel('A')) + img = newimg color_conversion = cv2.COLOR_GRAY2BGR if img.mode in ('1', 'L') else cv2.COLOR_RGB2BGR pil_as_np_array = np.array(img).astype('uint8') if img.mode == '1' else np.array(img) return cv2.cvtColor(pil_as_np_array, color_conversion) From a69470135a717e02b7f5d53701f45258dfdd8ca0 Mon Sep 17 00:00:00 2001 From: Robert Sachunsky Date: Tue, 11 Oct 2022 07:21:17 +0000 Subject: [PATCH 2/9] load_model: also allow SavedModel directories --- sbb_binarize/sbb_binarize.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sbb_binarize/sbb_binarize.py b/sbb_binarize/sbb_binarize.py index 8960354..247d54b 100644 --- a/sbb_binarize/sbb_binarize.py +++ b/sbb_binarize/sbb_binarize.py @@ -34,6 +34,8 @@ class SbbBinarizer: self.start_new_session() self.model_files = glob('%s/*.h5' % self.model_dir) + if not self.model_files: + self.model_files = glob('%s/*/' % self.model_dir) if not self.model_files: raise ValueError(f"No models found in {self.model_dir}") From 56ccb39539d17ceedbfc6e69d6816971ac3c57e8 Mon Sep 17 00:00:00 2001 From: Clemens Neudecker <952378+cneud@users.noreply.github.com> Date: Tue, 11 Oct 2022 11:37:00 +0200 Subject: [PATCH 3/9] Update README * recommend cropping (fix #49) * document huggingface saved_model --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d5cff03..d1f5c8e 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ ## Introduction -This tool performs document image binarization using trained models. The method is based on [Calvo-Zaragoza and Gallego, 2018](https://arxiv.org/abs/1706.10241). +This tool performs document image binarization using a trained ResNet50-UNet model. ## Installation @@ -18,10 +18,14 @@ Clone the repository, enter it and run ### Models -Pre-trained models can be downloaded from here: +Pre-trained models in `h5` format can be downloaded from here: https://qurator-data.de/sbb_binarization/ +We also provide a Tensorflow `saved_model` via Huggingface: + +https://huggingface.co/SBB/sbb_binarization + ## Usage ```sh @@ -32,9 +36,11 @@ sbb_binarize \ ``` -**Note** In virtually all cases, applying the `--patches` flag will improve the quality of results. +In virtually all cases, applying the `--patches` flag will improve the quality of results. + +Images containing a lot of border noise (black pixels) should be cropped beforehand to improve the quality of results. -Example +### Example ```sh sbb_binarize --patches -m /path/to/models/ myimage.tif myimage-bin.tif From f8ade5d3da2649baf47efa62916a1c7d62a14f3d Mon Sep 17 00:00:00 2001 From: Robert Sachunsky <38561704+bertsky@users.noreply.github.com> Date: Tue, 11 Oct 2022 17:19:30 +0200 Subject: [PATCH 4/9] ocrd-tool.json: register SavedModel resources --- sbb_binarize/ocrd-tool.json | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/sbb_binarize/ocrd-tool.json b/sbb_binarize/ocrd-tool.json index 158cb07..2c02d12 100644 --- a/sbb_binarize/ocrd-tool.json +++ b/sbb_binarize/ocrd-tool.json @@ -17,13 +17,31 @@ "description": "PAGE XML hierarchy level to operate on" }, "model": { - "description": "Directory containing HDF5 models. Can be an absolute path or a path relative to the current working directory or $SBB_BINARIZE_DATA environment variable (if set)", + "description": "Directory containing HDF5 or SavedModel/ProtoBuf models. Can be an absolute path or a path relative to the OCR-D resource location, the current working directory or the $SBB_BINARIZE_DATA environment variable (if set)", "type": "string", "format": "uri", "content-type": "text/directory", "required": true } - } + }, + "resources": [ + { + "url": "https://github.com/apacha/sbb_binarization/releases/download/pre-trained-models/model_2020_01_16.zip", + "name": "default", + "type": "archive", + "path_in_archive": "model_2020_01_16", + "size": 562917559, + "description": "default models provided by github.com/qurator-spk" + }, + { + "url": "https://github.com/apacha/sbb_binarization/releases/download/pre-trained-models/model_2021_03_09.zip", + "name": "default-2021-03-09", + "type": "archive", + "path_in_archive": ".", + "size": 133693693, + "description": "updated default models provided by github.com/qurator-spk" + } + ] } } } From 743ca0dbed6b905552bdf5195afa996e55881241 Mon Sep 17 00:00:00 2001 From: Robert Sachunsky <38561704+bertsky@users.noreply.github.com> Date: Tue, 11 Oct 2022 17:20:31 +0200 Subject: [PATCH 5/9] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a847f92..2f57afe 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ numpy setuptools >= 41 opencv-python-headless -ocrd >= 2.22.3 +ocrd >= 2.38.0 tensorflow >= 2.4.0 From 7c3f2176f7ecca60528efe7fadf96cc85d2c9927 Mon Sep 17 00:00:00 2001 From: vahid Date: Tue, 11 Oct 2022 19:18:40 +0200 Subject: [PATCH 6/9] issue #45 the patches option is omitted and it means that documents will be processed in patches while no patches is not desired by the tool --- sbb_binarize/cli.py | 5 +- sbb_binarize/ocrd_cli.py | 6 +- sbb_binarize/sbb_binarize.py | 206 ++++++++++++++++------------------- 3 files changed, 100 insertions(+), 117 deletions(-) diff --git a/sbb_binarize/cli.py b/sbb_binarize/cli.py index 0077bef..ddfbde6 100644 --- a/sbb_binarize/cli.py +++ b/sbb_binarize/cli.py @@ -7,9 +7,8 @@ from .sbb_binarize import SbbBinarizer @command() @version_option() -@option('--patches/--no-patches', default=True, help='by enabling this parameter you let the model to see the image in patches.') @option('--model-dir', '-m', type=types.Path(exists=True, file_okay=False), required=True, help='directory containing models for prediction') @argument('input_image') @argument('output_image') -def main(patches, model_dir, input_image, output_image): - SbbBinarizer(model_dir).run(image_path=input_image, use_patches=patches, save=output_image) +def main(model_dir, input_image, output_image): + SbbBinarizer(model_dir).run(image_path=input_image, save=output_image) diff --git a/sbb_binarize/ocrd_cli.py b/sbb_binarize/ocrd_cli.py index 9737bad..44a001f 100644 --- a/sbb_binarize/ocrd_cli.py +++ b/sbb_binarize/ocrd_cli.py @@ -110,7 +110,7 @@ class SbbBinarizeProcessor(Processor): if oplevel == 'page': LOG.info("Binarizing on 'page' level in page '%s'", page_id) - bin_image = cv2pil(self.binarizer.run(image=pil2cv(page_image), use_patches=True)) + bin_image = cv2pil(self.binarizer.run(image=pil2cv(page_image))) # update METS (add the image file): bin_image_path = self.workspace.save_image_file(bin_image, file_id + '.IMG-BIN', @@ -124,7 +124,7 @@ class SbbBinarizeProcessor(Processor): LOG.warning("Page '%s' contains no text/table regions", page_id) for region in regions: region_image, region_xywh = self.workspace.image_from_segment(region, page_image, page_xywh, feature_filter='binarized') - region_image_bin = cv2pil(binarizer.run(image=pil2cv(region_image), use_patches=True)) + region_image_bin = cv2pil(binarizer.run(image=pil2cv(region_image))) region_image_bin_path = self.workspace.save_image_file( region_image_bin, "%s_%s.IMG-BIN" % (file_id, region.id), @@ -139,7 +139,7 @@ class SbbBinarizeProcessor(Processor): LOG.warning("Page '%s' contains no text lines", page_id) for region_id, line in region_line_tuples: line_image, line_xywh = self.workspace.image_from_segment(line, page_image, page_xywh, feature_filter='binarized') - line_image_bin = cv2pil(binarizer.run(image=pil2cv(line_image), use_patches=True)) + line_image_bin = cv2pil(binarizer.run(image=pil2cv(line_image))) line_image_bin_path = self.workspace.save_image_file( line_image_bin, "%s_%s_%s.IMG-BIN" % (file_id, region_id, line.id), diff --git a/sbb_binarize/sbb_binarize.py b/sbb_binarize/sbb_binarize.py index 247d54b..7016020 100644 --- a/sbb_binarize/sbb_binarize.py +++ b/sbb_binarize/sbb_binarize.py @@ -62,7 +62,7 @@ class SbbBinarizer: n_classes = model.layers[len(model.layers)-1].output_shape[3] return model, model_height, model_width, n_classes - def predict(self, model_in, img, use_patches): + def predict(self, model_in, img): tensorflow_backend.set_session(self.session) model, model_height, model_width, n_classes = model_in @@ -101,152 +101,136 @@ class SbbBinarizer: img = np.copy(img_padded) - - - - if use_patches: - - margin = int(0.1 * model_width) - width_mid = model_width - 2 * margin - height_mid = model_height - 2 * margin + margin = int(0.1 * model_width) + width_mid = model_width - 2 * margin + height_mid = model_height - 2 * margin - img = img / float(255.0) - img_h = img.shape[0] - img_w = img.shape[1] + img = img / float(255.0) - prediction_true = np.zeros((img_h, img_w, 3)) - mask_true = np.zeros((img_h, img_w)) - nxf = img_w / float(width_mid) - nyf = img_h / float(height_mid) + img_h = img.shape[0] + img_w = img.shape[1] - if nxf > int(nxf): - nxf = int(nxf) + 1 - else: - nxf = int(nxf) + prediction_true = np.zeros((img_h, img_w, 3)) + mask_true = np.zeros((img_h, img_w)) + nxf = img_w / float(width_mid) + nyf = img_h / float(height_mid) - if nyf > int(nyf): - nyf = int(nyf) + 1 - else: - nyf = int(nyf) - - for i in range(nxf): - for j in range(nyf): + if nxf > int(nxf): + nxf = int(nxf) + 1 + else: + nxf = int(nxf) - if i == 0: - index_x_d = i * width_mid - index_x_u = index_x_d + model_width - elif i > 0: - index_x_d = i * width_mid - index_x_u = index_x_d + model_width + if nyf > int(nyf): + nyf = int(nyf) + 1 + else: + nyf = int(nyf) - if j == 0: - index_y_d = j * height_mid - index_y_u = index_y_d + model_height - elif j > 0: - index_y_d = j * height_mid - index_y_u = index_y_d + model_height + for i in range(nxf): + for j in range(nyf): - if index_x_u > img_w: - index_x_u = img_w - index_x_d = img_w - model_width - if index_y_u > img_h: - index_y_u = img_h - index_y_d = img_h - model_height + if i == 0: + index_x_d = i * width_mid + index_x_u = index_x_d + model_width + elif i > 0: + index_x_d = i * width_mid + index_x_u = index_x_d + model_width - img_patch = img[index_y_d:index_y_u, index_x_d:index_x_u, :] + if j == 0: + index_y_d = j * height_mid + index_y_u = index_y_d + model_height + elif j > 0: + index_y_d = j * height_mid + index_y_u = index_y_d + model_height - label_p_pred = model.predict(img_patch.reshape(1, img_patch.shape[0], img_patch.shape[1], img_patch.shape[2])) + if index_x_u > img_w: + index_x_u = img_w + index_x_d = img_w - model_width + if index_y_u > img_h: + index_y_u = img_h + index_y_d = img_h - model_height - seg = np.argmax(label_p_pred, axis=3)[0] + img_patch = img[index_y_d:index_y_u, index_x_d:index_x_u, :] - seg_color = np.repeat(seg[:, :, np.newaxis], 3, axis=2) + label_p_pred = model.predict(img_patch.reshape(1, img_patch.shape[0], img_patch.shape[1], img_patch.shape[2])) - if i == 0 and j == 0: - seg_color = seg_color[0:seg_color.shape[0] - margin, 0:seg_color.shape[1] - margin, :] - seg = seg[0:seg.shape[0] - margin, 0:seg.shape[1] - margin] + seg = np.argmax(label_p_pred, axis=3)[0] - mask_true[index_y_d + 0:index_y_u - margin, index_x_d + 0:index_x_u - margin] = seg - prediction_true[index_y_d + 0:index_y_u - margin, index_x_d + 0:index_x_u - margin, :] = seg_color + seg_color = np.repeat(seg[:, :, np.newaxis], 3, axis=2) - elif i == nxf-1 and j == nyf-1: - seg_color = seg_color[margin:seg_color.shape[0] - 0, margin:seg_color.shape[1] - 0, :] - seg = seg[margin:seg.shape[0] - 0, margin:seg.shape[1] - 0] + if i == 0 and j == 0: + seg_color = seg_color[0:seg_color.shape[0] - margin, 0:seg_color.shape[1] - margin, :] + seg = seg[0:seg.shape[0] - margin, 0:seg.shape[1] - margin] - mask_true[index_y_d + margin:index_y_u - 0, index_x_d + margin:index_x_u - 0] = seg - prediction_true[index_y_d + margin:index_y_u - 0, index_x_d + margin:index_x_u - 0, :] = seg_color + mask_true[index_y_d + 0:index_y_u - margin, index_x_d + 0:index_x_u - margin] = seg + prediction_true[index_y_d + 0:index_y_u - margin, index_x_d + 0:index_x_u - margin, :] = seg_color - elif i == 0 and j == nyf-1: - seg_color = seg_color[margin:seg_color.shape[0] - 0, 0:seg_color.shape[1] - margin, :] - seg = seg[margin:seg.shape[0] - 0, 0:seg.shape[1] - margin] + elif i == nxf-1 and j == nyf-1: + seg_color = seg_color[margin:seg_color.shape[0] - 0, margin:seg_color.shape[1] - 0, :] + seg = seg[margin:seg.shape[0] - 0, margin:seg.shape[1] - 0] - mask_true[index_y_d + margin:index_y_u - 0, index_x_d + 0:index_x_u - margin] = seg - prediction_true[index_y_d + margin:index_y_u - 0, index_x_d + 0:index_x_u - margin, :] = seg_color + mask_true[index_y_d + margin:index_y_u - 0, index_x_d + margin:index_x_u - 0] = seg + prediction_true[index_y_d + margin:index_y_u - 0, index_x_d + margin:index_x_u - 0, :] = seg_color - elif i == nxf-1 and j == 0: - seg_color = seg_color[0:seg_color.shape[0] - margin, margin:seg_color.shape[1] - 0, :] - seg = seg[0:seg.shape[0] - margin, margin:seg.shape[1] - 0] + elif i == 0 and j == nyf-1: + seg_color = seg_color[margin:seg_color.shape[0] - 0, 0:seg_color.shape[1] - margin, :] + seg = seg[margin:seg.shape[0] - 0, 0:seg.shape[1] - margin] - mask_true[index_y_d + 0:index_y_u - margin, index_x_d + margin:index_x_u - 0] = seg - prediction_true[index_y_d + 0:index_y_u - margin, index_x_d + margin:index_x_u - 0, :] = seg_color + mask_true[index_y_d + margin:index_y_u - 0, index_x_d + 0:index_x_u - margin] = seg + prediction_true[index_y_d + margin:index_y_u - 0, index_x_d + 0:index_x_u - margin, :] = seg_color - elif i == 0 and j != 0 and j != nyf-1: - seg_color = seg_color[margin:seg_color.shape[0] - margin, 0:seg_color.shape[1] - margin, :] - seg = seg[margin:seg.shape[0] - margin, 0:seg.shape[1] - margin] + elif i == nxf-1 and j == 0: + seg_color = seg_color[0:seg_color.shape[0] - margin, margin:seg_color.shape[1] - 0, :] + seg = seg[0:seg.shape[0] - margin, margin:seg.shape[1] - 0] - mask_true[index_y_d + margin:index_y_u - margin, index_x_d + 0:index_x_u - margin] = seg - prediction_true[index_y_d + margin:index_y_u - margin, index_x_d + 0:index_x_u - margin, :] = seg_color + mask_true[index_y_d + 0:index_y_u - margin, index_x_d + margin:index_x_u - 0] = seg + prediction_true[index_y_d + 0:index_y_u - margin, index_x_d + margin:index_x_u - 0, :] = seg_color - elif i == nxf-1 and j != 0 and j != nyf-1: - seg_color = seg_color[margin:seg_color.shape[0] - margin, margin:seg_color.shape[1] - 0, :] - seg = seg[margin:seg.shape[0] - margin, margin:seg.shape[1] - 0] + elif i == 0 and j != 0 and j != nyf-1: + seg_color = seg_color[margin:seg_color.shape[0] - margin, 0:seg_color.shape[1] - margin, :] + seg = seg[margin:seg.shape[0] - margin, 0:seg.shape[1] - margin] - mask_true[index_y_d + margin:index_y_u - margin, index_x_d + margin:index_x_u - 0] = seg - prediction_true[index_y_d + margin:index_y_u - margin, index_x_d + margin:index_x_u - 0, :] = seg_color + mask_true[index_y_d + margin:index_y_u - margin, index_x_d + 0:index_x_u - margin] = seg + prediction_true[index_y_d + margin:index_y_u - margin, index_x_d + 0:index_x_u - margin, :] = seg_color - elif i != 0 and i != nxf-1 and j == 0: - seg_color = seg_color[0:seg_color.shape[0] - margin, margin:seg_color.shape[1] - margin, :] - seg = seg[0:seg.shape[0] - margin, margin:seg.shape[1] - margin] + elif i == nxf-1 and j != 0 and j != nyf-1: + seg_color = seg_color[margin:seg_color.shape[0] - margin, margin:seg_color.shape[1] - 0, :] + seg = seg[margin:seg.shape[0] - margin, margin:seg.shape[1] - 0] - mask_true[index_y_d + 0:index_y_u - margin, index_x_d + margin:index_x_u - margin] = seg - prediction_true[index_y_d + 0:index_y_u - margin, index_x_d + margin:index_x_u - margin, :] = seg_color + mask_true[index_y_d + margin:index_y_u - margin, index_x_d + margin:index_x_u - 0] = seg + prediction_true[index_y_d + margin:index_y_u - margin, index_x_d + margin:index_x_u - 0, :] = seg_color - elif i != 0 and i != nxf-1 and j == nyf-1: - seg_color = seg_color[margin:seg_color.shape[0] - 0, margin:seg_color.shape[1] - margin, :] - seg = seg[margin:seg.shape[0] - 0, margin:seg.shape[1] - margin] + elif i != 0 and i != nxf-1 and j == 0: + seg_color = seg_color[0:seg_color.shape[0] - margin, margin:seg_color.shape[1] - margin, :] + seg = seg[0:seg.shape[0] - margin, margin:seg.shape[1] - margin] - mask_true[index_y_d + margin:index_y_u - 0, index_x_d + margin:index_x_u - margin] = seg - prediction_true[index_y_d + margin:index_y_u - 0, index_x_d + margin:index_x_u - margin, :] = seg_color + mask_true[index_y_d + 0:index_y_u - margin, index_x_d + margin:index_x_u - margin] = seg + prediction_true[index_y_d + 0:index_y_u - margin, index_x_d + margin:index_x_u - margin, :] = seg_color - else: - seg_color = seg_color[margin:seg_color.shape[0] - margin, margin:seg_color.shape[1] - margin, :] - seg = seg[margin:seg.shape[0] - margin, margin:seg.shape[1] - margin] + elif i != 0 and i != nxf-1 and j == nyf-1: + seg_color = seg_color[margin:seg_color.shape[0] - 0, margin:seg_color.shape[1] - margin, :] + seg = seg[margin:seg.shape[0] - 0, margin:seg.shape[1] - margin] - mask_true[index_y_d + margin:index_y_u - margin, index_x_d + margin:index_x_u - margin] = seg - prediction_true[index_y_d + margin:index_y_u - margin, index_x_d + margin:index_x_u - margin, :] = seg_color - - - - prediction_true = prediction_true[index_start_h: index_start_h+img_org_h, index_start_w: index_start_w+img_org_w,:] - prediction_true = prediction_true.astype(np.uint8) + mask_true[index_y_d + margin:index_y_u - 0, index_x_d + margin:index_x_u - margin] = seg + prediction_true[index_y_d + margin:index_y_u - 0, index_x_d + margin:index_x_u - margin, :] = seg_color - else: - img_h_page = img.shape[0] - img_w_page = img.shape[1] - img = img / float(255.0) - img = resize_image(img, model_height, model_width) + else: + seg_color = seg_color[margin:seg_color.shape[0] - margin, margin:seg_color.shape[1] - margin, :] + seg = seg[margin:seg.shape[0] - margin, margin:seg.shape[1] - margin] - label_p_pred = model.predict(img.reshape(1, img.shape[0], img.shape[1], img.shape[2])) + mask_true[index_y_d + margin:index_y_u - margin, index_x_d + margin:index_x_u - margin] = seg + prediction_true[index_y_d + margin:index_y_u - margin, index_x_d + margin:index_x_u - margin, :] = seg_color + + + + prediction_true = prediction_true[index_start_h: index_start_h+img_org_h, index_start_w: index_start_w+img_org_w,:] + prediction_true = prediction_true.astype(np.uint8) - seg = np.argmax(label_p_pred, axis=3)[0] - seg_color = np.repeat(seg[:, :, np.newaxis], 3, axis=2) - prediction_true = resize_image(seg_color, img_h_page, img_w_page) - prediction_true = prediction_true.astype(np.uint8) return prediction_true[:,:,0] - def run(self, image=None, image_path=None, save=None, use_patches=False): + def run(self, image=None, image_path=None, save=None): if (image is not None and image_path is not None) or \ (image is None and image_path is None): raise ValueError("Must pass either a opencv2 image or an image_path") @@ -256,7 +240,7 @@ class SbbBinarizer: 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) + res = self.predict(model, image) img_fin = np.zeros((res.shape[0], res.shape[1], 3)) res[:, :][res[:, :] == 0] = 2 From 0d8a9f33f5ee43965ad9c06978cdc6b5789cf8f6 Mon Sep 17 00:00:00 2001 From: Clemens Neudecker <952378+cneud@users.noreply.github.com> Date: Wed, 12 Oct 2022 00:29:22 +0200 Subject: [PATCH 7/9] Update README.md remove patches parameter from readme --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d1f5c8e..8ec4e4b 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Clone the repository, enter it and run ### Models -Pre-trained models in `h5` format can be downloaded from here: +Pre-trained models in `HDF5` format can be downloaded from here: https://qurator-data.de/sbb_binarization/ @@ -30,20 +30,17 @@ https://huggingface.co/SBB/sbb_binarization ```sh sbb_binarize \ - --patches \ - -m \ + -m \ ``` -In virtually all cases, applying the `--patches` flag will improve the quality of results. - Images containing a lot of border noise (black pixels) should be cropped beforehand to improve the quality of results. ### Example ```sh -sbb_binarize --patches -m /path/to/models/ myimage.tif myimage-bin.tif +sbb_binarize -m /path/to/model/ myimage.tif myimage-bin.tif ``` To use the [OCR-D](https://ocr-d.de/) interface: From 82816b048eb1361db01f5d77038d6a26145a7ac7 Mon Sep 17 00:00:00 2001 From: Konstantin Baierer Date: Mon, 24 Oct 2022 16:56:22 +0200 Subject: [PATCH 8/9] :memo: changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2811a4..0fc7686 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ Versioned according to [Semantic Versioning](http://semver.org/). ## Unreleased +Added: + + * Trained models listed in ocrd-tool.json for download with OCR-D resource manager, #53 + ## [0.0.10] - 2022-07-21 Fixed: From aeb6804b7d5e2e1deabe4fc1bec4c0e127af351f Mon Sep 17 00:00:00 2001 From: Konstantin Baierer Date: Mon, 24 Oct 2022 16:57:22 +0200 Subject: [PATCH 9/9] :package: v0.0.11 --- CHANGELOG.md | 3 +++ sbb_binarize/ocrd-tool.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fc7686..0ec8078 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ Versioned according to [Semantic Versioning](http://semver.org/). ## Unreleased +## [0.0.10] - 2022-10-24 + Added: * Trained models listed in ocrd-tool.json for download with OCR-D resource manager, #53 @@ -75,6 +77,7 @@ Fixed: Initial release +[0.0.11]: ../../compare/v0.0.11...v0.0.10 [0.0.10]: ../../compare/v0.0.10...v0.0.9 [0.0.9]: ../../compare/v0.0.9...v0.0.8 [0.0.8]: ../../compare/v0.0.8...v0.0.7 diff --git a/sbb_binarize/ocrd-tool.json b/sbb_binarize/ocrd-tool.json index 2c02d12..9148309 100644 --- a/sbb_binarize/ocrd-tool.json +++ b/sbb_binarize/ocrd-tool.json @@ -1,5 +1,5 @@ { - "version": "0.0.10", + "version": "0.0.11", "git_url": "https://github.com/qurator-spk/sbb_binarization", "tools": { "ocrd-sbb-binarize": {