mb-rag 1.0.117__py3-none-any.whl → 1.0.124__py3-none-any.whl
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.
Potentially problematic release.
This version of mb-rag might be problematic. Click here for more details.
- mb_rag/chatbot/basic.py +329 -295
- mb_rag/chatbot/chains.py +163 -202
- mb_rag/utils/bounding_box.py +203 -76
- mb_rag/utils/extra.py +1 -1
- mb_rag/version.py +1 -1
- {mb_rag-1.0.117.dist-info → mb_rag-1.0.124.dist-info}/METADATA +1 -1
- mb_rag-1.0.124.dist-info/RECORD +15 -0
- mb_rag-1.0.117.dist-info/RECORD +0 -15
- {mb_rag-1.0.117.dist-info → mb_rag-1.0.124.dist-info}/WHEEL +0 -0
- {mb_rag-1.0.117.dist-info → mb_rag-1.0.124.dist-info}/top_level.txt +0 -0
mb_rag/utils/bounding_box.py
CHANGED
|
@@ -1,96 +1,223 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"""
|
|
2
|
+
Bounding box utilities
|
|
3
|
+
"""
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import os
|
|
6
|
+
from typing import List, Dict, Any, Optional, Tuple, Union
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from mb_rag.utils.extra import check_package
|
|
6
9
|
|
|
10
|
+
__all__ = ['BoundingBoxConfig', 'BoundingBoxProcessor']
|
|
7
11
|
|
|
8
|
-
def
|
|
12
|
+
def check_image_dependencies() -> None:
|
|
9
13
|
"""
|
|
10
|
-
Check if
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Returns:
|
|
14
|
-
bool: True if package is installed, False otherwise
|
|
14
|
+
Check if required image processing packages are installed
|
|
15
|
+
Raises:
|
|
16
|
+
ImportError: If any required package is missing
|
|
15
17
|
"""
|
|
16
|
-
|
|
18
|
+
if not check_package("PIL"):
|
|
19
|
+
raise ImportError("Pillow package not found. Please install it using: pip install Pillow")
|
|
20
|
+
if not check_package("cv2"):
|
|
21
|
+
raise ImportError("OpenCV package not found. Please install it using: pip install opencv-python")
|
|
22
|
+
if not check_package("google.generativeai"):
|
|
23
|
+
raise ImportError("Google Generative AI package not found. Please install it using: pip install google-generativeai")
|
|
17
24
|
|
|
25
|
+
@dataclass
|
|
26
|
+
class BoundingBoxConfig:
|
|
27
|
+
"""Configuration for bounding box operations"""
|
|
28
|
+
model_name: str = "gemini-1.5-pro-latest"
|
|
29
|
+
api_key: Optional[str] = None
|
|
30
|
+
default_prompt: str = 'Return bounding boxes of container, for each only one return [ymin, xmin, ymax, xmax]'
|
|
18
31
|
|
|
19
|
-
|
|
32
|
+
class BoundingBoxProcessor:
|
|
20
33
|
"""
|
|
21
|
-
|
|
22
|
-
Args:
|
|
23
|
-
image_path (str): Image path
|
|
24
|
-
model_name (GenerativeModel): GenerativeModel object - google model (Default: )
|
|
25
|
-
prompt (str): Prompt
|
|
26
|
-
Returns:
|
|
27
|
-
res (str): Result
|
|
28
|
-
Raises:
|
|
29
|
-
FileNotFoundError: If image file doesn't exist
|
|
30
|
-
ValueError: If model is None or invalid
|
|
31
|
-
"""
|
|
32
|
-
try:
|
|
33
|
-
model = get_chatbot_google_generative_ai(model_name)
|
|
34
|
-
except Exception as e:
|
|
35
|
-
raise ValueError(f"Error initializing model: {str(e)}")
|
|
36
|
-
|
|
37
|
-
if not os.path.exists(image_path):
|
|
38
|
-
raise FileNotFoundError(f"Image file not found: {image_path}")
|
|
34
|
+
Class for processing images and generating bounding boxes
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
Attributes:
|
|
37
|
+
model: The Google Generative AI model instance
|
|
38
|
+
config: Configuration for bounding box operations
|
|
39
|
+
"""
|
|
44
40
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
41
|
+
def __init__(self, config: Optional[BoundingBoxConfig] = None, **kwargs):
|
|
42
|
+
"""
|
|
43
|
+
Initialize bounding box processor
|
|
44
|
+
Args:
|
|
45
|
+
config: Configuration for the processor
|
|
46
|
+
**kwargs: Additional arguments
|
|
47
|
+
"""
|
|
48
|
+
check_image_dependencies()
|
|
49
|
+
self.config = config or BoundingBoxConfig(**kwargs)
|
|
50
|
+
self._initialize_model()
|
|
51
|
+
self._initialize_image_libs()
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
53
|
+
@classmethod
|
|
54
|
+
def from_model(cls, model_name: str, api_key: Optional[str] = None, **kwargs) -> 'BoundingBoxProcessor':
|
|
55
|
+
"""
|
|
56
|
+
Create processor with specific model configuration
|
|
57
|
+
Args:
|
|
58
|
+
model_name: Name of the model
|
|
59
|
+
api_key: Optional API key
|
|
60
|
+
**kwargs: Additional configuration
|
|
61
|
+
Returns:
|
|
62
|
+
BoundingBoxProcessor: Configured processor
|
|
63
|
+
"""
|
|
64
|
+
config = BoundingBoxConfig(
|
|
65
|
+
model_name=model_name,
|
|
66
|
+
api_key=api_key
|
|
67
|
+
)
|
|
68
|
+
return cls(config, **kwargs)
|
|
69
|
+
|
|
70
|
+
def _initialize_model(self) -> None:
|
|
71
|
+
"""Initialize the AI model"""
|
|
72
|
+
import google.generativeai as genai
|
|
73
|
+
|
|
74
|
+
api_key = self.config.api_key or os.environ.get("GOOGLE_API_KEY")
|
|
75
|
+
if not api_key:
|
|
76
|
+
raise ValueError("Google API key not found. Please provide api_key parameter or set GOOGLE_API_KEY environment variable.")
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
genai.configure(api_key=api_key)
|
|
80
|
+
self.model = genai.GenerativeModel(model_name=self.config.model_name)
|
|
81
|
+
except Exception as e:
|
|
82
|
+
raise ValueError(f"Error initializing Google Generative AI model: {str(e)}")
|
|
83
|
+
|
|
84
|
+
def _initialize_image_libs(self) -> None:
|
|
85
|
+
"""Initialize image processing libraries"""
|
|
86
|
+
from PIL import Image
|
|
73
87
|
import cv2
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
88
|
+
self._Image = Image
|
|
89
|
+
self._cv2 = cv2
|
|
90
|
+
|
|
91
|
+
@staticmethod
|
|
92
|
+
def _validate_image_path(image_path: str) -> None:
|
|
93
|
+
"""
|
|
94
|
+
Validate image path
|
|
95
|
+
Args:
|
|
96
|
+
image_path: Path to image
|
|
97
|
+
Raises:
|
|
98
|
+
FileNotFoundError: If image doesn't exist
|
|
99
|
+
"""
|
|
100
|
+
if not os.path.exists(image_path):
|
|
101
|
+
raise FileNotFoundError(f"Image file not found: {image_path}")
|
|
102
|
+
|
|
103
|
+
def generate_bounding_boxes(self,
|
|
104
|
+
image_path: str,
|
|
105
|
+
prompt: Optional[str] = None) -> Any:
|
|
106
|
+
"""
|
|
107
|
+
Generate bounding boxes for an image
|
|
108
|
+
Args:
|
|
109
|
+
image_path: Path to image
|
|
110
|
+
prompt: Custom prompt for the model
|
|
111
|
+
Returns:
|
|
112
|
+
Any: Model response with bounding boxes
|
|
113
|
+
"""
|
|
114
|
+
self._validate_image_path(image_path)
|
|
77
115
|
|
|
116
|
+
try:
|
|
117
|
+
image = self._Image.open(image_path)
|
|
118
|
+
prompt = prompt or self.config.default_prompt
|
|
119
|
+
return self.model.generate_content([image, prompt])
|
|
120
|
+
except Exception as e:
|
|
121
|
+
raise ValueError(f"Error generating bounding boxes: {str(e)}")
|
|
78
122
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
123
|
+
def add_bounding_boxes(self,
|
|
124
|
+
image_path: str,
|
|
125
|
+
bounding_boxes: Dict[str, List[int]],
|
|
126
|
+
color: Tuple[int, int, int] = (0, 0, 255),
|
|
127
|
+
thickness: int = 4,
|
|
128
|
+
font_scale: float = 1.0,
|
|
129
|
+
show: bool = False) -> Any:
|
|
130
|
+
"""
|
|
131
|
+
Add bounding boxes to an image
|
|
132
|
+
Args:
|
|
133
|
+
image_path: Path to image
|
|
134
|
+
bounding_boxes: Dictionary of bounding boxes
|
|
135
|
+
color: BGR color tuple
|
|
136
|
+
thickness: Line thickness
|
|
137
|
+
font_scale: Font scale for labels
|
|
138
|
+
show: Whether to display the image
|
|
139
|
+
Returns:
|
|
140
|
+
Any: Image with bounding boxes
|
|
141
|
+
"""
|
|
142
|
+
self._validate_image_path(image_path)
|
|
143
|
+
|
|
144
|
+
if not isinstance(bounding_boxes, dict):
|
|
145
|
+
raise ValueError("bounding_boxes must be a dictionary")
|
|
146
|
+
|
|
147
|
+
try:
|
|
148
|
+
img = self._cv2.imread(image_path)
|
|
149
|
+
if img is None:
|
|
150
|
+
raise ValueError(f"Failed to load image: {image_path}")
|
|
151
|
+
|
|
152
|
+
for key, value in bounding_boxes.items():
|
|
83
153
|
if not isinstance(value, list) or len(value) != 4:
|
|
84
154
|
raise ValueError(f"Invalid bounding box format for key {key}. Expected [ymin, xmin, ymax, xmax]")
|
|
155
|
+
|
|
156
|
+
self._cv2.rectangle(
|
|
157
|
+
img=img,
|
|
158
|
+
pt1=(value[1], value[0]), # xmin, ymin
|
|
159
|
+
pt2=(value[3], value[2]), # xmax, ymax
|
|
160
|
+
color=color,
|
|
161
|
+
thickness=thickness
|
|
162
|
+
)
|
|
163
|
+
self._cv2.putText(
|
|
164
|
+
img=img,
|
|
165
|
+
text=key,
|
|
166
|
+
org=(value[1], value[0]),
|
|
167
|
+
fontFace=self._cv2.FONT_HERSHEY_SIMPLEX,
|
|
168
|
+
fontScale=font_scale,
|
|
169
|
+
color=color,
|
|
170
|
+
thickness=thickness//2
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
if show:
|
|
174
|
+
self._display_image(img)
|
|
85
175
|
|
|
86
|
-
|
|
87
|
-
|
|
176
|
+
return img
|
|
177
|
+
except Exception as e:
|
|
178
|
+
raise ValueError(f"Error adding bounding boxes to image: {str(e)}")
|
|
179
|
+
|
|
180
|
+
def _display_image(self, img: Any) -> None:
|
|
181
|
+
"""
|
|
182
|
+
Display an image
|
|
183
|
+
Args:
|
|
184
|
+
img: Image to display
|
|
185
|
+
"""
|
|
186
|
+
self._cv2.imshow("Image", img)
|
|
187
|
+
self._cv2.waitKey(0)
|
|
188
|
+
self._cv2.destroyAllWindows()
|
|
189
|
+
|
|
190
|
+
def save_image(self, img: Any, output_path: str) -> None:
|
|
191
|
+
"""
|
|
192
|
+
Save an image
|
|
193
|
+
Args:
|
|
194
|
+
img: Image to save
|
|
195
|
+
output_path: Path to save the image
|
|
196
|
+
"""
|
|
197
|
+
try:
|
|
198
|
+
self._cv2.imwrite(output_path, img)
|
|
199
|
+
except Exception as e:
|
|
200
|
+
raise ValueError(f"Error saving image: {str(e)}")
|
|
201
|
+
|
|
202
|
+
def process_image(self,
|
|
203
|
+
image_path: str,
|
|
204
|
+
output_path: Optional[str] = None,
|
|
205
|
+
show: bool = False,
|
|
206
|
+
**kwargs) -> Any:
|
|
207
|
+
"""
|
|
208
|
+
Complete image processing pipeline
|
|
209
|
+
Args:
|
|
210
|
+
image_path: Path to input image
|
|
211
|
+
output_path: Optional path to save output
|
|
212
|
+
show: Whether to display the result
|
|
213
|
+
**kwargs: Additional arguments for bounding box generation
|
|
214
|
+
Returns:
|
|
215
|
+
Any: Processed image
|
|
216
|
+
"""
|
|
217
|
+
boxes = self.generate_bounding_boxes(image_path, **kwargs)
|
|
218
|
+
img = self.add_bounding_boxes(image_path, boxes, show=show)
|
|
88
219
|
|
|
89
|
-
if
|
|
90
|
-
|
|
91
|
-
cv2.waitKey(0)
|
|
92
|
-
cv2.destroyAllWindows()
|
|
220
|
+
if output_path:
|
|
221
|
+
self.save_image(img, output_path)
|
|
93
222
|
|
|
94
223
|
return img
|
|
95
|
-
except Exception as e:
|
|
96
|
-
raise ValueError(f"Error adding bounding box to image: {str(e)}")
|
mb_rag/utils/extra.py
CHANGED
mb_rag/version.py
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
mb_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
mb_rag/version.py,sha256=g3pkzzTRM6lWK4_vY_dwd2hYFDmXrp2VRW8Uj2krk4k,208
|
|
3
|
+
mb_rag/chatbot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
mb_rag/chatbot/basic.py,sha256=OR2IvDg-Sy968C2Mna6lxmFfh7Czj8yCEkCfyvtxBwI,14223
|
|
5
|
+
mb_rag/chatbot/chains.py,sha256=vDbLX5R29sWN1pcFqJ5fyxJEgMCM81JAikunAEvMC9A,7223
|
|
6
|
+
mb_rag/chatbot/prompts.py,sha256=n1PyiLbU-5fkslRv6aVOzt0dDlwya_cEdQ7kRnRhMuY,1749
|
|
7
|
+
mb_rag/rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
mb_rag/rag/embeddings.py,sha256=kOnHjrbi0GRVErfcjML8fZz-KttipObUfa5fW9tGOoY,21196
|
|
9
|
+
mb_rag/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
mb_rag/utils/bounding_box.py,sha256=XnuhnLrsGvsI8P8VtOwlBrDlFE2It1HEZOcLlK6kusE,7931
|
|
11
|
+
mb_rag/utils/extra.py,sha256=spbFrGgdruNyYQ5PzgvpSIa6Nm0rn9bb4qc8W9g582o,2492
|
|
12
|
+
mb_rag-1.0.124.dist-info/METADATA,sha256=XyQ055JYBEiv5OU8m9FBhcOnHCoipo69LbnMgSa4bmM,154
|
|
13
|
+
mb_rag-1.0.124.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
14
|
+
mb_rag-1.0.124.dist-info/top_level.txt,sha256=FIK1eAa5uYnurgXZquBG-s3PIy-HDTC5yJBW4lTH_pM,7
|
|
15
|
+
mb_rag-1.0.124.dist-info/RECORD,,
|
mb_rag-1.0.117.dist-info/RECORD
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
mb_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
mb_rag/version.py,sha256=gwipOtP0TZlqdg5Rg1j43hyxg2GzlRZ0U9N3VPUDxNE,208
|
|
3
|
-
mb_rag/chatbot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
mb_rag/chatbot/basic.py,sha256=AEcgMrXcH-QsCdoykqqgRJsS2-ZOEmxJuj2nd5KgcgI,13804
|
|
5
|
-
mb_rag/chatbot/chains.py,sha256=KwdvAgI3DosSLgXGsm6fxeOKPYSbwy1mHH4ZIlOfTZY,8355
|
|
6
|
-
mb_rag/chatbot/prompts.py,sha256=n1PyiLbU-5fkslRv6aVOzt0dDlwya_cEdQ7kRnRhMuY,1749
|
|
7
|
-
mb_rag/rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
mb_rag/rag/embeddings.py,sha256=kOnHjrbi0GRVErfcjML8fZz-KttipObUfa5fW9tGOoY,21196
|
|
9
|
-
mb_rag/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
mb_rag/utils/bounding_box.py,sha256=PLfP_wSFkfNRu1uOu-1YIAQh93cuUHIkpFj77M4GaNk,3676
|
|
11
|
-
mb_rag/utils/extra.py,sha256=qgaFsybeonT6XAFNfAU5h24FimDb-beGZ1qTztTFhSk,2434
|
|
12
|
-
mb_rag-1.0.117.dist-info/METADATA,sha256=YH6LUu87Vn06x6NLD8FNS1YnaOuqx8Tq1vpTb8_81W0,154
|
|
13
|
-
mb_rag-1.0.117.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
14
|
-
mb_rag-1.0.117.dist-info/top_level.txt,sha256=FIK1eAa5uYnurgXZquBG-s3PIy-HDTC5yJBW4lTH_pM,7
|
|
15
|
-
mb_rag-1.0.117.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|