orient_express 2.1__tar.gz → 2.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {orient_express-2.1 → orient_express-2.1.2}/PKG-INFO +8 -10
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/predictors/classification.py +1 -5
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/predictors/instance_segmentation.py +15 -22
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/predictors/multi_label_classification.py +1 -5
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/predictors/object_detection.py +11 -18
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/predictors/predictor.py +14 -1
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/predictors/semantic_segmentation.py +6 -13
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/utils/image_processor.py +9 -1
- {orient_express-2.1 → orient_express-2.1.2}/pyproject.toml +10 -13
- {orient_express-2.1 → orient_express-2.1.2}/README.md +0 -0
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/__init__.py +0 -0
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/deployment.py +0 -0
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/model_wrapper.py +0 -0
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/predictors/__init__.py +0 -0
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/sklearn_pipeline.py +0 -0
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/utils/colors.py +0 -0
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/utils/gs.py +0 -0
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/utils/paths.py +0 -0
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/utils/retry.py +0 -0
- {orient_express-2.1 → orient_express-2.1.2}/orient_express/vertex.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: orient_express
|
|
3
|
-
Version: 2.1
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: A library to simplify model deployment to Vertex AI
|
|
5
5
|
Author: Alexey Zankevich
|
|
6
6
|
Author-email: alex.zankevich@shiftsmart.com
|
|
@@ -9,21 +9,19 @@ Classifier: Programming Language :: Python :: 3
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.10
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.11
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
-
Requires-Dist: Pillow (
|
|
12
|
+
Requires-Dist: Pillow (>=10.0.1)
|
|
13
13
|
Requires-Dist: gcsfs (>=2024.10.0,<2025.0.0)
|
|
14
|
-
Requires-Dist: google-cloud-aiplatform
|
|
15
|
-
Requires-Dist: google-cloud-storage
|
|
16
|
-
Requires-Dist: kserve (==0.16.0)
|
|
14
|
+
Requires-Dist: google-cloud-aiplatform (>=1.0,<2.0)
|
|
15
|
+
Requires-Dist: google-cloud-storage (>=3.0,<4.0)
|
|
17
16
|
Requires-Dist: onnxruntime (>=1.20,<2.0) ; sys_platform == "darwin" or platform_machine == "aarch64" or platform_machine == "arm64" or sys_platform == "win32" and platform_machine == "ARM64"
|
|
18
17
|
Requires-Dist: onnxruntime-gpu (>=1.20,<2.0) ; sys_platform == "linux" and platform_machine == "x86_64" or sys_platform == "win32" and platform_machine == "AMD64"
|
|
19
|
-
Requires-Dist: opencv-python-headless (
|
|
20
|
-
Requires-Dist: pandas
|
|
21
|
-
Requires-Dist: python-json-logger (==2.0.7)
|
|
18
|
+
Requires-Dist: opencv-python-headless (>=4.11.0,<5.0.0)
|
|
19
|
+
Requires-Dist: pandas (>=2.0,<3.0)
|
|
22
20
|
Requires-Dist: pyyaml (>=6.0,<7.0)
|
|
23
|
-
Requires-Dist: scikit-learn (
|
|
21
|
+
Requires-Dist: scikit-learn (>=1.5.0,<2.0.0)
|
|
24
22
|
Requires-Dist: torch (>=2.5.0,<3.0.0)
|
|
25
23
|
Requires-Dist: torchvision (>=0.20.0,<0.21.0)
|
|
26
|
-
Requires-Dist: xgboost (
|
|
24
|
+
Requires-Dist: xgboost (>=2.0.0,<3.0.0)
|
|
27
25
|
Description-Content-Type: text/markdown
|
|
28
26
|
|
|
29
27
|
# Orient Express
|
|
@@ -23,11 +23,7 @@ class ClassificationPrediction:
|
|
|
23
23
|
|
|
24
24
|
class OnnxClassifier(OnnxSessionWrapper):
|
|
25
25
|
def __call__(self, pil_images: list[Image.Image]):
|
|
26
|
-
|
|
27
|
-
cv2.resize(np.array(pil_img), (self.resolution, self.resolution))
|
|
28
|
-
for pil_img in pil_images
|
|
29
|
-
]
|
|
30
|
-
images_array = np.array(images)
|
|
26
|
+
images_array = self.collate_images(pil_images)
|
|
31
27
|
|
|
32
28
|
input_dict = {self.input_names[0]: images_array}
|
|
33
29
|
|
{orient_express-2.1 → orient_express-2.1.2}/orient_express/predictors/instance_segmentation.py
RENAMED
|
@@ -35,13 +35,19 @@ class InstanceSegmentationPrediction:
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
class OnnxInstanceSegmentation(OnnxSessionWrapper):
|
|
38
|
-
def
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
def __call__(self, pil_images: list[Image.Image], confidence: float = 0.5):
|
|
39
|
+
images_array = self.collate_images(pil_images)
|
|
40
|
+
target_sizes_array = self.collate_sizes(pil_images)
|
|
41
|
+
|
|
42
|
+
input_dict = {
|
|
43
|
+
self.input_names[0]: images_array,
|
|
44
|
+
self.input_names[1]: target_sizes_array,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
boxes, scores, labels, masks = self.session.run(None, input_dict)
|
|
48
|
+
return self.postprocess(
|
|
49
|
+
boxes, scores, labels, masks, target_sizes_array, confidence
|
|
50
|
+
)
|
|
45
51
|
|
|
46
52
|
def postprocess(
|
|
47
53
|
self,
|
|
@@ -92,19 +98,6 @@ class OnnxInstanceSegmentation(OnnxSessionWrapper):
|
|
|
92
98
|
|
|
93
99
|
return results
|
|
94
100
|
|
|
95
|
-
def __call__(self, pil_images: list[Image.Image], confidence: float = 0.5):
|
|
96
|
-
images_array, target_sizes_array = self.preprocess(pil_images)
|
|
97
|
-
|
|
98
|
-
input_dict = {
|
|
99
|
-
self.input_names[0]: images_array,
|
|
100
|
-
self.input_names[1]: target_sizes_array,
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
boxes, scores, labels, masks = self.session.run(None, input_dict)
|
|
104
|
-
return self.postprocess(
|
|
105
|
-
boxes, scores, labels, masks, target_sizes_array, confidence
|
|
106
|
-
)
|
|
107
|
-
|
|
108
101
|
|
|
109
102
|
class InstanceSegmentationPredictor(ImagePredictor):
|
|
110
103
|
model_type = "instance-segmentation-onnx"
|
|
@@ -166,8 +159,8 @@ class InstanceSegmentationPredictor(ImagePredictor):
|
|
|
166
159
|
centroid_x = int((prediction.bbox[0] + prediction.bbox[2]) / 2)
|
|
167
160
|
centroid_y = int((prediction.bbox[1] + prediction.bbox[3]) / 2)
|
|
168
161
|
# Put the object count in the center of the bbox
|
|
169
|
-
font_scale =
|
|
170
|
-
font_thickness =
|
|
162
|
+
font_scale = 2
|
|
163
|
+
font_thickness = 4
|
|
171
164
|
text = str(index)
|
|
172
165
|
text_size = cv2.getTextSize(
|
|
173
166
|
text, cv2.FONT_HERSHEY_SIMPLEX, font_scale, font_thickness
|
{orient_express-2.1 → orient_express-2.1.2}/orient_express/predictors/multi_label_classification.py
RENAMED
|
@@ -21,11 +21,7 @@ class MultiLabelClassificationPrediction:
|
|
|
21
21
|
|
|
22
22
|
class OnnxMultiLabelClassifier(OnnxSessionWrapper):
|
|
23
23
|
def __call__(self, pil_images: list[Image.Image]):
|
|
24
|
-
|
|
25
|
-
cv2.resize(np.array(pil_img), (self.resolution, self.resolution))
|
|
26
|
-
for pil_img in pil_images
|
|
27
|
-
]
|
|
28
|
-
images_array = np.array(images)
|
|
24
|
+
images_array = self.collate_images(pil_images)
|
|
29
25
|
|
|
30
26
|
input_dict = {self.input_names[0]: images_array}
|
|
31
27
|
|
|
@@ -30,13 +30,17 @@ class BoundingBoxPrediction:
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class OnnxDetector(OnnxSessionWrapper):
|
|
33
|
-
def
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
def __call__(self, pil_images: list[Image.Image], confidence: float = 0.5):
|
|
34
|
+
images_array = self.collate_images(pil_images)
|
|
35
|
+
target_sizes_array = self.collate_sizes(pil_images)
|
|
36
|
+
|
|
37
|
+
input_dict = {
|
|
38
|
+
self.input_names[0]: images_array,
|
|
39
|
+
self.input_names[1]: target_sizes_array,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
boxes, scores, labels = self.session.run(None, input_dict)
|
|
43
|
+
return self.postprocess(boxes, scores, labels, confidence)
|
|
40
44
|
|
|
41
45
|
def postprocess(
|
|
42
46
|
self,
|
|
@@ -67,17 +71,6 @@ class OnnxDetector(OnnxSessionWrapper):
|
|
|
67
71
|
|
|
68
72
|
return results
|
|
69
73
|
|
|
70
|
-
def __call__(self, pil_images: list[Image.Image], confidence: float = 0.5):
|
|
71
|
-
images_array, target_sizes_array = self.preprocess(pil_images)
|
|
72
|
-
|
|
73
|
-
input_dict = {
|
|
74
|
-
self.input_names[0]: images_array,
|
|
75
|
-
self.input_names[1]: target_sizes_array,
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
boxes, scores, labels = self.session.run(None, input_dict)
|
|
79
|
-
return self.postprocess(boxes, scores, labels, confidence)
|
|
80
|
-
|
|
81
74
|
|
|
82
75
|
class BoundingBoxPredictor(ImagePredictor):
|
|
83
76
|
model_type = "object-detection-onnx"
|
|
@@ -4,9 +4,13 @@ import warnings
|
|
|
4
4
|
|
|
5
5
|
import yaml
|
|
6
6
|
import onnxruntime as ort
|
|
7
|
+
from PIL import Image
|
|
8
|
+
import cv2
|
|
9
|
+
import numpy as np
|
|
7
10
|
|
|
8
11
|
from ..utils.paths import get_metadata_path
|
|
9
12
|
from ..utils.colors import generate_color_scheme
|
|
13
|
+
from ..utils.image_processor import image_to_array
|
|
10
14
|
|
|
11
15
|
|
|
12
16
|
class Predictor(ABC):
|
|
@@ -42,7 +46,7 @@ class ImagePredictor(Predictor):
|
|
|
42
46
|
self.model_path = model_path
|
|
43
47
|
|
|
44
48
|
def get_serving_container_image_uri(self):
|
|
45
|
-
return "us-west1-docker.pkg.dev/shiftsmart-api/orient-express/image-onnx:v2.1"
|
|
49
|
+
return "us-west1-docker.pkg.dev/shiftsmart-api/orient-express/image-onnx:v2.1.2"
|
|
46
50
|
|
|
47
51
|
def get_serving_container_health_route(self, model_name):
|
|
48
52
|
return f"/v1/models/{model_name}"
|
|
@@ -92,3 +96,12 @@ class OnnxSessionWrapper:
|
|
|
92
96
|
|
|
93
97
|
input_shape = self.session.get_inputs()[0].shape
|
|
94
98
|
self.resolution = input_shape[1]
|
|
99
|
+
self.img_size = (self.resolution, self.resolution)
|
|
100
|
+
|
|
101
|
+
def collate_sizes(self, pil_images: list[Image.Image]):
|
|
102
|
+
sizes = [[img.size[1], img.size[0]] for img in pil_images]
|
|
103
|
+
return np.array(sizes, dtype=np.float32)
|
|
104
|
+
|
|
105
|
+
def collate_images(self, pil_images: list[Image.Image]):
|
|
106
|
+
images = [cv2.resize(image_to_array(img), self.img_size) for img in pil_images]
|
|
107
|
+
return np.array(images)
|
{orient_express-2.1 → orient_express-2.1.2}/orient_express/predictors/semantic_segmentation.py
RENAMED
|
@@ -25,13 +25,12 @@ class SemanticSegmentationPrediction:
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class OnnxSemanticSegmentation(OnnxSessionWrapper):
|
|
28
|
-
def
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return np.array(images), np.array(sizes, dtype=np.float32)
|
|
28
|
+
def __call__(self, pil_images: list[Image.Image]):
|
|
29
|
+
images_array = self.collate_images(pil_images)
|
|
30
|
+
target_sizes_array = self.collate_sizes(pil_images)
|
|
31
|
+
input_dict = {self.input_names[0]: images_array}
|
|
32
|
+
masks = self.session.run(None, input_dict)[0]
|
|
33
|
+
return self.postprocess(masks, target_sizes_array)
|
|
35
34
|
|
|
36
35
|
def postprocess(self, masks: np.ndarray, target_sizes: np.ndarray):
|
|
37
36
|
results: list[np.ndarray] = []
|
|
@@ -55,12 +54,6 @@ class OnnxSemanticSegmentation(OnnxSessionWrapper):
|
|
|
55
54
|
|
|
56
55
|
return results
|
|
57
56
|
|
|
58
|
-
def __call__(self, pil_images: list[Image.Image]):
|
|
59
|
-
images_array, target_sizes_array = self.preprocess(pil_images)
|
|
60
|
-
input_dict = {self.input_names[0]: images_array}
|
|
61
|
-
masks = self.session.run(None, input_dict)[0]
|
|
62
|
-
return self.postprocess(masks, target_sizes_array)
|
|
63
|
-
|
|
64
57
|
|
|
65
58
|
class SemanticSegmentationPredictor(ImagePredictor):
|
|
66
59
|
model_type = "semantic-segmentation-onnx"
|
|
@@ -82,8 +82,16 @@ def image_to_bytes(image):
|
|
|
82
82
|
return buffered.getvalue()
|
|
83
83
|
|
|
84
84
|
|
|
85
|
+
def base64_to_image(base64_data: str):
|
|
86
|
+
return Image.open(BytesIO(base64.b64decode(base64_data)))
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def image_to_array(image: Image.Image):
|
|
90
|
+
return np.array(image.convert("RGB"))
|
|
91
|
+
|
|
92
|
+
|
|
85
93
|
def pil_to_opencv(image: Image.Image):
|
|
86
|
-
return cv2.cvtColor(
|
|
94
|
+
return cv2.cvtColor(image_to_array(image), cv2.COLOR_RGB2BGR)
|
|
87
95
|
|
|
88
96
|
|
|
89
97
|
def opencv_to_pil(image: np.ndarray):
|
|
@@ -1,34 +1,31 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "orient_express"
|
|
3
|
-
version = "2.1"
|
|
3
|
+
version = "2.1.2"
|
|
4
4
|
description = "A library to simplify model deployment to Vertex AI"
|
|
5
5
|
authors = ["Alexey Zankevich <alex.zankevich@shiftsmart.com>", "Ian Myers <ian.myers@shiftsmart.com>"]
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
|
|
8
8
|
[tool.poetry.dependencies]
|
|
9
9
|
python = ">=3.10,<3.13"
|
|
10
|
-
google-cloud-aiplatform = "
|
|
11
|
-
google-cloud-storage = "
|
|
12
|
-
pandas = "
|
|
10
|
+
google-cloud-aiplatform = "^1.0"
|
|
11
|
+
google-cloud-storage = "^3.0"
|
|
12
|
+
pandas = "^2.0"
|
|
13
13
|
pyyaml = "^6.0"
|
|
14
|
-
|
|
15
|
-
kserve = "0.16.0"
|
|
16
14
|
torch = {version = "^2.5.0", source = "pytorch-cpu"}
|
|
17
15
|
torchvision = {version = "^0.20.0", source = "pytorch-cpu"}
|
|
18
|
-
opencv-python-headless = "4.11.0
|
|
19
|
-
Pillow = "10.0.1"
|
|
20
|
-
python-json-logger = "2.0.7"
|
|
16
|
+
opencv-python-headless = "^4.11.0"
|
|
17
|
+
Pillow = ">=10.0.1"
|
|
21
18
|
gcsfs = "^2024.10.0"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
xgboost = "2.1.2"
|
|
25
|
-
|
|
19
|
+
scikit-learn = "^1.5.0"
|
|
20
|
+
xgboost = "^2.0.0"
|
|
26
21
|
onnxruntime-gpu = {version = "^1.20", markers = "sys_platform == 'linux' and platform_machine == 'x86_64' or sys_platform == 'win32' and platform_machine == 'AMD64'"}
|
|
27
22
|
onnxruntime = {version = "^1.20", markers = "sys_platform == 'darwin' or platform_machine == 'aarch64' or platform_machine == 'arm64' or sys_platform == 'win32' and platform_machine == 'ARM64'"}
|
|
28
23
|
|
|
29
24
|
[tool.poetry.group.dev.dependencies]
|
|
30
25
|
black = "24.10.0"
|
|
31
26
|
pytest = "8.3.3"
|
|
27
|
+
kserve = "^0.16.0"
|
|
28
|
+
python-json-logger = "^4.0.0"
|
|
32
29
|
|
|
33
30
|
[build-system]
|
|
34
31
|
requires = ["poetry-core"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|