minh9972t12 commited on
Commit
ceb9e66
Β·
1 Parent(s): 84b458c

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +64 -44
main.py CHANGED
@@ -16,7 +16,6 @@ from src.detection import YOLOv11Detector
16
  from src.comparison import DamageComparator
17
  from src.visualization import DamageVisualizer
18
 
19
-
20
  app = FastAPI(
21
  title="Car Damage Detection API",
22
  description="YOLOv11-based car damage detection and comparison system",
@@ -38,12 +37,15 @@ comparator = DamageComparator()
38
  visualizer = DamageVisualizer()
39
 
40
  # Create necessary directories
41
- Path("uploads").mkdir(exist_ok=True)
42
- Path("results").mkdir(exist_ok=True)
 
 
43
 
44
  # Mount static files directory
45
  app.mount("/uploads", StaticFiles(directory="uploads"), name="uploads")
46
 
 
47
  @app.get("/")
48
  async def root():
49
  """Root endpoint"""
@@ -59,23 +61,12 @@ async def root():
59
  }
60
 
61
 
62
- def save_temp_file(upload_file: UploadFile) -> str:
63
- """Save an uploaded file into /tmp and return the temp file path"""
64
- tmp_dir = Path("/tmp")
65
- tmp_dir.mkdir(exist_ok=True)
66
-
67
- temp_path = tmp_dir / upload_file.filename
68
-
69
- with open(temp_path, "wb") as buffer:
70
- shutil.copyfileobj(upload_file.file, buffer)
71
- return str(temp_path)
72
-
73
-
74
  @app.get("/health")
75
  async def health_check():
76
  """Health check endpoint"""
77
  return {"status": "healthy", "model": "YOLOv11"}
78
 
 
79
  @app.post("/detect")
80
  async def detect_single_image(file: UploadFile = File(...)):
81
  """
@@ -100,11 +91,18 @@ async def detect_single_image(file: UploadFile = File(...)):
100
  # Create visualization
101
  visualized = visualizer.draw_detections(image_bgr, detections, 'new_damage')
102
 
103
-
104
  filename = f"detection_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{uuid.uuid4().hex[:8]}.jpg"
105
- output_path = Path("/tmp") / filename
 
 
 
 
106
  cv2.imwrite(str(output_path), visualized)
107
 
 
 
 
108
  return JSONResponse({
109
  "status": "success",
110
  "detections": detections,
@@ -112,28 +110,32 @@ async def detect_single_image(file: UploadFile = File(...)):
112
  "total_damages": len(detections['boxes']),
113
  "damage_types": list(set(detections['classes']))
114
  },
115
- "visualized_image_path": f"/tmp/{filename}",
 
 
 
116
  })
117
 
118
  except Exception as e:
119
  raise HTTPException(status_code=500, detail=f"Detection failed: {str(e)}")
120
 
 
121
  @app.post("/compare")
122
  async def compare_vehicle_damages(
123
- # Before delivery images (6 positions)
124
- before_1: UploadFile = File(..., description="Before - Position 1"),
125
- before_2: UploadFile = File(..., description="Before - Position 2"),
126
- before_3: UploadFile = File(..., description="Before - Position 3"),
127
- before_4: UploadFile = File(..., description="Before - Position 4"),
128
- before_5: UploadFile = File(..., description="Before - Position 5"),
129
- before_6: UploadFile = File(..., description="Before - Position 6"),
130
- # After delivery images (6 positions)
131
- after_1: UploadFile = File(..., description="After - Position 1"),
132
- after_2: UploadFile = File(..., description="After - Position 2"),
133
- after_3: UploadFile = File(..., description="After - Position 3"),
134
- after_4: UploadFile = File(..., description="After - Position 4"),
135
- after_5: UploadFile = File(..., description="After - Position 5"),
136
- after_6: UploadFile = File(..., description="After - Position 6"),
137
  ):
138
  """
139
  Compare vehicle damages before and after delivery
@@ -201,25 +203,34 @@ async def compare_vehicle_damages(
201
  comparison
202
  )
203
 
204
- # Save visualization image with unique filename
205
- vis_filename = f"comparison_{timestamp_str}_{session_id}_pos{i+1}.jpg"
206
- vis_path = Path("/tmp") / vis_filename
207
- cv2.imwrite(str(vis_path), vis_img)
208
 
 
 
 
 
 
 
 
 
209
  vis_url = f"http://localhost:8000/uploads/{vis_filename}"
210
  all_visualizations.append(vis_url)
211
 
212
  # Store position result
213
  position_results.append({
214
- f"position_{i+1}": {
215
  "case": comparison['case'],
216
  "message": comparison['message'],
217
  "statistics": comparison['statistics'],
218
  "new_damages": comparison['new_damages'],
219
  "matched_damages": comparison['matched_damages'],
220
  "repaired_damages": comparison['repaired_damages'],
221
- "visualization_path": f"/tmp/{vis_filename}",
222
- "visualization_url": vis_url
 
 
223
  }
224
  })
225
 
@@ -235,13 +246,20 @@ async def compare_vehicle_damages(
235
  overall_message = "Error from the beginning, not during the delivery process -> Delivery completed"
236
 
237
  # Create summary grid visualization
238
- grid_results = [res[f"position_{i+1}"] for i, res in enumerate(position_results)]
239
  grid_img = visualizer.create_summary_grid(grid_results, image_pairs)
240
 
241
- # Save grid summary image
242
  grid_filename = f"summary_grid_{timestamp_str}_{session_id}.jpg"
243
- grid_path = Path("uploads") / grid_filename
244
- cv2.imwrite(str(grid_path), grid_img)
 
 
 
 
 
 
 
245
  grid_url = f"http://localhost:8000/uploads/{grid_filename}"
246
 
247
  # Generate timestamp for tracking
@@ -261,8 +279,10 @@ async def compare_vehicle_damages(
261
  }
262
  },
263
  "position_results": position_results,
264
- "summary_visualization_path": f"/uploads/{grid_filename}",
 
265
  "summary_visualization_url": grid_url,
 
266
  "recommendations": {
267
  "action_required": total_new_damages > 0,
268
  "suggested_action": "Investigate delivery process" if total_new_damages > 0 else "Proceed with delivery completion"
 
16
  from src.comparison import DamageComparator
17
  from src.visualization import DamageVisualizer
18
 
 
19
  app = FastAPI(
20
  title="Car Damage Detection API",
21
  description="YOLOv11-based car damage detection and comparison system",
 
37
  visualizer = DamageVisualizer()
38
 
39
  # Create necessary directories
40
+ UPLOADS_DIR = Path("uploads")
41
+ RESULTS_DIR = Path("results")
42
+ UPLOADS_DIR.mkdir(exist_ok=True)
43
+ RESULTS_DIR.mkdir(exist_ok=True)
44
 
45
  # Mount static files directory
46
  app.mount("/uploads", StaticFiles(directory="uploads"), name="uploads")
47
 
48
+
49
  @app.get("/")
50
  async def root():
51
  """Root endpoint"""
 
61
  }
62
 
63
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  @app.get("/health")
65
  async def health_check():
66
  """Health check endpoint"""
67
  return {"status": "healthy", "model": "YOLOv11"}
68
 
69
+
70
  @app.post("/detect")
71
  async def detect_single_image(file: UploadFile = File(...)):
72
  """
 
91
  # Create visualization
92
  visualized = visualizer.draw_detections(image_bgr, detections, 'new_damage')
93
 
94
+ # Generate unique filename
95
  filename = f"detection_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{uuid.uuid4().hex[:8]}.jpg"
96
+
97
+ # βœ… FIX: Use consistent relative path
98
+ output_path = UPLOADS_DIR / filename
99
+
100
+ # Save visualization image
101
  cv2.imwrite(str(output_path), visualized)
102
 
103
+ # Generate URL for accessing the image
104
+ image_url = f"http://localhost:8000/uploads/{filename}"
105
+
106
  return JSONResponse({
107
  "status": "success",
108
  "detections": detections,
 
110
  "total_damages": len(detections['boxes']),
111
  "damage_types": list(set(detections['classes']))
112
  },
113
+ # βœ… FIX: Correct paths
114
+ "visualized_image_path": f"uploads/{filename}",
115
+ "visualized_image_url": image_url,
116
+ "filename": filename
117
  })
118
 
119
  except Exception as e:
120
  raise HTTPException(status_code=500, detail=f"Detection failed: {str(e)}")
121
 
122
+
123
  @app.post("/compare")
124
  async def compare_vehicle_damages(
125
+ # Before delivery images (6 positions)
126
+ before_1: UploadFile = File(..., description="Before - Position 1"),
127
+ before_2: UploadFile = File(..., description="Before - Position 2"),
128
+ before_3: UploadFile = File(..., description="Before - Position 3"),
129
+ before_4: UploadFile = File(..., description="Before - Position 4"),
130
+ before_5: UploadFile = File(..., description="Before - Position 5"),
131
+ before_6: UploadFile = File(..., description="Before - Position 6"),
132
+ # After delivery images (6 positions)
133
+ after_1: UploadFile = File(..., description="After - Position 1"),
134
+ after_2: UploadFile = File(..., description="After - Position 2"),
135
+ after_3: UploadFile = File(..., description="After - Position 3"),
136
+ after_4: UploadFile = File(..., description="After - Position 4"),
137
+ after_5: UploadFile = File(..., description="After - Position 5"),
138
+ after_6: UploadFile = File(..., description="After - Position 6"),
139
  ):
140
  """
141
  Compare vehicle damages before and after delivery
 
203
  comparison
204
  )
205
 
206
+ # βœ… FIX: Save visualization image with consistent path
207
+ vis_filename = f"comparison_{timestamp_str}_{session_id}_pos{i + 1}.jpg"
208
+ vis_path = UPLOADS_DIR / vis_filename # Use consistent relative path
 
209
 
210
+ # Save the image
211
+ success = cv2.imwrite(str(vis_path), vis_img)
212
+ if not success:
213
+ print(f"⚠️ Warning: Failed to save visualization for position {i + 1}")
214
+ else:
215
+ print(f"βœ… Saved: {vis_path}")
216
+
217
+ # Generate URL for accessing the image
218
  vis_url = f"http://localhost:8000/uploads/{vis_filename}"
219
  all_visualizations.append(vis_url)
220
 
221
  # Store position result
222
  position_results.append({
223
+ f"position_{i + 1}": {
224
  "case": comparison['case'],
225
  "message": comparison['message'],
226
  "statistics": comparison['statistics'],
227
  "new_damages": comparison['new_damages'],
228
  "matched_damages": comparison['matched_damages'],
229
  "repaired_damages": comparison['repaired_damages'],
230
+ # βœ… FIX: Correct paths
231
+ "visualization_path": f"uploads/{vis_filename}",
232
+ "visualization_url": vis_url,
233
+ "filename": vis_filename
234
  }
235
  })
236
 
 
246
  overall_message = "Error from the beginning, not during the delivery process -> Delivery completed"
247
 
248
  # Create summary grid visualization
249
+ grid_results = [res[f"position_{i + 1}"] for i, res in enumerate(position_results)]
250
  grid_img = visualizer.create_summary_grid(grid_results, image_pairs)
251
 
252
+ # βœ… FIX: Save grid summary image with consistent path
253
  grid_filename = f"summary_grid_{timestamp_str}_{session_id}.jpg"
254
+ grid_path = UPLOADS_DIR / grid_filename # Already correct in original
255
+
256
+ # Save the grid image
257
+ grid_success = cv2.imwrite(str(grid_path), grid_img)
258
+ if not grid_success:
259
+ print(f"⚠️ Warning: Failed to save grid summary")
260
+ else:
261
+ print(f"βœ… Saved grid: {grid_path}")
262
+
263
  grid_url = f"http://localhost:8000/uploads/{grid_filename}"
264
 
265
  # Generate timestamp for tracking
 
279
  }
280
  },
281
  "position_results": position_results,
282
+ # βœ… FIX: Correct paths
283
+ "summary_visualization_path": f"uploads/{grid_filename}",
284
  "summary_visualization_url": grid_url,
285
+ "all_visualizations": all_visualizations, # Added for convenience
286
  "recommendations": {
287
  "action_required": total_new_damages > 0,
288
  "suggested_action": "Investigate delivery process" if total_new_damages > 0 else "Proceed with delivery completion"