Skip to content

Commit 08b70d7

Browse files
authored
tests: validate additional models, small fixes (#410)
* save * save * save * fix * remove github actions
1 parent e8356ff commit 08b70d7

File tree

9 files changed

+8138
-7
lines changed

9 files changed

+8138
-7
lines changed

src/model_api/models/instance_segmentation.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,14 @@ def postprocess(self, outputs: dict, meta: dict) -> InstanceSegmentationResult:
185185
saliency_maps = []
186186

187187
# Apply confidence threshold, bounding box area filter and label index filter.
188-
keep = (scores > self.confidence_threshold) & ((boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1]) > 1)
188+
# Calculate box areas safely to avoid overflow
189+
box_widths = np.clip(boxes[:, 2] - boxes[:, 0], 0, None)
190+
box_heights = np.clip(boxes[:, 3] - boxes[:, 1], 0, None)
191+
192+
# Use float64 for area calculation to prevent overflow, then check if area > 1
193+
box_areas = box_widths.astype(np.float64) * box_heights.astype(np.float64)
194+
195+
keep = (scores > self.confidence_threshold) & (box_areas > 1)
189196

190197
if self.labels:
191198
keep &= labels < len(self.labels)

src/model_api/models/segmentation.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,9 @@ def get_contours(
241241
cv2.drawContours(mask, contours, contourIdx=next_child_idx, color=0, thickness=-1)
242242
next_child_idx = hierarchy[next_child_idx][0]
243243

244+
if current_label_soft_prediction.dtype != np.float32:
245+
current_label_soft_prediction = current_label_soft_prediction.astype(np.float32)
246+
244247
probability = cv2.mean(current_label_soft_prediction, mask)[0]
245248
combined_contours.append(Contour(label, probability, contour, children))
246249

src/model_api/models/utils.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,12 @@ def add_rotated_rects(inst_seg_result: InstanceSegmentationResult) -> RotatedSeg
2626
cv2.RETR_EXTERNAL,
2727
cv2.CHAIN_APPROX_SIMPLE,
2828
)
29-
contour = np.vstack(contours)
30-
objects_with_rects.append(cv2.minAreaRect(contour))
29+
# Check if contours were found before processing
30+
if contours:
31+
contour = np.vstack(contours)
32+
objects_with_rects.append(cv2.minAreaRect(contour))
33+
else:
34+
objects_with_rects.append(((0, 0), (0, 0), 0))
3135
return RotatedSegmentationResult(
3236
bboxes=inst_seg_result.bboxes,
3337
masks=inst_seg_result.masks,

tests/accuracy/conftest.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010

1111
def pytest_addoption(parser):
1212
parser.addoption("--data", action="store", help="data folder with dataset")
13+
parser.addoption(
14+
"--model_data",
15+
action="store",
16+
default="public_scope.json",
17+
help="path to model data JSON file for test parameterization",
18+
)
1319
parser.addoption(
1420
"--device",
1521
action="store",

tests/accuracy/download_models.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#
2+
# Copyright (C) 2025 Intel Corporation
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
import argparse
6+
import asyncio
7+
import json
8+
import time
9+
from pathlib import Path
10+
11+
import httpx
12+
13+
14+
async def stream_file(client, url, filename, semaphore):
15+
async with semaphore:
16+
start_time = time.time()
17+
total_bytes = 0
18+
async with client.stream("GET", url) as stream:
19+
with Path(filename).open("wb") as file:
20+
async for data in stream.aiter_bytes():
21+
file.write(data)
22+
total_bytes += len(data)
23+
end_time = time.time()
24+
download_time = end_time - start_time
25+
total_bytes /= 1024 * 1024
26+
27+
speed_mbps = total_bytes / download_time if download_time > 0 else 0
28+
print(f"Downloaded {url} - {total_bytes:.2f} MB in {download_time:.2f}s ({speed_mbps:.2f} MB/s)")
29+
30+
31+
async def main():
32+
parser = argparse.ArgumentParser()
33+
parser.add_argument(
34+
"-d",
35+
"--data_dir",
36+
type=Path,
37+
required=True,
38+
help="Directory to store downloaded models and datasets",
39+
)
40+
parser.add_argument(
41+
"-j",
42+
"--json_path",
43+
type=Path,
44+
required=True,
45+
help="Path to the JSON file with model information",
46+
)
47+
args = parser.parse_args()
48+
49+
with args.json_path.open("r") as f:
50+
models_data = json.load(f)
51+
52+
base_path = "https://storage.geti.intel.com/geti_predict/test/"
53+
semaphore = asyncio.Semaphore(10)
54+
args.data_dir.mkdir(parents=True, exist_ok=True)
55+
async with httpx.AsyncClient(timeout=60.0) as client:
56+
tasks = []
57+
for model_entry in models_data:
58+
model_name = model_entry["name"]
59+
download_url = base_path + model_name
60+
save_path = args.data_dir / model_name
61+
save_path.parent.mkdir(parents=True, exist_ok=True)
62+
tasks.append(stream_file(client, download_url, save_path, semaphore))
63+
64+
if model_name.endswith(".xml"):
65+
tasks.append(
66+
stream_file(client, download_url.replace(".xml", ".bin"), save_path.with_suffix(".bin"), semaphore),
67+
)
68+
69+
print(f"Starting download of {len(tasks)} files with max 10 concurrent downloads...")
70+
await asyncio.gather(*tasks)
71+
print(f"All {len(tasks)} files downloaded successfully!")
72+
73+
74+
if __name__ == "__main__":
75+
asyncio.run(main())

0 commit comments

Comments
 (0)