Skip to content

Commit 841d73a

Browse files
authored
Merge pull request #10 from cospectrum/dev
remove opencv
2 parents c50dbed + 68544a1 commit 841d73a

File tree

5 files changed

+48
-41
lines changed

5 files changed

+48
-41
lines changed

pyproject.toml

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ requires-python = ">=3.10"
99
dependencies = [
1010
"numpy>=2.2.0",
1111
"onnxruntime>=1.20.1",
12-
"opencv-python>=4.10.0.84",
1312
"pillow>=11.0.0",
1413
]
1514

src/microwink/seg.py

+27-18
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
H = NewType("H", int)
1818
W = NewType("W", int)
19-
RgbBuf = NewType("RgbBuf", np.ndarray)
2019

2120

2221
@dataclass
@@ -84,8 +83,13 @@ def apply(
8483
) -> list[SegResult]:
8584
CLASS_ID = 0
8685
assert image.mode == "RGB"
87-
buf = RgbBuf(np.array(image))
88-
raw = self._run(buf, threshold.confidence, threshold.iou)
86+
assert image.width > 0
87+
assert image.height > 0
88+
89+
assert 0.0 <= threshold.iou <= 1.0
90+
assert 0.0 <= threshold.confidence <= 1.0
91+
92+
raw = self._run(image, threshold.confidence, iou_threshold=threshold.iou)
8993
if raw is None:
9094
return []
9195

@@ -105,17 +109,16 @@ def apply(
105109
return results
106110

107111
def _run(
108-
self, img: RgbBuf, conf_threshold: float, iou_threshold: float
112+
self, image: PILImage, conf_threshold: float, iou_threshold: float
109113
) -> RawResult | None:
110114
NM = 32
111-
ih, iw, _ = img.shape
112-
113-
blob, ratio, (pad_w, pad_h) = self.preprocess(img)
115+
assert image.mode == "RGB"
116+
blob, ratio, (pad_w, pad_h) = self.preprocess(image)
114117
assert blob.ndim == 4
115118
preds = self.session.run(None, {self.input_.name: blob})
116119
return self.postprocess(
117120
preds,
118-
img_size=(ih, iw),
121+
img_size=(H(image.height), W(image.width)),
119122
ratio=ratio,
120123
pad_w=pad_w,
121124
pad_h=pad_h,
@@ -125,15 +128,20 @@ def _run(
125128
)
126129

127130
def preprocess(
128-
self, img_buf: RgbBuf
131+
self, image: PILImage
129132
) -> tuple[np.ndarray, float, tuple[float, float]]:
130133
BORDER_COLOR = (114, 114, 114)
131134
EPS = 0.1
132-
img = np.array(img_buf)
135+
136+
assert image.mode == "RGB"
137+
img = np.array(image)
138+
133139
ih, iw, _ = img.shape
134140
oh, ow = self.model_height, self.model_width
135141
r = min(oh / ih, ow / iw)
136142
rw, rh = round(iw * r), round(ih * r)
143+
rw = max(1, rw)
144+
rh = max(1, rh)
137145

138146
pad_w, pad_h = [
139147
(ow - rw) / 2,
@@ -167,16 +175,16 @@ def postprocess(
167175
B = 1
168176
NM, MH, MW = (nm, 160, 160)
169177
NUM_CLASSES = 1
170-
C = 4 + NUM_CLASSES + NM
171178

172179
x, protos = preds
173180
assert len(x) == len(protos) == B
174181
protos = protos[0]
175182
x = x[0].T
176183
assert protos.shape == (NM, MH, MW), protos.shape
177-
assert x.shape == (len(x), C)
184+
assert x.shape == (len(x), 4 + NUM_CLASSES + NM)
178185

179186
likely = x[:, 4 : 4 + NUM_CLASSES].max(axis=1) > conf_threshold
187+
assert likely.ndim == 1
180188
x = x[likely]
181189

182190
scores = x[:, 4 : 4 + NUM_CLASSES].max(axis=1)
@@ -335,14 +343,15 @@ def with_border(
335343
bottom: int,
336344
left: int,
337345
right: int,
338-
color: tuple[int, int, int],
346+
color: Color,
339347
) -> np.ndarray:
340-
import cv2
341-
342348
assert img.ndim == 3
343-
return cv2.copyMakeBorder(
344-
img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color
345-
)
349+
pil_img = Image.fromarray(img)
350+
ow = pil_img.width + left + right
351+
oh = pil_img.height + top + bottom
352+
out = Image.new("RGB", (ow, oh), color)
353+
out.paste(pil_img, (left, top))
354+
return np.array(out).astype(img.dtype)
346355

347356

348357
def resize(buf: np.ndarray, size: tuple[W, H]) -> np.ndarray:

tests/test_props.py

+18-3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,26 @@
1010

1111

1212
@settings(
13-
deadline=1 * 1000,
14-
max_examples=50,
13+
max_examples=200,
14+
)
15+
@given(img=arb_img((1, 2000), (1, 2000)))
16+
def test_preprocess(img: PILImage, seg_model: SegModel) -> None:
17+
B = 1
18+
CH = 3
19+
H = seg_model.model_height
20+
W = seg_model.model_width
21+
22+
blob, *_ = seg_model.preprocess(img)
23+
assert blob.shape == (B, CH, H, W)
24+
assert blob.min() >= 0.0
25+
assert blob.max() <= 1.0
26+
27+
28+
@settings(
29+
deadline=2 * 1000,
1530
)
1631
@given(
17-
img=arb_img((1, 1000), (1, 1000)),
32+
img=arb_img((1, 2000), (1, 2000)),
1833
iou=st.none() | st.floats(0.01, 1.0),
1934
score=st.none() | st.floats(0.01, 1.0),
2035
)

tests/test_samples.py

+3
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ def test_samples(
4949
actual = img.copy()
5050
for card, box in zip(cards, boxes):
5151
assert 0.0 < card.score < 1.0
52+
assert card.mask.min() >= 0.0
53+
assert card.mask.max() <= 1.0
5254
assert round_box(card.box) == box
55+
5356
actual = draw_box(actual, card.box)
5457
actual = draw_mask(actual, card.mask > BIN_THRESHOLD)
5558
assert truth == actual

uv.lock

-19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)