broadfield-dev commited on
Commit
0b2ce51
·
verified ·
1 Parent(s): d84d480

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -17
app.py CHANGED
@@ -20,31 +20,29 @@ def extract_frames(gif_path):
20
  except Exception as e:
21
  return None, f"Error loading GIF: {str(e)}"
22
 
23
- def preprocess_frame(frame):
24
  """Preprocess a frame: isolate mid-to-light pixels and enhance circular patterns."""
25
  # Apply Gaussian blur to reduce noise
26
  blurred = cv2.GaussianBlur(frame, (9, 9), 0)
27
 
28
- # Isolate mid-to-light pixels (intensity range 100–200 in grayscale)
29
- lower_bound = 150
30
- upper_bound = 255
31
  mask = cv2.inRange(blurred, lower_bound, upper_bound)
32
 
33
  # Apply morphological operation to enhance circular patterns
34
  kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
35
- enhanced = cv2.dilate(mask, kernel, iterations=2)
36
 
37
  return enhanced
38
 
39
- def detect_circles(frame_diff, image_center, min_radius=20, max_radius=200):
40
  """Detect circles in a frame difference image, centered at the Sun."""
41
  circles = cv2.HoughCircles(
42
  frame_diff,
43
  cv2.HOUGH_GRADIENT,
44
  dp=1.5, # Resolution for better detection
45
  minDist=100, # Prevent overlapping circles
46
- param1=80, # Lower edge threshold to capture fainter edges
47
- param2=15, # Lower accumulator threshold to detect faint circles
48
  minRadius=min_radius,
49
  maxRadius=max_radius
50
  )
@@ -53,7 +51,6 @@ def detect_circles(frame_diff, image_center, min_radius=20, max_radius=200):
53
  circles = np.round(circles[0, :]).astype("int")
54
  # Filter circles: only keep those centered near the image center
55
  filtered_circles = []
56
- center_tolerance = 30 # Allow 30-pixel deviation from the center
57
  for (x, y, r) in circles:
58
  if (abs(x - image_center[0]) < center_tolerance and
59
  abs(y - image_center[1]) < center_tolerance):
@@ -61,7 +58,7 @@ def detect_circles(frame_diff, image_center, min_radius=20, max_radius=200):
61
  return filtered_circles if filtered_circles else None
62
  return None
63
 
64
- def analyze_gif(gif_file):
65
  """Analyze a GIF for growing concentric circles of mid-to-light pixels."""
66
  try:
67
  # Handle Gradio file input
@@ -86,8 +83,8 @@ def analyze_gif(gif_file):
86
 
87
  # Process frames and detect circles
88
  for i in range(len(frames) - 1):
89
- frame1 = preprocess_frame(frames[i])
90
- frame2 = preprocess_frame(frames[i + 1])
91
 
92
  # Compute absolute difference between consecutive frames
93
  frame_diff = cv2.absdiff(frame2, frame1)
@@ -95,7 +92,7 @@ def analyze_gif(gif_file):
95
  frame_diff = cv2.convertScaleAbs(frame_diff, alpha=3.0, beta=0)
96
 
97
  # Detect circles centered at the Sun
98
- circles = detect_circles(frame_diff, image_center, min_radius, max_radius)
99
 
100
  if circles:
101
  # Take the largest circle (most prominent CME feature)
@@ -120,7 +117,7 @@ def analyze_gif(gif_file):
120
 
121
  # Generate output frames and report
122
  results = []
123
- report = "Analysis Report (as of 07:34 PM PDT, May 24, 2025):\n"
124
  if growing_circle_data:
125
  report += f"Detected {len(growing_circle_data)} frames with growing concentric circles of mid-to-light pixels:\n"
126
  for c in growing_circle_data:
@@ -140,16 +137,24 @@ def analyze_gif(gif_file):
140
  except Exception as e:
141
  return f"Error during analysis: {str(e)}", []
142
 
143
- # Gradio interface
144
  iface = gr.Interface(
145
  fn=analyze_gif,
146
- inputs=gr.File(label="Upload Solar GIF", file_types=[".gif"]),
 
 
 
 
 
 
 
 
147
  outputs=[
148
  gr.Textbox(label="Analysis Report"),
149
  gr.Gallery(label="Frames with Growing Circles")
150
  ],
151
  title="Solar CME Detection",
152
- description="Upload a GIF of solar images to detect growing concentric circles of mid-to-light pixels indicative of Earth-directed coronal mass ejections (CMEs)."
153
  )
154
 
155
  if __name__ == "__main__":
 
20
  except Exception as e:
21
  return None, f"Error loading GIF: {str(e)}"
22
 
23
+ def preprocess_frame(frame, lower_bound, upper_bound, morph_iterations):
24
  """Preprocess a frame: isolate mid-to-light pixels and enhance circular patterns."""
25
  # Apply Gaussian blur to reduce noise
26
  blurred = cv2.GaussianBlur(frame, (9, 9), 0)
27
 
28
+ # Isolate mid-to-light pixels using user-defined intensity range
 
 
29
  mask = cv2.inRange(blurred, lower_bound, upper_bound)
30
 
31
  # Apply morphological operation to enhance circular patterns
32
  kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
33
+ enhanced = cv2.dilate(mask, kernel, iterations=morph_iterations)
34
 
35
  return enhanced
36
 
37
+ def detect_circles(frame_diff, image_center, center_tolerance, param1, param2, min_radius=20, max_radius=200):
38
  """Detect circles in a frame difference image, centered at the Sun."""
39
  circles = cv2.HoughCircles(
40
  frame_diff,
41
  cv2.HOUGH_GRADIENT,
42
  dp=1.5, # Resolution for better detection
43
  minDist=100, # Prevent overlapping circles
44
+ param1=param1, # User-defined edge threshold
45
+ param2=param2, # User-defined accumulator threshold
46
  minRadius=min_radius,
47
  maxRadius=max_radius
48
  )
 
51
  circles = np.round(circles[0, :]).astype("int")
52
  # Filter circles: only keep those centered near the image center
53
  filtered_circles = []
 
54
  for (x, y, r) in circles:
55
  if (abs(x - image_center[0]) < center_tolerance and
56
  abs(y - image_center[1]) < center_tolerance):
 
58
  return filtered_circles if filtered_circles else None
59
  return None
60
 
61
+ def analyze_gif(gif_file, lower_bound, upper_bound, param1, param2, center_tolerance, morph_iterations):
62
  """Analyze a GIF for growing concentric circles of mid-to-light pixels."""
63
  try:
64
  # Handle Gradio file input
 
83
 
84
  # Process frames and detect circles
85
  for i in range(len(frames) - 1):
86
+ frame1 = preprocess_frame(frames[i], lower_bound, upper_bound, morph_iterations)
87
+ frame2 = preprocess_frame(frames[i + 1], lower_bound, upper_bound, morph_iterations)
88
 
89
  # Compute absolute difference between consecutive frames
90
  frame_diff = cv2.absdiff(frame2, frame1)
 
92
  frame_diff = cv2.convertScaleAbs(frame_diff, alpha=3.0, beta=0)
93
 
94
  # Detect circles centered at the Sun
95
+ circles = detect_circles(frame_diff, image_center, center_tolerance, param1, param2, min_radius, max_radius)
96
 
97
  if circles:
98
  # Take the largest circle (most prominent CME feature)
 
117
 
118
  # Generate output frames and report
119
  results = []
120
+ report = "Analysis Report (as of 07:44 PM PDT, May 24, 2025):\n"
121
  if growing_circle_data:
122
  report += f"Detected {len(growing_circle_data)} frames with growing concentric circles of mid-to-light pixels:\n"
123
  for c in growing_circle_data:
 
137
  except Exception as e:
138
  return f"Error during analysis: {str(e)}", []
139
 
140
+ # Gradio interface with user controls
141
  iface = gr.Interface(
142
  fn=analyze_gif,
143
+ inputs=[
144
+ gr.File(label="Upload Solar GIF", file_types=[".gif"]),
145
+ gr.Slider(minimum=0, maximum=255, value=100, step=1, label="Lower Intensity Bound (0-255)"),
146
+ gr.Slider(minimum=0, maximum=255, value=200, step=1, label="Upper Intensity Bound (0-255)"),
147
+ gr.Slider(minimum=10, maximum=200, value=80, step=1, label="Hough Param1 (Edge Threshold)"),
148
+ gr.Slider(minimum=1, maximum=50, value=15, step=1, label="Hough Param2 (Accumulator Threshold)"),
149
+ gr.Slider(minimum=10, maximum=100, value=30, step=1, label="Center Tolerance (Pixels)"),
150
+ gr.Slider(minimum=1, maximum=5, value=2, step=1, label="Morphological Dilation Iterations")
151
+ ],
152
  outputs=[
153
  gr.Textbox(label="Analysis Report"),
154
  gr.Gallery(label="Frames with Growing Circles")
155
  ],
156
  title="Solar CME Detection",
157
+ description="Upload a GIF of solar images to detect growing concentric circles of mid-to-light pixels indicative of Earth-directed coronal mass ejections (CMEs). Adjust the sliders to fine-tune detection."
158
  )
159
 
160
  if __name__ == "__main__":