Sentoz commited on
Commit
1afce9a
·
verified ·
1 Parent(s): 97f491b

Deploy KidneyDL CT Scan Classifier

Browse files
src/cnnClassifier/pipeline/prediction.py CHANGED
@@ -3,9 +3,19 @@ from tensorflow.keras.models import load_model
3
  from tensorflow.keras.preprocessing import image
4
  import os
5
 
6
- # Minimum softmax confidence required to trust a prediction.
7
- # Below this threshold the image is likely not a kidney CT scan.
8
- CONFIDENCE_THRESHOLD = 0.80
 
 
 
 
 
 
 
 
 
 
9
 
10
 
11
  class PredictionPipeline:
@@ -24,15 +34,16 @@ class PredictionPipeline:
24
  model = load_model(model_path)
25
 
26
  img = image.load_img(self.filename, target_size=(224, 224))
27
- img_array = image.img_to_array(img)
28
- img_array = np.expand_dims(img_array, axis=0) / 255.0
29
 
30
- predictions = model.predict(img_array)
31
- confidence = float(np.max(predictions))
32
- class_idx = int(np.argmax(predictions, axis=1)[0])
33
 
34
- if confidence < CONFIDENCE_THRESHOLD:
35
- return [{"image": "InvalidImage", "confidence": round(confidence, 4)}]
 
 
36
 
37
  return [{"image": "Tumor" if class_idx == 1 else "Normal",
38
  "confidence": round(confidence, 4)}]
 
3
  from tensorflow.keras.preprocessing import image
4
  import os
5
 
6
+ # CT scans are grayscale all three RGB channels are nearly identical.
7
+ # This threshold is the max allowed std-dev of inter-channel pixel differences.
8
+ # True CT scans score ~0–8; colour photos score ~20–80+.
9
+ GRAYSCALE_THRESHOLD = 15.0
10
+
11
+
12
+ def _is_ct_like(img_array):
13
+ """Return True if the image looks like a grayscale CT scan."""
14
+ r = img_array[:, :, 0].astype(float)
15
+ g = img_array[:, :, 1].astype(float)
16
+ b = img_array[:, :, 2].astype(float)
17
+ max_channel_diff = max(np.std(r - g), np.std(r - b), np.std(g - b))
18
+ return max_channel_diff < GRAYSCALE_THRESHOLD
19
 
20
 
21
  class PredictionPipeline:
 
34
  model = load_model(model_path)
35
 
36
  img = image.load_img(self.filename, target_size=(224, 224))
37
+ img_array = image.img_to_array(img) # shape (224, 224, 3), values 0–255
 
38
 
39
+ # Reject non-CT images before they reach the model
40
+ if not _is_ct_like(img_array):
41
+ return [{"image": "InvalidImage"}]
42
 
43
+ img_input = np.expand_dims(img_array, axis=0) / 255.0
44
+ predictions = model.predict(img_input)
45
+ class_idx = int(np.argmax(predictions, axis=1)[0])
46
+ confidence = float(np.max(predictions))
47
 
48
  return [{"image": "Tumor" if class_idx == 1 else "Normal",
49
  "confidence": round(confidence, 4)}]