orient_express 2.2.0__tar.gz → 2.2.1__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.
Files changed (21) hide show
  1. {orient_express-2.2.0 → orient_express-2.2.1}/PKG-INFO +3 -3
  2. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/predictors/instance_segmentation.py +40 -18
  3. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/predictors/object_detection.py +7 -2
  4. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/predictors/semantic_segmentation.py +8 -5
  5. {orient_express-2.2.0 → orient_express-2.2.1}/pyproject.toml +3 -8
  6. {orient_express-2.2.0 → orient_express-2.2.1}/README.md +0 -0
  7. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/__init__.py +0 -0
  8. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/deployment.py +0 -0
  9. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/model_wrapper.py +0 -0
  10. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/predictors/__init__.py +0 -0
  11. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/predictors/classification.py +0 -0
  12. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/predictors/feature_extraction.py +0 -0
  13. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/predictors/multi_label_classification.py +0 -0
  14. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/predictors/predictor.py +0 -0
  15. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/sklearn_pipeline.py +0 -0
  16. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/utils/colors.py +0 -0
  17. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/utils/gs.py +0 -0
  18. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/utils/image_processor.py +0 -0
  19. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/utils/paths.py +0 -0
  20. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/utils/retry.py +0 -0
  21. {orient_express-2.2.0 → orient_express-2.2.1}/orient_express/vertex.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orient_express
3
- Version: 2.2.0
3
+ Version: 2.2.1
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
@@ -19,8 +19,8 @@ Requires-Dist: opencv-python-headless (>=4.11.0,<5.0.0)
19
19
  Requires-Dist: pandas (>=2.0,<3.0)
20
20
  Requires-Dist: pyyaml (>=6.0,<7.0)
21
21
  Requires-Dist: scikit-learn (>=1.5.0,<2.0.0)
22
- Requires-Dist: torch (>=2.5.0,<3.0.0)
23
- Requires-Dist: torchvision (>=0.20.0,<0.21.0)
22
+ Requires-Dist: torch (>=2.5.0)
23
+ Requires-Dist: torchvision (>=0.20.0)
24
24
  Requires-Dist: xgboost (>=2.0.0,<3.0.0)
25
25
  Description-Content-Type: text/markdown
26
26
 
@@ -10,6 +10,8 @@ import torch.nn.functional as F
10
10
  from .predictor import OnnxSessionWrapper, ImagePredictor
11
11
  from ..utils.image_processor import pil_to_opencv, opencv_to_pil
12
12
 
13
+ FONT = cv2.FONT_HERSHEY_SIMPLEX
14
+
13
15
 
14
16
  @dataclass
15
17
  class InstanceSegmentationPrediction:
@@ -128,7 +130,12 @@ class InstanceSegmentationPredictor(ImagePredictor):
128
130
  return outputs
129
131
 
130
132
  def get_annotated_image(
131
- self, image: Image.Image, predictions: list[InstanceSegmentationPrediction]
133
+ self,
134
+ image: Image.Image,
135
+ predictions: list[InstanceSegmentationPrediction],
136
+ mask_opacity: float = 0.3,
137
+ draw_indices: bool = True,
138
+ font_scale: float | None = None,
132
139
  ) -> Image.Image:
133
140
  opencv_image = pil_to_opencv(image)
134
141
  mask_overlay = opencv_image.copy()
@@ -137,15 +144,20 @@ class InstanceSegmentationPredictor(ImagePredictor):
137
144
  fill_color = self.color_scheme.get(pred.clss, (120, 120, 120))
138
145
  mask_overlay[pred.mask] = fill_color[:3]
139
146
 
140
- alpha = 0.5
141
147
  annotated_image = cv2.addWeighted(
142
- mask_overlay, alpha, opencv_image, 1 - alpha, 0
148
+ mask_overlay, mask_opacity, opencv_image, 1 - mask_opacity, 0
143
149
  )
144
150
 
145
- class_counts = defaultdict(int)
146
- for pred in predictions:
147
- class_counts[pred.clss] += 1
148
- self.draw_mask_index(annotated_image, pred, class_counts[pred.clss])
151
+ if draw_indices:
152
+ class_counts = defaultdict(int)
153
+ for pred in predictions:
154
+ class_counts[pred.clss] += 1
155
+ self.draw_mask_index(
156
+ annotated_image,
157
+ pred,
158
+ class_counts[pred.clss],
159
+ font_scale,
160
+ )
149
161
 
150
162
  return opencv_to_pil(annotated_image)
151
163
 
@@ -154,25 +166,35 @@ class InstanceSegmentationPredictor(ImagePredictor):
154
166
  opencv_image: np.ndarray,
155
167
  prediction: InstanceSegmentationPrediction,
156
168
  index: int,
169
+ font_scale: float | None = None,
157
170
  ):
158
- # Calculate the centroid of the bbox
159
- centroid_x = int((prediction.bbox[0] + prediction.bbox[2]) / 2)
160
- centroid_y = int((prediction.bbox[1] + prediction.bbox[3]) / 2)
161
- # Put the object count in the center of the bbox
162
- font_scale = 2
163
- font_thickness = 4
164
171
  text = str(index)
165
- text_size = cv2.getTextSize(
166
- text, cv2.FONT_HERSHEY_SIMPLEX, font_scale, font_thickness
167
- )[0]
172
+
173
+ bbox = prediction.bbox
174
+ bbox_width = bbox[2] - bbox[0]
175
+ bbox_height = bbox[3] - bbox[1]
176
+
177
+ if font_scale is None:
178
+ target_size = min(bbox_width, bbox_height) * 0.3
179
+ (base_w, base_h), _ = cv2.getTextSize(text, FONT, 1, 1)
180
+ font_scale = target_size / max(base_w, base_h)
181
+
182
+ assert font_scale is not None
183
+ thickness = max(int(font_scale * 2), 1)
184
+
185
+ text_size = cv2.getTextSize(text, FONT, font_scale, thickness)[0]
186
+
187
+ centroid_x = int((bbox[0] + bbox[2]) / 2)
188
+ centroid_y = int((bbox[1] + bbox[3]) / 2)
168
189
  text_x = int(centroid_x - text_size[0] / 2)
169
190
  text_y = int(centroid_y + text_size[1] / 2)
191
+
170
192
  cv2.putText(
171
193
  opencv_image,
172
194
  text,
173
195
  (text_x, text_y),
174
- cv2.FONT_HERSHEY_SIMPLEX,
196
+ FONT,
175
197
  font_scale,
176
198
  (255, 255, 255),
177
- font_thickness,
199
+ thickness,
178
200
  )
@@ -117,7 +117,10 @@ class BoundingBoxPredictor(ImagePredictor):
117
117
  return outputs
118
118
 
119
119
  def get_annotated_image(
120
- self, image: Image.Image, predictions: list[BoundingBoxPrediction]
120
+ self,
121
+ image: Image.Image,
122
+ predictions: list[BoundingBoxPrediction],
123
+ line_width: int = 8,
121
124
  ):
122
125
  opencv_image = pil_to_opencv(image)
123
126
 
@@ -125,6 +128,8 @@ class BoundingBoxPredictor(ImagePredictor):
125
128
  color = self.color_scheme.get(pred.clss, (255, 255, 255))
126
129
  x1, y1, x2, y2 = pred.bbox
127
130
  x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
128
- opencv_image = cv2.rectangle(opencv_image, (x1, y1), (x2, y2), color, 2)
131
+ opencv_image = cv2.rectangle(
132
+ opencv_image, (x1, y1), (x2, y2), color, line_width
133
+ )
129
134
 
130
135
  return opencv_to_pil(opencv_image)
@@ -76,15 +76,18 @@ class SemanticSegmentationPredictor(ImagePredictor):
76
76
  )
77
77
  return outputs
78
78
 
79
- def get_annotated_image(self, image: Image.Image, mask: np.array) -> Image.Image:
79
+ def get_annotated_image(
80
+ self, image: Image.Image, mask: np.array, mask_opacity: float = 0.3
81
+ ) -> Image.Image:
80
82
  opencv_image = pil_to_opencv(image)
81
-
82
- mask_rgb = np.zeros((*mask.shape, 3), dtype=np.uint8)
83
+ mask_overlay = opencv_image.copy()
83
84
 
84
85
  for class_id, class_name in self.classes.items():
85
86
  fill_color = self.color_scheme.get(class_name, (120, 120, 120))
86
- mask_rgb[mask == class_id] = fill_color[:3]
87
+ mask_overlay[mask == class_id] = fill_color[:3]
87
88
 
88
- annotated_image = cv2.addWeighted(opencv_image, 0.7, mask_rgb, 0.3, 0)
89
+ annotated_image = cv2.addWeighted(
90
+ mask_overlay, mask_opacity, opencv_image, 1 - mask_opacity, 0
91
+ )
89
92
 
90
93
  return opencv_to_pil(annotated_image)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "orient_express"
3
- version = "2.2.0"
3
+ version = "2.2.1"
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"
@@ -11,8 +11,8 @@ google-cloud-aiplatform = "^1.0"
11
11
  google-cloud-storage = "^3.0"
12
12
  pandas = "^2.0"
13
13
  pyyaml = "^6.0"
14
- torch = {version = "^2.5.0", source = "pytorch-cpu"}
15
- torchvision = {version = "^0.20.0", source = "pytorch-cpu"}
14
+ torch = ">=2.5.0"
15
+ torchvision = ">=0.20.0"
16
16
  opencv-python-headless = "^4.11.0"
17
17
  Pillow = ">=10.0.1"
18
18
  gcsfs = "^2024.10.0"
@@ -30,8 +30,3 @@ python-json-logger = "^4.0.0"
30
30
  [build-system]
31
31
  requires = ["poetry-core"]
32
32
  build-backend = "poetry.core.masonry.api"
33
-
34
- [[tool.poetry.source]]
35
- name = "pytorch-cpu"
36
- url = "https://download.pytorch.org/whl/cpu"
37
- priority = "explicit"
File without changes