Skip to content

Commit c4821c2

Browse files
committed
Merge branch 'feature/annotations' into develop
2 parents f33fdb8 + c98e58b commit c4821c2

File tree

11 files changed

+383
-181
lines changed

11 files changed

+383
-181
lines changed

CHANGELOG.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
## [1.0.2] - 2022-03-... (unreleased)
1+
## [1.0.3] - 2022-03-20
2+
### Changed
3+
- Changed `mltu.augmentors` to work only with `Image` objects
4+
5+
### Added
6+
- Created `Image` object in `mltu.annotations.image` to handle image annotations
7+
8+
9+
## [1.0.2] - 2022-03-20
210
### Changed
311
- changes `OnnxInferenceModel` in `mltu.torch.inferenceModels` to load custom metadata from saved ONNX model
412
- improved `mltu.dataProvider` to remove bad samples from dataset on epoch end
@@ -21,7 +29,7 @@
2129
- added `mltu.torch.models`, used to create PyTorch models, that wrapps whole model pipeline (training, validation, metrics, callbacks, etc.)
2230
- added `mltu.torch.callbacks`, used to create PyTorch callbacks, that may be used in training and validation
2331
- added `mltu.torch.metrics`, used to create PyTorch metrics, that may be used in training and validation
24-
- added 07_pytorch_tutorial tutorial
32+
- added `07_pytorch_tutorial` tutorial
2533

2634

2735
## [1.0.0] - 2022-03-06

Tutorials/08_handwriting_recognition_torch/train_torch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def download_and_unzip(url, extract_to='Datasets', chunk_size=1024*1024):
8080
batch_size=configs.batch_size,
8181
data_preprocessors=[ImageReader()],
8282
transformers=[
83-
# ImageShowCV2(), # uncomment to show images during training
83+
# ImageShowCV2(), # uncomment to show images when iterating over the data provider
8484
ImageResizer(configs.width, configs.height, keep_aspect_ratio=False),
8585
LabelIndexer(configs.vocab),
8686
LabelPadding(max_word_length=configs.max_text_length, padding_value=len(configs.vocab))

Tutorials/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
4. [Handwritten sentence recognition with TensorFlow](https://pylessons.com/handwritten-sentence-recognition), code in ```Tutorials\04_sentence_recognition``` folder;
66
5. [Introduction to speech recognition with TensorFlow](https://pylessons.com/speech-recognition), code in ```Tutorials\05_speech_recognition``` folder;
77
6. [Introduction to PyTorch in a practical way](https://pylessons.com/pytorch-introduction), code in ```Tutorials\06_pytorch_introduction``` folder;
8-
7. [Using custom wrapper to simplify PyTorch models training pipeline](https://pylessons.com/pytorch-introduction), code in ```Tutorials\07_pytorch_wrapper``` folder;
8+
7. [Using custom wrapper to simplify PyTorch models training pipeline](https://pylessons.com/pytorch-introduction), code in ```Tutorials\07_pytorch_wrapper``` folder;
9+
8. [Handwriting words recognition with PyTorch](https://pylessons.com/handwriting-recognition-pytorch), code in ```Tutorials\08_handwriting_recognition_torch``` folder;

mltu/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
__version__ = "1.0.2"
1+
__version__ = "1.0.3"
2+
3+
from .annotations.image import Image

mltu/annotations/__init__.py

Whitespace-only changes.

mltu/annotations/image.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import os
2+
import cv2
3+
import typing
4+
import numpy as np
5+
6+
class Image:
7+
""" Image class for storing image data and metadata
8+
9+
Args:
10+
image (str or np.ndarray): Path to image or numpy.ndarray
11+
method (int, optional): OpenCV method for reading image. Defaults to cv2.IMREAD_COLOR.
12+
path (str, optional): Path to image. Defaults to "".
13+
color (str, optional): Color format of image. Defaults to "".
14+
"""
15+
def __init__(
16+
self,
17+
image: typing.Union[str, np.ndarray],
18+
method: int = cv2.IMREAD_COLOR,
19+
path: str = "",
20+
color: str = ""
21+
) -> None:
22+
23+
if isinstance(image, str):
24+
if not os.path.exists(image):
25+
raise FileNotFoundError(f"Image {image} not found.")
26+
27+
self.image = cv2.imread(image, method)
28+
self.path = image
29+
self.color = "BGR"
30+
31+
elif isinstance(image, np.ndarray):
32+
self.image = image
33+
self.path = path
34+
self.color = color
35+
36+
else:
37+
raise TypeError(f"Image must be either path to image or numpy.ndarray, not {type(image)}")
38+
39+
self.method = method
40+
41+
if self.image is None:
42+
return None
43+
44+
# save width, height and channels
45+
self.width = self.image.shape[1]
46+
self.height = self.image.shape[0]
47+
self.channels = 1 if len(self.image.shape) == 2 else self.image.shape[2]
48+
49+
@property
50+
def shape(self) -> tuple:
51+
return self.image.shape
52+
53+
@property
54+
def center(self) -> tuple:
55+
return (self.width // 2, self.height // 2)
56+
57+
def RGB(self) -> np.ndarray:
58+
if self.color == "RGB":
59+
return self.image
60+
elif self.color == "BGR":
61+
return cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB)
62+
else:
63+
raise ValueError(f"Unknown color format {self.color}")
64+
65+
def HSV(self) -> np.ndarray:
66+
if self.color == "BGR":
67+
return cv2.cvtColor(self.image, cv2.COLOR_BGR2HSV)
68+
elif self.color == "RGB":
69+
return cv2.cvtColor(self.image, cv2.COLOR_RGB2HSV)
70+
else:
71+
raise ValueError(f"Unknown color format {self.color}")
72+
73+
def update(self, image: np.ndarray):
74+
if isinstance(image, np.ndarray):
75+
self.image = image
76+
77+
# save width, height and channels
78+
self.width = self.image.shape[1]
79+
self.height = self.image.shape[0]
80+
self.channels = 1 if len(self.image.shape) == 2 else self.image.shape[2]
81+
82+
return self
83+
84+
else:
85+
raise TypeError(f"image must be numpy.ndarray, not {type(image)}")
86+
87+
def flip(self, axis: int = 0):
88+
""" Flip image along x or y axis
89+
90+
Args:
91+
axis (int, optional): Axis along which image will be flipped. Defaults to 0.
92+
93+
Returns:
94+
Object with flipped points
95+
"""
96+
# axis must be either 0 or 1
97+
if axis not in [0, 1]:
98+
raise ValueError(f"axis must be either 0 or 1, not {axis}")
99+
100+
self.image = self.image[:, ::-1] if axis == 0 else self.image[::-1]
101+
102+
return self
103+
104+
def numpy(self) -> np.ndarray:
105+
return self.image
106+
107+
def __call__(self) -> np.ndarray:
108+
return self.image

0 commit comments

Comments
 (0)