ZENLLC commited on
Commit
fc232c8
·
verified ·
1 Parent(s): 72d2178

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +55 -21
app.py CHANGED
@@ -5,24 +5,45 @@ import gradio as gr
5
 
6
  def classify_pipe_material(image_np):
7
  """
8
- Heuristic to classify the overall pipe material based on the image's brightness.
9
- Assumes that plastic pipes tend to be brighter and metal pipes darker.
10
  """
11
  gray = cv2.cvtColor(image_np, cv2.COLOR_RGB2GRAY)
12
  mean_intensity = np.mean(gray)
13
- # If the mean intensity is high, assume plastic; otherwise, metal.
14
  return "Plastic" if mean_intensity > 130 else "Metal"
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  def classify_defect(roi):
17
  """
18
- Heuristic to classify the defect type within a region of interest (ROI).
19
- This simple method uses the area and intensity variation (std deviation)
20
- to differentiate between a crack (typically long and thin with high contrast)
21
- and corrosion (possibly larger, more blob-like with different texture).
 
 
22
  """
23
  area = roi.shape[0] * roi.shape[1]
24
  std_intensity = np.std(roi)
25
- # Adjust thresholds based on real-world testing.
 
 
 
 
 
 
26
  if area < 5000 and std_intensity > 50:
27
  return "Crack"
28
  elif area >= 5000 and std_intensity > 40:
@@ -32,15 +53,15 @@ def classify_defect(roi):
32
 
33
  def detect_pipe_issues(image: Image.Image):
34
  try:
35
- # Convert the PIL image to a NumPy array (RGB)
36
  image_np = np.array(image)
37
  annotated = image.copy() # Copy for annotation
38
  draw = ImageDraw.Draw(annotated)
39
 
40
- # Classify the overall pipe material
41
  pipe_material = classify_pipe_material(image_np)
42
 
43
- # Convert to grayscale and enhance contrast using CLAHE
44
  gray = cv2.cvtColor(image_np, cv2.COLOR_RGB2GRAY)
45
  clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
46
  enhanced = clahe.apply(gray)
@@ -56,32 +77,44 @@ def detect_pipe_issues(image: Image.Image):
56
  11, 2
57
  )
58
 
59
- # Use morphological closing to connect fragmented areas
60
  kernel = np.ones((3, 3), np.uint8)
61
  morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)
62
 
63
- # Detect edges with Canny
64
  edges = cv2.Canny(morph, 50, 150)
65
 
66
- # Find contours that might correspond to defects
67
  contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
68
  detections = []
69
 
 
 
 
 
 
 
 
 
70
  for cnt in contours:
71
  # Filter out small contours to ignore noise
72
  if cv2.contourArea(cnt) < 100:
73
  continue
74
  x, y, w, h = cv2.boundingRect(cnt)
75
- roi = enhanced[y:y+h, x:x+w]
 
 
 
76
  defect_type = classify_defect(roi)
77
  detection_info = f"{defect_type} at ({x}, {y}, {w}, {h})"
78
  detections.append(detection_info)
79
 
80
- # Draw bounding box and defect label
81
- draw.rectangle([x, y, x+w, y+h], outline="red", width=2)
82
- draw.text((x, y-10), defect_type, fill="red")
 
83
 
84
- # Prepare a textual summary including pipe material and all defect detections
85
  if detections:
86
  summary = f"Pipe Material: {pipe_material}\nDetected Issues:\n" + "\n".join(detections)
87
  else:
@@ -98,8 +131,9 @@ iface = gr.Interface(
98
  outputs=[gr.Image(label="Annotated Image"), gr.Textbox(label="Detection Summary")],
99
  title="Pipe Defect Detector",
100
  description=(
101
- "Upload an image of a pipe to detect granular issues such as cracks or corrosion. "
102
- "The app classifies the defect type and determines if the pipe material is plastic or metal."
 
103
  )
104
  )
105
 
 
5
 
6
  def classify_pipe_material(image_np):
7
  """
8
+ Heuristic to classify the overall pipe material based on brightness.
9
+ Brighter images (mean intensity > 130) are assumed to be Plastic; otherwise, Metal.
10
  """
11
  gray = cv2.cvtColor(image_np, cv2.COLOR_RGB2GRAY)
12
  mean_intensity = np.mean(gray)
 
13
  return "Plastic" if mean_intensity > 130 else "Metal"
14
 
15
+ def detect_rust(roi):
16
+ """
17
+ Detect rust in the region of interest (ROI) by analyzing the HSV color space.
18
+ Rust typically has reddish-brown hues.
19
+ """
20
+ # Convert ROI to HSV color space
21
+ hsv_roi = cv2.cvtColor(roi, cv2.COLOR_RGB2HSV)
22
+ # Define rust color range in HSV (tweak these values as needed)
23
+ lower_rust = np.array([5, 50, 50])
24
+ upper_rust = np.array([25, 255, 255])
25
+ mask = cv2.inRange(hsv_roi, lower_rust, upper_rust)
26
+ rust_ratio = np.count_nonzero(mask) / float(roi.shape[0] * roi.shape[1])
27
+ return rust_ratio
28
+
29
  def classify_defect(roi):
30
  """
31
+ Classify the defect type using both geometric/texture heuristics and color analysis.
32
+ The function returns one of:
33
+ - "Rust" (if a significant fraction of the region has rust-like colors)
34
+ - "Crack" (if the ROI is small, long, and has high intensity variation)
35
+ - "Corrosion" (if the ROI is larger with moderate texture variation)
36
+ - "Other Defect" (fallback category)
37
  """
38
  area = roi.shape[0] * roi.shape[1]
39
  std_intensity = np.std(roi)
40
+
41
+ # Check for rust first
42
+ rust_ratio = detect_rust(roi)
43
+ if rust_ratio > 0.3:
44
+ return "Rust"
45
+
46
+ # Use area and intensity variation to distinguish other defects.
47
  if area < 5000 and std_intensity > 50:
48
  return "Crack"
49
  elif area >= 5000 and std_intensity > 40:
 
53
 
54
  def detect_pipe_issues(image: Image.Image):
55
  try:
56
+ # Convert PIL image to a NumPy array (RGB)
57
  image_np = np.array(image)
58
  annotated = image.copy() # Copy for annotation
59
  draw = ImageDraw.Draw(annotated)
60
 
61
+ # Classify overall pipe material
62
  pipe_material = classify_pipe_material(image_np)
63
 
64
+ # Preprocessing: convert to grayscale and enhance contrast with CLAHE
65
  gray = cv2.cvtColor(image_np, cv2.COLOR_RGB2GRAY)
66
  clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
67
  enhanced = clahe.apply(gray)
 
77
  11, 2
78
  )
79
 
80
+ # Morphological closing to connect fragmented regions
81
  kernel = np.ones((3, 3), np.uint8)
82
  morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)
83
 
84
+ # Edge detection
85
  edges = cv2.Canny(morph, 50, 150)
86
 
87
+ # Find contours corresponding to potential defects
88
  contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
89
  detections = []
90
 
91
+ # Define colors for different defect types
92
+ colors = {
93
+ "Rust": "orange",
94
+ "Crack": "red",
95
+ "Corrosion": "blue",
96
+ "Other Defect": "green"
97
+ }
98
+
99
  for cnt in contours:
100
  # Filter out small contours to ignore noise
101
  if cv2.contourArea(cnt) < 100:
102
  continue
103
  x, y, w, h = cv2.boundingRect(cnt)
104
+ # Extract ROI from the original image
105
+ roi = image_np[y:y+h, x:x+w]
106
+ if roi.size == 0:
107
+ continue
108
  defect_type = classify_defect(roi)
109
  detection_info = f"{defect_type} at ({x}, {y}, {w}, {h})"
110
  detections.append(detection_info)
111
 
112
+ # Draw bounding box with corresponding color and label
113
+ box_color = colors.get(defect_type, "green")
114
+ draw.rectangle([x, y, x+w, y+h], outline=box_color, width=2)
115
+ draw.text((x, y-10), defect_type, fill=box_color)
116
 
117
+ # Create a summary including pipe material and detected defects
118
  if detections:
119
  summary = f"Pipe Material: {pipe_material}\nDetected Issues:\n" + "\n".join(detections)
120
  else:
 
131
  outputs=[gr.Image(label="Annotated Image"), gr.Textbox(label="Detection Summary")],
132
  title="Pipe Defect Detector",
133
  description=(
134
+ "Upload an image of a pipe to detect granular issues such as cracks, corrosion, rust, "
135
+ "and other defects. The app classifies the defect type and displays a colored bounding box for each class. "
136
+ "Pipe material (Plastic or Metal) is also identified."
137
  )
138
  )
139