File size: 6,385 Bytes
4697ca4 3834351 4768cde dd1d7f5 a32df56 4c1c4a7 3834351 668a993 484130e 668a993 f8ac29e 668a993 f8ac29e ca48751 916b83d 668a993 916b83d 4768cde 916b83d 2716edf 49abd9f 916b83d 2716edf 916b83d 2716edf 7c31b44 0153931 668a993 60e6efb 3c8af25 60e6efb f8ac29e 60e6efb 3834351 916b83d 02ce968 e88ed7d 2592b1e 2716edf 668a993 e768711 d807150 916b83d 668a993 d807150 e768711 668a993 2a055cf 668a993 2a055cf e768711 5f6c42c 3c8af25 c170961 2a055cf c170961 93d0941 2a055cf e768711 2a055cf 668a993 2a055cf 1bf989c 2a055cf e768711 916b83d 668a993 2a055cf 916b83d 3834351 69b6a19 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
import os
# Force cache to /tmp before any imports
os.environ['HF_HOME'] = '/tmp/huggingface'
os.environ['TRANSFORMERS_CACHE'] = '/tmp/huggingface/transformers'
os.environ['TORCH_HOME'] = '/tmp/torch'
import gradio as gr
import tempfile
from pathlib import Path
from wrapper import run_pipeline_on_image
from PIL import Image
# Base directory for preset images
BASE_DIR = Path(__file__).resolve().parent
# Preset images available for selection
PRESET_IMAGES = {
"Sorghum": str(BASE_DIR / "Sorghum.tif"),
"Corn": str(BASE_DIR / "Corn.tif"),
"Cotton": str(BASE_DIR / "Cotton.tif"),
}
# Path to header logo
LOGO_PATH = str(BASE_DIR / "logo.png")
def process(file_path, preset_choice):
"""Process image and yield results progressively for immediate display."""
# Determine dataset type (single-plant mode for Corn, multi-plant for others)
single_plant_mode = False
if preset_choice:
chosen = PRESET_IMAGES.get(preset_choice)
if chosen:
file_path = chosen
# Corn uses single-plant mode
single_plant_mode = (preset_choice == "Corn")
if not file_path:
# Return 10 outputs (removed YOLO tips)
return None, None, None, None, None, None, None, [], None, ""
with tempfile.TemporaryDirectory() as tmpdir:
src = Path(file_path)
ext = src.suffix.lstrip('.') or 'tif'
img_path = Path(tmpdir) / f"input.{ext}"
try:
# Copy raw uploaded bytes
img_bytes = src.read_bytes()
img_path.write_bytes(img_bytes)
except Exception:
# Fallback: save via PIL if direct copy fails
Image.open(src).save(img_path)
# Don't show immediate preview - wait for pipeline's InputImage for correctness
input_preview = None
# Helper to load PIL images
def load_pil(path_str):
try:
if not path_str:
return None
im = Image.open(path_str)
copied = im.copy()
im.close()
return copied
except Exception:
return None
# Run the pipeline progressively (generator)
for outputs in run_pipeline_on_image(str(img_path), tmpdir, save_artifacts=True, single_plant_mode=single_plant_mode):
# Load all available outputs progressively
composite = load_pil(outputs.get('Composite'))
overlay = load_pil(outputs.get('Overlay'))
mask = load_pil(outputs.get('Mask'))
input_img = load_pil(outputs.get('InputImage')) or input_preview
size_img = load_pil(str(Path(tmpdir) / 'results/size.size_analysis.png'))
# Texture images (green band)
lbp_path = Path(tmpdir) / 'texture_output/lbp_green.png'
hog_path = Path(tmpdir) / 'texture_output/hog_green.png'
lac1_path = Path(tmpdir) / 'texture_output/lac1_green.png'
texture_img = load_pil(str(lbp_path)) if lbp_path.exists() else None
hog_img = load_pil(str(hog_path)) if hog_path.exists() else None
lac1_img = load_pil(str(lac1_path)) if lac1_path.exists() else None
# Vegetation indices
order = ['NDVI', 'GNDVI', 'SAVI']
gallery_items = [load_pil(outputs[k]) for k in order if k in outputs]
stats_text = outputs.get('StatsText', '')
# Yield intermediate/final results as they become available
yield (
input_img,
composite,
mask,
overlay,
texture_img,
hog_img,
lac1_img,
gallery_items,
size_img,
stats_text,
)
with gr.Blocks(fill_width=True) as demo:
# Header logo (no share/download/fullscreen buttons), full width
gr.Image(
value=LOGO_PATH,
show_label=False,
interactive=False,
height=80,
container=False,
show_download_button=False,
show_share_button=False,
show_fullscreen_button=False,
)
gr.Markdown("# 🌿 Automated Plant Analysis Demo")
gr.Markdown("Upload a plant image (TIFF preferred) to compute and visualize composite, mask, overlay, texture, vegetation indices, and statistics.")
with gr.Row():
with gr.Column():
# Use File input to preserve raw TIFFs
inp = gr.File(
type="filepath",
file_types=[".tif", ".tiff", ".png", ".jpg"],
label="Upload Image"
)
preset = gr.Radio(
choices=list(PRESET_IMAGES.keys()),
label="Or choose a preset image",
value=None
)
run = gr.Button("Run Pipeline", variant="primary")
# Row 1: input image
with gr.Row():
input_img = gr.Image(type="pil", label="Input Image", interactive=False, height=380)
# Row 2: composite, mask, overlay
with gr.Row():
composite_img = gr.Image(type="pil", label="Composite (Segmentation Input)", interactive=False)
mask_img = gr.Image(type="pil", label="Mask", interactive=False)
overlay_img = gr.Image(type="pil", label="Segmentation Overlay", interactive=False)
# Row 3: textures
with gr.Row():
texture_img = gr.Image(type="pil", label="Texture LBP (Green Band)", interactive=False)
hog_img = gr.Image(type="pil", label="Texture HOG (Green Band)", interactive=False)
lac1_img = gr.Image(type="pil", label="Texture Lac1 (Green Band)", interactive=False)
# Row 4: vegetation indices
gallery = gr.Gallery(label="Vegetation Indices", columns=3, height="auto")
# Row 5: morphology size (YOLO removed)
with gr.Row():
size_img = gr.Image(type="pil", label="Plant Morphology", interactive=False)
# Final: statistics table
stats = gr.Textbox(label="Statistics", lines=4)
run.click(
process,
inputs=[inp, preset],
outputs=[
input_img,
composite_img,
mask_img,
overlay_img,
texture_img,
hog_img,
lac1_img,
gallery,
size_img,
stats,
]
)
if __name__ == "__main__":
demo.launch()
|