mrprimenotes commited on
Commit
6c49c31
·
verified ·
1 Parent(s): d85e310

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -28
app.py CHANGED
@@ -6,6 +6,12 @@ from pathlib import Path
6
  from PIL import Image
7
  from io import BytesIO
8
  import tempfile
 
 
 
 
 
 
9
 
10
  # Define categories and their limits
11
  CATEGORY_LIMITS = {
@@ -15,33 +21,48 @@ CATEGORY_LIMITS = {
15
  CATEGORIES = list(CATEGORY_LIMITS.keys())
16
  MAX_SIZE = [1024, 1024] # Maximum width and height for resized images
17
 
18
- class AnnotationManager:
19
  def __init__(self):
20
- self.annotations = {}
21
- self.temp_dir = tempfile.mkdtemp() # Create temporary directory for resized images
22
-
 
 
 
 
 
 
 
 
23
  def resize_image(self, image_path):
24
- """Resize image to maximum dimensions while maintaining aspect ratio"""
25
  try:
26
- # Read and resize image
 
 
27
  with open(image_path, "rb") as f:
28
  img = Image.open(BytesIO(f.read()))
29
  img.thumbnail(MAX_SIZE, Image.Resampling.LANCZOS)
30
 
31
- # Save resized image to temporary file
32
- filename = os.path.basename(image_path)
33
- temp_path = os.path.join(self.temp_dir, f"resized_{filename}")
34
- img.save(temp_path)
 
 
 
 
 
 
35
 
36
- return temp_path
37
  except Exception as e:
38
- raise ValueError(f"Error processing image: {str(e)}")
39
-
40
- def process_image_upload(self, image_path):
41
- """Process uploaded image and return path to resized version"""
42
- if not image_path:
43
- return None
44
- return self.resize_image(image_path)
45
 
46
  def validate_annotations(self, bbox_data):
47
  """Validate the annotation data and return (is_valid, error_message)"""
@@ -81,6 +102,21 @@ class AnnotationManager:
81
 
82
  return True, ""
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  def add_annotation(self, bbox_data):
85
  """Add or update annotations for an image"""
86
  is_valid, error_msg = self.validate_annotations(bbox_data)
@@ -159,25 +195,38 @@ def create_interface():
159
  save_btn = gr.Button("Save Current Image Annotations", variant="primary")
160
  clear_btn = gr.Button("Clear All Annotations", variant="secondary")
161
 
162
- # Add status message
163
  status_msg = gr.Markdown(label="Status")
 
164
 
165
  # Event handlers
166
- def update_image(image_path):
167
- if not image_path or not isinstance(image_path, (str, Path)):
168
- return None
169
  try:
170
- resized_path = annotation_mgr.process_image_upload(image_path)
171
- return resized_path
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  except Exception as e:
173
- print(f"Error processing image: {e}")
174
- return image_path
 
175
 
176
  # Handle image upload and resizing
177
  bbox_input.upload(
178
- fn=update_image,
179
  inputs=[bbox_input],
180
- outputs=[bbox_input]
181
  )
182
 
183
  save_btn.click(
 
6
  from PIL import Image
7
  from io import BytesIO
8
  import tempfile
9
+ import shutil
10
+ import logging
11
+
12
+ # Set up logging
13
+ logging.basicConfig(level=logging.INFO)
14
+ logger = logging.getLogger(__name__)
15
 
16
  # Define categories and their limits
17
  CATEGORY_LIMITS = {
 
21
  CATEGORIES = list(CATEGORY_LIMITS.keys())
22
  MAX_SIZE = [1024, 1024] # Maximum width and height for resized images
23
 
24
+ class ImageProcessor:
25
  def __init__(self):
26
+ # Create a persistent directory for resized images
27
+ self.base_dir = os.path.join(tempfile.gettempdir(), "annotation_tool")
28
+ self.resized_dir = os.path.join(self.base_dir, "resized_images")
29
+ self._setup_directories()
30
+ logger.info(f"Initialized ImageProcessor with directory: {self.base_dir}")
31
+
32
+ def _setup_directories(self):
33
+ """Create necessary directories if they don't exist"""
34
+ os.makedirs(self.resized_dir, exist_ok=True)
35
+ logger.info(f"Set up directories: {self.resized_dir}")
36
+
37
  def resize_image(self, image_path):
38
+ """Resize image and save to persistent directory"""
39
  try:
40
+ logger.info(f"Processing image: {image_path}")
41
+
42
+ # Read original image
43
  with open(image_path, "rb") as f:
44
  img = Image.open(BytesIO(f.read()))
45
  img.thumbnail(MAX_SIZE, Image.Resampling.LANCZOS)
46
 
47
+ # Create a unique filename for the resized image
48
+ original_filename = os.path.basename(image_path)
49
+ resized_filename = f"resized_{original_filename}"
50
+ resized_path = os.path.join(self.resized_dir, resized_filename)
51
+
52
+ # Save resized image
53
+ img.save(resized_path)
54
+ logger.info(f"Saved resized image to: {resized_path}")
55
+
56
+ return resized_path
57
 
 
58
  except Exception as e:
59
+ logger.error(f"Error processing image: {str(e)}")
60
+ raise
61
+
62
+ class AnnotationManager:
63
+ def __init__(self):
64
+ self.annotations = {}
65
+ self.image_processor = ImageProcessor()
66
 
67
  def validate_annotations(self, bbox_data):
68
  """Validate the annotation data and return (is_valid, error_message)"""
 
102
 
103
  return True, ""
104
 
105
+ def process_upload(self, image_path):
106
+ """Process uploaded image"""
107
+ if not image_path:
108
+ logger.warning("No image path provided")
109
+ return None
110
+
111
+ try:
112
+ logger.info(f"Processing upload: {image_path}")
113
+ resized_path = self.image_processor.resize_image(image_path)
114
+ logger.info(f"Successfully processed upload: {resized_path}")
115
+ return resized_path
116
+ except Exception as e:
117
+ logger.error(f"Error in process_upload: {str(e)}")
118
+ return None
119
+
120
  def add_annotation(self, bbox_data):
121
  """Add or update annotations for an image"""
122
  is_valid, error_msg = self.validate_annotations(bbox_data)
 
195
  save_btn = gr.Button("Save Current Image Annotations", variant="primary")
196
  clear_btn = gr.Button("Clear All Annotations", variant="secondary")
197
 
198
+ # Add status message and debug output
199
  status_msg = gr.Markdown(label="Status")
200
+ debug_output = gr.Textbox(label="Debug Info", interactive=False)
201
 
202
  # Event handlers
203
+ def handle_image_upload(image_path):
 
 
204
  try:
205
+ if not image_path:
206
+ return None, "No image uploaded"
207
+
208
+ logger.info(f"Handling upload for: {image_path}")
209
+ resized_path = annotation_mgr.process_upload(image_path)
210
+
211
+ if resized_path and os.path.exists(resized_path):
212
+ debug_msg = f"Processed image path: {resized_path}"
213
+ logger.info(debug_msg)
214
+ return resized_path, debug_msg
215
+ else:
216
+ error_msg = "Failed to process image"
217
+ logger.error(error_msg)
218
+ return None, error_msg
219
+
220
  except Exception as e:
221
+ error_msg = f"Error in upload handler: {str(e)}"
222
+ logger.error(error_msg)
223
+ return None, error_msg
224
 
225
  # Handle image upload and resizing
226
  bbox_input.upload(
227
+ fn=handle_image_upload,
228
  inputs=[bbox_input],
229
+ outputs=[bbox_input, debug_output]
230
  )
231
 
232
  save_btn.click(