Fahimeh Orvati Nia commited on
Commit
e768711
·
1 Parent(s): f2055ee
Files changed (2) hide show
  1. app.py +20 -13
  2. wrapper.py +29 -2
app.py CHANGED
@@ -12,36 +12,43 @@ def show_preview(image):
12
 
13
  def process(image):
14
  if image is None:
15
- return []
16
  with tempfile.TemporaryDirectory() as tmpdir:
17
  # Save PIL image preserving original format
18
- # Determine extension from image format
19
  ext = image.format.lower() if image.format else 'png'
20
  img_path = Path(tmpdir) / f"input.{ext}"
21
  image.save(img_path)
22
  outputs = run_pipeline_on_image(str(img_path), tmpdir, save_artifacts=True)
23
- # Keep order consistent: return vegetation indices only for now
24
- order = [
25
- 'NDVI', 'ARI', 'GNDVI' # , 'LBP', 'HOG', 'Lacunarity', 'SizeAnalysis'
26
- ]
27
- return [outputs[k] for k in order if k in outputs]
 
 
 
28
 
29
  with gr.Blocks() as demo:
30
  gr.Markdown("# 🌿 Sorghum Plant Analysis Demo")
31
- gr.Markdown("Upload a sorghum plant image to analyze vegetation indices, texture features, and morphology.")
32
-
33
  with gr.Row():
34
  with gr.Column():
35
  inp = gr.Image(type="pil", label="Upload Image")
36
  run = gr.Button("Run Pipeline", variant="primary")
37
  with gr.Column():
38
  preview = gr.Image(type="pil", label="Uploaded Image Preview", interactive=False)
39
-
40
- gallery = gr.Gallery(label="Analysis Results", columns=3, height="auto")
41
-
 
 
 
 
 
42
  # Update preview when image is uploaded
43
  inp.change(fn=show_preview, inputs=inp, outputs=preview)
44
- run.click(process, inputs=inp, outputs=gallery)
45
 
46
  if __name__ == "__main__":
47
  demo.launch()
 
12
 
13
  def process(image):
14
  if image is None:
15
+ return None, None, [], ""
16
  with tempfile.TemporaryDirectory() as tmpdir:
17
  # Save PIL image preserving original format
 
18
  ext = image.format.lower() if image.format else 'png'
19
  img_path = Path(tmpdir) / f"input.{ext}"
20
  image.save(img_path)
21
  outputs = run_pipeline_on_image(str(img_path), tmpdir, save_artifacts=True)
22
+
23
+ # Assemble displays
24
+ overlay = outputs.get('Overlay')
25
+ mask = outputs.get('Mask')
26
+ order = ['NDVI', 'ARI', 'GNDVI']
27
+ gallery_items = [outputs[k] for k in order if k in outputs]
28
+ stats_text = outputs.get('StatsText', '')
29
+ return overlay, mask, gallery_items, stats_text
30
 
31
  with gr.Blocks() as demo:
32
  gr.Markdown("# 🌿 Sorghum Plant Analysis Demo")
33
+ gr.Markdown("Upload a sorghum plant image to analyze vegetation indices, segmentation overlay, and stats.")
34
+
35
  with gr.Row():
36
  with gr.Column():
37
  inp = gr.Image(type="pil", label="Upload Image")
38
  run = gr.Button("Run Pipeline", variant="primary")
39
  with gr.Column():
40
  preview = gr.Image(type="pil", label="Uploaded Image Preview", interactive=False)
41
+
42
+ with gr.Row():
43
+ overlay_img = gr.Image(type="filepath", label="Segmentation Overlay", interactive=False)
44
+ mask_img = gr.Image(type="filepath", label="Mask", interactive=False)
45
+
46
+ gallery = gr.Gallery(label="Vegetation Indices", columns=3, height="auto")
47
+ stats = gr.Textbox(label="Statistics", lines=4)
48
+
49
  # Update preview when image is uploaded
50
  inp.change(fn=show_preview, inputs=inp, outputs=preview)
51
+ run.click(process, inputs=inp, outputs=[overlay_img, mask_img, gallery, stats])
52
 
53
  if __name__ == "__main__":
54
  demo.launch()
wrapper.py CHANGED
@@ -21,6 +21,10 @@ def run_pipeline_on_image(input_image_path: str, work_dir: str, save_artifacts:
21
  # Use input path directly (already in work_dir from app.py)
22
  input_path = Path(input_image_path)
23
 
 
 
 
 
24
  # Build in-memory config pointing input/output to the working directory
25
  cfg = Config()
26
  cfg.paths = Paths(
@@ -31,8 +35,6 @@ def run_pipeline_on_image(input_image_path: str, work_dir: str, save_artifacts:
31
  pipeline = SorghumPipeline(config=cfg)
32
 
33
  # Run the pipeline (single image minimal demo)
34
- os.environ['MINIMAL_DEMO'] = '1'
35
- os.environ['FAST_OUTPUT'] = '1'
36
  results = pipeline.run(single_image_path=str(input_path))
37
 
38
  # Collect outputs
@@ -55,4 +57,29 @@ def run_pipeline_on_image(input_image_path: str, work_dir: str, save_artifacts:
55
  if path.exists():
56
  outputs[label] = str(path)
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  return outputs
 
21
  # Use input path directly (already in work_dir from app.py)
22
  input_path = Path(input_image_path)
23
 
24
+ # Ensure demo env vars are set before pipeline construction
25
+ os.environ['MINIMAL_DEMO'] = '1'
26
+ os.environ['FAST_OUTPUT'] = '1'
27
+
28
  # Build in-memory config pointing input/output to the working directory
29
  cfg = Config()
30
  cfg.paths = Paths(
 
35
  pipeline = SorghumPipeline(config=cfg)
36
 
37
  # Run the pipeline (single image minimal demo)
 
 
38
  results = pipeline.run(single_image_path=str(input_path))
39
 
40
  # Collect outputs
 
57
  if path.exists():
58
  outputs[label] = str(path)
59
 
60
+ # Also include overlay and mask if present
61
+ overlay_path = work / 'results/overlay.png'
62
+ mask_path = work / 'results/mask.png'
63
+ if overlay_path.exists():
64
+ outputs['Overlay'] = str(overlay_path)
65
+ if mask_path.exists():
66
+ outputs['Mask'] = str(mask_path)
67
+
68
+ # Extract simple stats for display if present in pipeline results
69
+ try:
70
+ plants = results.get('plants', {}) if isinstance(results, dict) else {}
71
+ if plants:
72
+ _, pdata = next(iter(plants.items()))
73
+ veg = pdata.get('vegetation_indices', {})
74
+ stats_lines = []
75
+ for name in ['NDVI', 'ARI', 'GNDVI']:
76
+ entry = veg.get(name, {})
77
+ st = entry.get('statistics', {}) if isinstance(entry, dict) else {}
78
+ if st:
79
+ stats_lines.append(f"{name}: mean={st.get('mean', 0):.3f}, std={st.get('std', 0):.3f}")
80
+ if stats_lines:
81
+ outputs['StatsText'] = "\n".join(stats_lines)
82
+ except Exception:
83
+ pass
84
+
85
  return outputs