diff --git a/docs/leaf_focus/ocr/keras_ocr.html b/docs/leaf_focus/ocr/keras_ocr.html index 3f76f54..f660033 100644 --- a/docs/leaf_focus/ocr/keras_ocr.html +++ b/docs/leaf_focus/ocr/keras_ocr.html @@ -134,269 +134,273 @@
84 def engine_run( - 85 self, - 86 image_file: pathlib.Path, - 87 ) -> typing.Tuple[typing.List, typing.Any]: - 88 """Run the recognition engine. - 89 - 90 Args: - 91 image_file: The path to the image file. - 92 - 93 Returns: - 94 typing.Tuple[typing.List, typing.Any]: The list of images - 95 and list of recognition results. - 96 """ - 97 try: - 98 import keras_ocr # pylint: disable=import-outside-toplevel - 99 except ModuleNotFoundError as error: -100 msg = "Cannot run ocr on this Python version." -101 logger.error(msg) -102 raise utils.LeafFocusError(msg) from error -103 -104 self.engine_create() -105 -106 if not self._pipeline: -107 msg = "Keras OCR pipeline has not been initialised yet." -108 logger.error(msg) -109 raise utils.LeafFocusError(msg) -110 -111 images = [keras_ocr.tools.read(str(image_file))] -112 return images, self._pipeline.recognize(images) +@@ -896,30 +908,30 @@88 def engine_run( + 89 self, + 90 image_file: pathlib.Path, + 91 ) -> typing.Tuple[typing.List, typing.Any]: + 92 """Run the recognition engine. + 93 + 94 Args: + 95 image_file: The path to the image file. + 96 + 97 Returns: + 98 typing.Tuple[typing.List, typing.Any]: The list of images + 99 and list of recognition results. +100 """ +101 try: +102 import keras_ocr # pylint: disable=import-outside-toplevel +103 except ModuleNotFoundError as error: +104 msg = "Cannot run ocr on this Python version." +105 logger.error(msg) +106 raise utils.LeafFocusError(msg) from error +107 +108 self.engine_create() +109 +110 if not self._pipeline: +111 msg = "Keras OCR pipeline has not been initialised yet." +112 logger.error(msg) +113 raise utils.LeafFocusError(msg) +114 +115 images = [keras_ocr.tools.read(str(image_file))] +116 return images, self._pipeline.recognize(images)Returns:
114 def engine_annotate( -115 self, -116 image: typing.Optional[np.ndarray], -117 predictions: typing.List[typing.Tuple[typing.Any, typing.Any]], -118 axis, -119 ) -> None: -120 """Run the annotation engine. -121 -122 Args: -123 image: The image data. -124 predictions: The recognised text from the image. -125 axis: The plot axis for drawing annotations. -126 -127 Returns: -128 None -129 """ -130 try: -131 import keras_ocr # pylint: disable=import-outside-toplevel -132 except ModuleNotFoundError as error: -133 msg = "Cannot run ocr on this Python version." -134 logger.error(msg) -135 raise utils.LeafFocusError(msg) from error -136 -137 keras_ocr.tools.drawAnnotations(image=image, predictions=predictions, ax=axis) +@@ -953,72 +965,72 @@118 def engine_annotate( +119 self, +120 image: typing.Optional[np.ndarray], +121 predictions: typing.List[typing.Tuple[typing.Any, typing.Any]], +122 axis, +123 ) -> None: +124 """Run the annotation engine. +125 +126 Args: +127 image: The image data. +128 predictions: The recognised text from the image. +129 axis: The plot axis for drawing annotations. +130 +131 Returns: +132 None +133 """ +134 try: +135 import keras_ocr # pylint: disable=import-outside-toplevel +136 except ModuleNotFoundError as error: +137 msg = "Cannot run ocr on this Python version." +138 logger.error(msg) +139 raise utils.LeafFocusError(msg) from error +140 +141 keras_ocr.tools.drawAnnotations(image=image, predictions=predictions, ax=axis)Returns:
139 def recognise_text( -140 self, -141 image_file: pathlib.Path, -142 output_dir: pathlib.Path, -143 ) -> model.KerasOcrResult: -144 """Recognise text in an image file. -145 -146 Args: -147 image_file: The path to the image file. -148 output_dir: The directory to write the results. +@@ -1051,49 +1063,49 @@143 def recognise_text( +144 self, +145 image_file: pathlib.Path, +146 output_dir: pathlib.Path, +147 ) -> model.KerasOcrResult: +148 """Recognise text in an image file. 149 -150 Returns: -151 model.KerasOcrResult: The text recognition results. -152 """ -153 if not image_file: -154 msg = "Must supply image file." -155 raise utils.LeafFocusError(msg) -156 if not output_dir: -157 msg = "Must supply output directory." -158 raise utils.LeafFocusError(msg) -159 if not image_file.exists(): -160 msg = f"Image file does not exist '{image_file}'." -161 raise utils.LeafFocusError(msg) from FileNotFoundError(image_file) -162 -163 # check if output files already exist -164 annotations_file = utils.output_root(image_file, "annotations", output_dir) -165 annotations_file = annotations_file.with_suffix(".png") +150 Args: +151 image_file: The path to the image file. +152 output_dir: The directory to write the results. +153 +154 Returns: +155 model.KerasOcrResult: The text recognition results. +156 """ +157 if not image_file: +158 msg = "Must supply image file." +159 raise utils.LeafFocusError(msg) +160 if not output_dir: +161 msg = "Must supply output directory." +162 raise utils.LeafFocusError(msg) +163 if not image_file.exists(): +164 msg = f"Image file does not exist '{image_file}'." +165 raise utils.LeafFocusError(msg) from FileNotFoundError(image_file) 166 -167 predictions_file = utils.output_root(image_file, "predictions", output_dir) -168 predictions_file = predictions_file.with_suffix(".csv") -169 -170 result = model.KerasOcrResult( -171 output_dir=output_dir, -172 annotations_file=annotations_file, -173 predictions_file=predictions_file, -174 items=[], -175 ) -176 -177 if annotations_file.exists() and predictions_file.exists(): -178 logger.debug( -179 "Predictions and annotations files already exist for '%s'.", -180 image_file.stem, -181 ) -182 all_items = list(model.TextItem.load(predictions_file)) -183 result.items = model.TextItem.order_text_lines(all_items) -184 return result -185 -186 # read in the image -187 logger.debug( -188 "Creating predictions and annotations files for '%s'.", -189 image_file.stem, -190 ) -191 -192 # Each list of predictions in prediction_groups is a list of -193 # (word, box) tuples. -194 images, prediction_groups = self.engine_run(image_file) +167 # check if output files already exist +168 annotations_file = utils.output_root(image_file, "annotations", output_dir) +169 annotations_file = annotations_file.with_suffix(".png") +170 +171 predictions_file = utils.output_root(image_file, "predictions", output_dir) +172 predictions_file = predictions_file.with_suffix(".csv") +173 +174 result = model.KerasOcrResult( +175 output_dir=output_dir, +176 annotations_file=annotations_file, +177 predictions_file=predictions_file, +178 items=[], +179 ) +180 +181 if annotations_file.exists() and predictions_file.exists(): +182 logger.debug( +183 "Predictions and annotations files already exist for '%s'.", +184 image_file.stem, +185 ) +186 all_items = list(model.TextItem.load(predictions_file)) +187 result.items = model.TextItem.order_text_lines(all_items) +188 return result +189 +190 # read in the image +191 logger.debug( +192 "Creating predictions and annotations files for '%s'.", +193 image_file.stem, +194 ) 195 -196 # Plot and save the predictions -197 for image, predictions in zip(images, prediction_groups): -198 self.save_figure(annotations_file, image, predictions) +196 # Each list of predictions in prediction_groups is a list of +197 # (word, box) tuples. +198 images, prediction_groups = self.engine_run(image_file) 199 -200 items = self.convert_predictions(predictions) -201 self.save_items(predictions_file, [item for line in items for item in line]) -202 result.items = items +200 # Plot and save the predictions +201 for image, predictions in zip(images, prediction_groups): +202 self.save_figure(annotations_file, image, predictions) 203 -204 return result +204 items = self.convert_predictions(predictions) +205 self.save_items(predictions_file, [item for line in items for item in line]) +206 result.items = items +207 +208 return resultReturns:
206 def save_figure( -207 self, -208 annotation_file: pathlib.Path, -209 image: typing.Optional[np.ndarray], -210 predictions: typing.List[typing.Tuple[typing.Any, typing.Any]], -211 ) -> None: -212 """Save the annotated image. -213 -214 Args: -215 annotation_file: The path to the file containing annotations. -216 image: The image data. -217 predictions: The text recognition results. -218 -219 Returns: -220 None -221 """ -222 if not annotation_file: -223 msg = "Must supply annotation file." -224 raise utils.LeafFocusError(msg) -225 -226 expected_image_shape = 3 -227 if image is None or image.size < 1 or len(image.shape) != expected_image_shape: -228 msg_image = image.shape if image is not None else None -229 msg = f"Must supply valid image data, not '{msg_image}'." -230 raise utils.LeafFocusError(msg) -231 if not predictions: -232 predictions = [] -233 -234 logger.info("Saving OCR image to '%s'.", annotation_file) -235 -236 import matplotlib as mpl # pylint: disable=import-outside-toplevel -237 from matplotlib import pyplot as plt # pylint: disable=import-outside-toplevel -238 -239 mpl.use("agg") -240 -241 annotation_file.parent.mkdir(exist_ok=True, parents=True) +@@ -1127,29 +1139,29 @@210 def save_figure( +211 self, +212 annotation_file: pathlib.Path, +213 image: typing.Optional[np.ndarray], +214 predictions: typing.List[typing.Tuple[typing.Any, typing.Any]], +215 ) -> None: +216 """Save the annotated image. +217 +218 Args: +219 annotation_file: The path to the file containing annotations. +220 image: The image data. +221 predictions: The text recognition results. +222 +223 Returns: +224 None +225 """ +226 if not annotation_file: +227 msg = "Must supply annotation file." +228 raise utils.LeafFocusError(msg) +229 +230 expected_image_shape = 3 +231 if image is None or image.size < 1 or len(image.shape) != expected_image_shape: +232 msg_image = image.shape if image is not None else None +233 msg = f"Must supply valid image data, not '{msg_image}'." +234 raise utils.LeafFocusError(msg) +235 if not predictions: +236 predictions = [] +237 +238 logger.info("Saving OCR image to '%s'.", annotation_file) +239 +240 import matplotlib as mpl # pylint: disable=import-outside-toplevel +241 from matplotlib import pyplot as plt # pylint: disable=import-outside-toplevel 242 -243 fig, axis = plt.subplots(figsize=(20, 20)) +243 mpl.use("agg") 244 -245 self.engine_annotate(image, predictions, axis) +245 annotation_file.parent.mkdir(exist_ok=True, parents=True) 246 -247 fig.savefig(str(annotation_file)) -248 plt.close(fig) +247 fig, axis = plt.subplots(figsize=(20, 20)) +248 +249 self.engine_annotate(image, predictions, axis) +250 +251 fig.savefig(str(annotation_file)) +252 plt.close(fig)Returns:
250 def convert_predictions( -251 self, -252 predictions: typing.List[typing.Tuple[typing.Any, typing.Any]], -253 ) -> typing.List[typing.List[model.TextItem]]: -254 """Convert predictions to items. -255 -256 Args: -257 predictions: The list of recognised text. -258 -259 Returns: -260 typing.List[typing.List[model.TextItem]]: The equivalent text items. -261 """ -262 if not predictions: -263 predictions = [] -264 -265 items = [] -266 for prediction in predictions: -267 items.append(model.TextItem.from_prediction(prediction)) +@@ -1181,31 +1193,31 @@254 def convert_predictions( +255 self, +256 predictions: typing.List[typing.Tuple[typing.Any, typing.Any]], +257 ) -> typing.List[typing.List[model.TextItem]]: +258 """Convert predictions to items. +259 +260 Args: +261 predictions: The list of recognised text. +262 +263 Returns: +264 typing.List[typing.List[model.TextItem]]: The equivalent text items. +265 """ +266 if not predictions: +267 predictions = [] 268 -269 # order_text_lines sets the line number and line order -270 line_items = model.TextItem.order_text_lines(items) -271 -272 return line_items +269 items = [] +270 for prediction in predictions: +271 items.append(model.TextItem.from_prediction(prediction)) +272 +273 # order_text_lines sets the line number and line order +274 line_items = model.TextItem.order_text_lines(items) +275 +276 return line_itemsReturns:
274 def save_items( -275 self, -276 items_file: pathlib.Path, -277 items: typing.Iterable[model.TextItem], -278 ) -> None: -279 """Save items to csv file. -280 -281 Args: -282 items_file: Write the text items to this file. -283 items: The text items to save. +278 def save_items( +279 self, +280 items_file: pathlib.Path, +281 items: typing.Iterable[model.TextItem], +282 ) -> None: +283 """Save items to csv file. 284 -285 Returns: -286 None -287 """ -288 if not items_file: -289 msg = "Must supply predictions file." -290 raise utils.LeafFocusError(msg) -291 if not items: -292 msg = "Must supply predictions data." -293 raise utils.LeafFocusError(msg) -294 -295 logger.info("Saving OCR predictions to '%s'.", items_file) -296 -297 items_list = list(items) -298 model.TextItem.save(items_file, items_list) +285 Args: +286 items_file: Write the text items to this file. +287 items: The text items to save. +288 +289 Returns: +290 None +291 """ +292 if not items_file: +293 msg = "Must supply predictions file." +294 raise utils.LeafFocusError(msg) +295 if not items: +296 msg = "Must supply predictions data." +297 raise utils.LeafFocusError(msg) +298 +299 logger.info("Saving OCR predictions to '%s'.", items_file) +300 +301 items_list = list(items) +302 model.TextItem.save(items_file, items_list)