SaniaE commited on
Commit
122dbdd
·
verified ·
1 Parent(s): cd91996

added occlusion sensitivity endpoint

Browse files
Files changed (1) hide show
  1. app.py +70 -1
app.py CHANGED
@@ -66,4 +66,73 @@ async def predict(file: UploadFile = File(...)):
66
 
67
  # Return Stream
68
  _, buffer = cv2.imencode('.jpg', processed_img)
69
- return StreamingResponse(io.BytesIO(buffer), media_type="image/jpeg")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
  # Return Stream
68
  _, buffer = cv2.imencode('.jpg', processed_img)
69
+ return StreamingResponse(io.BytesIO(buffer), media_type="image/jpeg")
70
+
71
+
72
+ @app.post("/explain/occlusion")
73
+ async def explain_occlusion(file: UploadFile = File(...)):
74
+ # 1. Prepare Image
75
+ contents = await file.read()
76
+ image_pil = Image.open(io.BytesIO(contents)).convert("RGB")
77
+ image_np = np.array(image_pil)
78
+ h, w, _ = image_np.shape
79
+
80
+ # 2. Get Baseline Score
81
+ # We use the max score of the primary detection as our baseline
82
+ with graph.as_default():
83
+ baseline_results = model_eval.detect([image_np], verbose=0)[0]
84
+
85
+ if len(baseline_results['scores']) == 0:
86
+ return {"error": "No petrol station detected in the baseline image."}
87
+
88
+ baseline_score = baseline_results['scores'][0]
89
+
90
+ # 3. Occlusion Parameters
91
+ # Larger patches/strides prevent the API from hanging
92
+ patch_size = 64
93
+ stride = 32
94
+
95
+ # Initialize heatmap
96
+ sensitivity_map = np.zeros((h, w), dtype=np.float32)
97
+
98
+ # 4. Sliding Window Occlusion
99
+ # We mask out areas and see how much the confidence drops
100
+ with graph.as_default():
101
+ for y in range(0, h - patch_size, stride):
102
+ for x in range(0, w - patch_size, stride):
103
+ # Create occluded copy
104
+ img_occ = image_np.copy()
105
+ # Apply a "gray" occluder
106
+ img_occ[y:y+patch_size, x:x+patch_size, :] = 128
107
+
108
+ # Run inference
109
+ res = model_eval.detect([img_occ], verbose=0)[0]
110
+
111
+ # Calculate confidence drop
112
+ # If the target is lost or confidence drops, this area was important
113
+ current_score = res['scores'][0] if len(res['scores']) > 0 else 0
114
+ drop = max(0, baseline_score - current_score)
115
+
116
+ # Fill the patch area in our map
117
+ sensitivity_map[y:y+patch_size, x:x+patch_size] += drop
118
+
119
+ # 5. Normalize and Colorize
120
+ # Scale 0-1
121
+ if np.max(sensitivity_map) > 0:
122
+ sensitivity_map = (sensitivity_map - np.min(sensitivity_map)) / (np.max(sensitivity_map) - np.min(sensitivity_map) + 1e-8)
123
+
124
+ # Create JET Heatmap (Red = Highly sensitive/Important)
125
+ heatmap = cv2.applyColorMap(np.uint8(255 * sensitivity_map), cv2.COLORMAP_JET)
126
+
127
+ # 6. Final Overlay
128
+ # Convert original to BGR for OpenCV
129
+ original_bgr = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
130
+ overlay = cv2.addWeighted(original_bgr, 0.6, heatmap, 0.4, 0)
131
+
132
+ # Add Label with your signature Teal color
133
+ cv2.putText(overlay, "Occlusion Sensitivity Analysis", (20, 40),
134
+ cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 0), 2)
135
+
136
+ # 7. Stream result
137
+ _, buffer = cv2.imencode('.jpg', overlay)
138
+ return StreamingResponse(io.BytesIO(buffer.tobytes()), media_type="image/jpeg")