Skip to content

Commit 00599f6

Browse files
committed
docs: fixed additional typing errors
1 parent 37bb5c4 commit 00599f6

8 files changed

Lines changed: 68 additions & 60 deletions

File tree

aztec_tool/codewords.py

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
from __future__ import annotations
44

55
from functools import cached_property
6-
from typing import List, Optional
6+
from typing import List, Optional, Tuple
77

88
import numpy as np
9+
import numpy.typing as npt
910
import reedsolo
1011

1112
from .enums import AztecTableType, AztecType, ReadingDirection
@@ -26,7 +27,7 @@ class CodewordReader:
2627
"""Read the data spiral, apply Reed-Solomon correction and decode code-words.
2728
2829
:param matrix: Square binary matrix (0/1) representing the Aztec symbol.
29-
:type matrix: numpy.ndarray
30+
:type matrix: npt.NDArray[np.int_]
3031
:param layers: Number of data layers (excluding the bull's-eye).
3132
:type layers: int
3233
:param data_words: Expected count of data code-words (script does *not* include ECC words).
@@ -54,7 +55,7 @@ class CodewordReader:
5455

5556
def __init__(
5657
self,
57-
matrix: np.ndarray,
58+
matrix: npt.NDArray[np.int_],
5859
layers: int,
5960
data_words: int,
6061
aztec_type: AztecType,
@@ -93,15 +94,15 @@ def _is_reference(self, r: int, c: int) -> bool:
9394
centre = self.matrix.shape[0] // 2
9495
return bool((r - centre) % 16 == 0 or (c - centre) % 16 == 0)
9596

96-
def _read_bits(self) -> np.ndarray:
97-
bitmap = []
97+
def _read_bits(self) -> npt.NDArray[np.int_]:
98+
bitmap: List[int] = []
9899
square_size = self.matrix.shape[0]
99100
reading_direction = ReadingDirection.BOTTOM
100-
start_point = (
101+
start_point: Tuple[int, int] = (
101102
0,
102103
0,
103104
) # We start reading from the top left corner to the bottom left corner
104-
end_point = (
105+
end_point: Tuple[int, int] = (
105106
square_size
106107
- 1
107108
- 2, # - 2 because the two last lines are readed in a different direction
@@ -120,15 +121,15 @@ def _read_bits(self) -> np.ndarray:
120121
not self._is_reference(i, start_point[1])
121122
or self.aztec_type == AztecType.COMPACT
122123
):
123-
bitmap.append(
124+
bitmap.extend(
124125
self.matrix[i, start_point[1] : end_point[1] + 1]
125126
)
126127
elif reading_direction == ReadingDirection.RIGHT:
127128
if (
128129
not self._is_reference(start_point[0], i)
129130
or self.aztec_type == AztecType.COMPACT
130131
):
131-
bitmap.append(
132+
bitmap.extend(
132133
self.matrix[start_point[0] : end_point[0] - 1 : -1, i]
133134
)
134135
elif reading_direction == ReadingDirection.TOP:
@@ -138,7 +139,7 @@ def _read_bits(self) -> np.ndarray:
138139
)
139140
or self.aztec_type == AztecType.COMPACT
140141
):
141-
bitmap.append(
142+
bitmap.extend(
142143
self.matrix[
143144
start_point[0] - i + apply_to_borns,
144145
start_point[1] : end_point[1] - 1 : -1,
@@ -151,7 +152,7 @@ def _read_bits(self) -> np.ndarray:
151152
)
152153
or self.aztec_type == AztecType.COMPACT
153154
):
154-
bitmap.append(
155+
bitmap.extend(
155156
self.matrix[
156157
start_point[0] : end_point[0] + 1,
157158
start_point[1] - i + apply_to_borns,
@@ -198,14 +199,14 @@ def _read_bits(self) -> np.ndarray:
198199
"no data modules extracted - check bull's-eye/layer count"
199200
)
200201

201-
return np.concatenate(bitmap).astype(int)
202+
return np.array(bitmap, dtype=int)
202203

203204
@cached_property
204-
def bitmap(self) -> np.ndarray:
205+
def bitmap(self) -> npt.NDArray[np.int_]:
205206
"""Raw bit-stream extracted from the symbol (before ECC correction)."""
206207
return self._read_bits()
207208

208-
def _correct(self) -> List[int]:
209+
def _correct(self) -> npt.NDArray[np.int_]:
209210
if self.layers <= 2:
210211
cw_size = 6
211212
elif self.layers <= 8:
@@ -248,15 +249,15 @@ def _correct(self) -> List[int]:
248249
except reedsolo.ReedSolomonError as exc:
249250
raise ReedSolomonError(str(exc)) from exc
250251

251-
corrected_bits = []
252+
corrected_bits: List[int] = []
252253
for sym in full_codeword:
253254
for shift in range(cw_size - 1, -1, -1):
254255
corrected_bits.append((sym >> shift) & 1)
255256

256-
return corrected_bits
257+
return np.array(corrected_bits, dtype=int)
257258

258259
@cached_property
259-
def corrected_bits(self) -> List[int]:
260+
def corrected_bits(self) -> npt.NDArray[np.int_]:
260261
"""Bit-stream after Reed-Solomon decoding and bit-stuff removal."""
261262
return self._correct()
262263

@@ -269,7 +270,7 @@ def _bits_to_bytes(cls, bits: List[int]) -> bytes:
269270
return bytes(cls._bits_to_int(bits[i : i + 8]) for i in range(0, len(bits), 8))
270271

271272
def _remove_stuff_bits(
272-
self, bits: List[int], cw_size: int, data_words: int
273+
self, bits: npt.NDArray[np.int_], cw_size: int, data_words: int
273274
) -> List[int]:
274275
"""Remove the stuffing bits from the bit-stream.
275276
@@ -279,7 +280,7 @@ def _remove_stuff_bits(
279280
Remove also the padding bits at the beginning of the stream.
280281
281282
:param bits: The bit-stream to clean.
282-
:type bits: List[int]
283+
:type bits: npt.NDArray[np.int_]
283284
:param cw_size: The size of the code-words (6, 8, 10 or 12).
284285
:type cw_size: int
285286
:param data_words: The number of data code-words in the symbol.
@@ -288,7 +289,7 @@ def _remove_stuff_bits(
288289
:return: The cleaned bit-stream without the stuffed bits and the padding bits.
289290
:rtype: List[int]
290291
"""
291-
cleaned = []
292+
cleaned: List[int] = []
292293
i = 0
293294
words_seen = 0
294295
while words_seen < data_words and i < len(bits):
@@ -324,7 +325,7 @@ def _decode(self) -> str:
324325
bits = self._remove_stuff_bits(self.bitmap, codeword_size, self.data_words)
325326

326327
i = 0
327-
chars = []
328+
chars: List[str] = []
328329
current_mode = AztecTableType.UPPER # Default mode is UPPER
329330
previous_mode = AztecTableType.UPPER
330331
single_shift = False

aztec_tool/decoder.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from typing import List, Optional, Tuple, Union
88

99
import numpy as np
10+
import numpy.typing as npt
1011

1112
from .codewords import CodewordReader
1213
from .detection import BullseyeDetector
@@ -32,7 +33,7 @@ class AztecDecoder:
3233
:type image_path: Optional[Union[str, Path]]
3334
:param matrix: Binary matrix (0/1) of the Aztec symbol. If not provided, the
3435
*image_path* parameter must be used instead.
35-
:type matrix: Optional[np.ndarray]
36+
:type matrix: Optional[npt.NDArray[np.int_]]
3637
:param auto_orient: If *True*, the matrix is rotated automatically so that orientation
3738
patterns match the canonical position (black-white corner pattern), defaults to ``True``
3839
:type auto_orient: Optional[bool]
@@ -70,7 +71,7 @@ def __init__(
7071
self,
7172
image_path: Optional[Union[str, Path]] = None,
7273
*,
73-
matrix: Optional[np.ndarray] = None,
74+
matrix: Optional[npt.NDArray[np.int_]] = None,
7475
auto_orient: Optional[bool] = True,
7576
auto_correct: Optional[bool] = True,
7677
mode_auto_correct: Optional[bool] = True,
@@ -80,7 +81,7 @@ def __init__(
8081
"either 'image_path' or 'matrix' must be provided"
8182
)
8283

83-
self._input_matrix: Optional[np.ndarray] = None
84+
self._input_matrix: Optional[npt.NDArray[np.int_]] = None
8485
if matrix is not None:
8586
if not isinstance(matrix, np.ndarray) or matrix.ndim != 2:
8687
raise InvalidParameterError(
@@ -100,7 +101,7 @@ def __init__(
100101
self._mode_auto_correct = mode_auto_correct
101102

102103
@cached_property
103-
def _raw_matrix(self) -> np.ndarray:
104+
def _raw_matrix(self) -> npt.NDArray[np.int_]:
104105
if self._input_matrix is not None:
105106
return self._input_matrix
106107
return AztecMatrix(str(self.image_path)).matrix
@@ -120,7 +121,7 @@ def aztec_type(self) -> AztecType:
120121
return self._bullseye.aztec_type
121122

122123
@cached_property
123-
def matrix(self) -> np.ndarray:
124+
def matrix(self) -> npt.NDArray[np.int_]:
124125
"""Final, possibly rotated, binary matrix (0/1) of the symbol."""
125126
if not self._auto_orient:
126127
return self._raw_matrix
@@ -151,12 +152,12 @@ def _codewords(self) -> CodewordReader:
151152
)
152153

153154
@cached_property
154-
def bitmap(self) -> np.ndarray:
155+
def bitmap(self) -> npt.NDArray[np.int_]:
155156
"""Raw bit-stream extracted from the data spiral (before ECC)."""
156157
return self._codewords.bitmap
157158

158159
@cached_property
159-
def corrected_bits(self) -> List[int]:
160+
def corrected_bits(self) -> npt.NDArray[np.int_]:
160161
"""Bit-stream after Reed-Solomon correction and bit-stuff removal."""
161162
return self._codewords.corrected_bits
162163

aztec_tool/detection.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Tuple, Union
55

66
import numpy as np
7+
import numpy.typing as npt
78

89
from .enums import AztecType
910
from .exceptions import (
@@ -22,7 +23,7 @@ class BullseyeDetector:
2223
the detector expands outward ring-by-ring until the pattern breaks.
2324
2425
:param matrix: Square binary matrix (0/1) representing the entire Aztec symbol.
25-
:type matrix: numpy.ndarray
26+
:type matrix: npt.NDArray[np.int_]
2627
2728
:raises InvalidParameterError: *matrix* is not a square 2-D array of **odd** side length.
2829
:raises BullseyeDetectionError: The alternating ring pattern cannot be found (symbol damaged or
@@ -41,7 +42,7 @@ class BullseyeDetector:
4142
<AztecType.FULL: 1>
4243
"""
4344

44-
def __init__(self, matrix: np.ndarray) -> None:
45+
def __init__(self, matrix: npt.NDArray[np.int_]) -> None:
4546
if matrix.ndim != 2 or matrix.shape[0] != matrix.shape[1]:
4647
raise InvalidParameterError("matrix must be a square 2-D array")
4748
if matrix.shape[0] % 2 == 0:

aztec_tool/matrix.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
import cv2
1010
import numpy as np
11+
import numpy.typing as npt
12+
from cv2.typing import MatLike
1113

1214
from .exceptions import InvalidParameterError, UnsupportedSymbolError
1315

@@ -46,7 +48,7 @@ def _detect_rois(
4648
min_area_ratio: float = 0.005,
4749
ar_tol: float = 0.15,
4850
density_tol: float = 0.15,
49-
) -> List[Tuple[np.ndarray, Tuple[int, int, int, int]]]:
51+
) -> List[Tuple[MatLike, Tuple[int, int, int, int]]]:
5052
"""Detect all candidate Aztec codes in the image and return the crops.
5153
5254
:param min_area_ratio: Minimum area of the detected region as a fraction of the image area, defaults to 0.005
@@ -60,7 +62,7 @@ def _detect_rois(
6062
:rtype: List[Tuple[crop_BGR, (x, y, w, h)]]
6163
"""
6264

63-
img = cv2.imread(self.image_path)
65+
img = cv2.imread(str(self.image_path))
6466
h, w = img.shape[:2]
6567

6668
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
@@ -74,7 +76,7 @@ def _detect_rois(
7476
n_labels, _, stats, _ = cv2.connectedComponentsWithStats(inv, connectivity=8)
7577

7678
img_area = h * w
77-
rois = [] # results
79+
rois: List[Tuple[MatLike, Tuple[int, int, int, int]]] = [] # results
7880

7981
for i in range(1, n_labels): # 0 = background, we start from 1
8082
x, y, ww, hh, area = stats[i]
@@ -101,11 +103,11 @@ def _detect_rois(
101103
print(len(rois))
102104
return rois
103105

104-
def _estimate_n(self, binary: np.ndarray) -> int:
106+
def _estimate_n(self, binary: MatLike) -> int:
105107
h, w = binary.shape
106108
row = (binary[h // 2, :] < 128).astype(int)
107109

108-
runs = []
110+
runs: List[int] = []
109111
current = row[0]
110112
length = 1
111113
for pix in row[1:]:
@@ -127,7 +129,7 @@ def _estimate_n(self, binary: np.ndarray) -> int:
127129
raise UnsupportedSymbolError(f"unsupported Aztec side length: {n}")
128130
return n
129131

130-
def _matrix_from_crop(self, crop: np.ndarray) -> np.ndarray:
132+
def _matrix_from_crop(self, crop: MatLike) -> npt.NDArray[np.int_]:
131133
"""Convert a *single* square crop to a binary module matrix."""
132134
gray = cv2.cvtColor(crop, cv2.COLOR_BGR2GRAY)
133135
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
@@ -152,18 +154,16 @@ def _matrix_from_crop(self, crop: np.ndarray) -> np.ndarray:
152154
matrix[y, x] = 1 if binary[cy, cx] < 128 else 0
153155
return matrix
154156

155-
def _extract_matrix(self) -> List[np.ndarray]:
157+
def _extract_matrix(self) -> List[npt.NDArray[np.int_]]:
156158
rois = self._detect_rois() if self._multiple else []
157159
if not rois: # No Aztec code croped, try to read the whole image
158160
img = cv2.imread(str(self.image_path))
159-
if img is None:
160-
raise InvalidParameterError(f"cannot read image: {self.image_path}")
161161
try:
162162
return [self._matrix_from_crop(img)]
163163
except (InvalidParameterError, UnsupportedSymbolError):
164164
return [] # no Aztec code found
165165

166-
matrices = []
166+
matrices: List[npt.NDArray[np.int_]] = []
167167
for crop, _ in rois:
168168
try:
169169
matrices.append(self._matrix_from_crop(crop))
@@ -174,15 +174,15 @@ def _extract_matrix(self) -> List[np.ndarray]:
174174
return matrices
175175

176176
@cached_property
177-
def matrices(self) -> List[np.ndarray]:
177+
def matrices(self) -> List[npt.NDArray[np.int_]]:
178178
"""List of module matrices detected in the image."""
179179
matrices = self._extract_matrix()
180180
if not matrices:
181181
raise InvalidParameterError("no Aztec matrix detected in the image")
182182
return matrices
183183

184184
@cached_property
185-
def matrix(self) -> np.ndarray:
185+
def matrix(self) -> npt.NDArray[np.int_]:
186186
"""The binary module matrix (0 = white, 1 = black), shape (N, N). Lazy property."""
187187
if not self.matrices:
188188
raise InvalidParameterError("no Aztec matrix detected in the image")

0 commit comments

Comments
 (0)