CaffeinatedCoding commited on
Commit
cbfd492
Β·
verified Β·
1 Parent(s): 2ac1b86

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. src/orchestrator.py +2 -1
  2. src/patchcore.py +7 -8
  3. src/retriever.py +6 -1
src/orchestrator.py CHANGED
@@ -206,7 +206,8 @@ def run_inspection(pil_img: Image.Image,
206
 
207
  # ── STEP 7: Index 2 retrieval ─────────────────────────────
208
  similar_cases = retriever.retrieve_similar_defects(
209
- clip_crop, k=5, exclude_hash=image_hash
 
210
  )
211
 
212
  # ── STEP 8: Knowledge graph traversal ────────────────────
 
206
 
207
  # ── STEP 7: Index 2 retrieval ─────────────────────────────
208
  similar_cases = retriever.retrieve_similar_defects(
209
+ clip_crop, k=5, exclude_hash=image_hash,
210
+ category_filter=category
211
  )
212
 
213
  # ── STEP 8: Knowledge graph traversal ────────────────────
src/patchcore.py CHANGED
@@ -160,17 +160,16 @@ class PatchCoreExtractor:
160
 
161
  def get_anomaly_centroid(self, heatmap: np.ndarray) -> tuple:
162
  """
163
- Find centroid of highest-activation region.
164
  Used to locate defect crop for Index 2 retrieval.
165
- Returns: (cx, cy) pixel coordinates
166
  """
167
- threshold = np.percentile(heatmap, 90)
168
- mask = heatmap > threshold
169
- if mask.sum() == 0:
170
  return (112, 112) # centre fallback
171
-
172
- ys, xs = np.where(mask)
173
- return (int(xs.mean()), int(ys.mean()))
 
174
 
175
  def calibrate_score(self,
176
  raw_score: float,
 
160
 
161
  def get_anomaly_centroid(self, heatmap: np.ndarray) -> tuple:
162
  """
163
+ Find the peak (highest activation) location of the anomaly.
164
  Used to locate defect crop for Index 2 retrieval.
165
+ Returns: (cx, cy) pixel coordinates of maximum activation
166
  """
167
+ if heatmap.size == 0:
 
 
168
  return (112, 112) # centre fallback
169
+
170
+ # Use peak location, not mean of thresholded region
171
+ max_idx = np.unravel_index(np.argmax(heatmap), heatmap.shape)
172
+ return (int(max_idx[1]), int(max_idx[0])) # cx, cy
173
 
174
  def calibrate_score(self,
175
  raw_score: float,
src/retriever.py CHANGED
@@ -99,11 +99,13 @@ class FAISSRetriever:
99
  def retrieve_similar_defects(self,
100
  clip_crop_embedding: np.ndarray,
101
  k: int = 5,
102
- exclude_hash: str = None) -> list:
 
103
  """
104
  Given a defect-crop CLIP embedding, return k most similar
105
  historical defect cases.
106
  exclude_hash: skip self-match (same image submitted again)
 
107
  Returns: list of metadata dicts with similarity scores
108
  """
109
  query = clip_crop_embedding.reshape(1, -1).astype(np.float32)
@@ -118,6 +120,9 @@ class FAISSRetriever:
118
  continue
119
  meta = self.index2_metadata[idx].copy()
120
  meta["similarity_score"] = float(dist)
 
 
 
121
  # Skip self-match
122
  if exclude_hash and meta.get("image_hash") == exclude_hash:
123
  continue
 
99
  def retrieve_similar_defects(self,
100
  clip_crop_embedding: np.ndarray,
101
  k: int = 5,
102
+ exclude_hash: str = None,
103
+ category_filter: str = None) -> list:
104
  """
105
  Given a defect-crop CLIP embedding, return k most similar
106
  historical defect cases.
107
  exclude_hash: skip self-match (same image submitted again)
108
+ category_filter: only return cases from specified category
109
  Returns: list of metadata dicts with similarity scores
110
  """
111
  query = clip_crop_embedding.reshape(1, -1).astype(np.float32)
 
120
  continue
121
  meta = self.index2_metadata[idx].copy()
122
  meta["similarity_score"] = float(dist)
123
+ # Filter by category if provided
124
+ if category_filter and meta.get("category") != category_filter:
125
+ continue
126
  # Skip self-match
127
  if exclude_hash and meta.get("image_hash") == exclude_hash:
128
  continue