Vignesh38 commited on
Commit
09a3fbd
·
1 Parent(s): 1c92d3e

Add Gradio app.py and update requirements.txt

Browse files
Files changed (2) hide show
  1. app.py +89 -0
  2. requirements.txt +1 -0
app.py ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ import numpy as np
4
+ from PIL import Image
5
+ import torchvision.transforms as transforms
6
+ import gradio as gr
7
+
8
+ from models.networks import define_G
9
+
10
+ # --- 1. Model Configuration ---
11
+ class Args:
12
+ n_class = 2
13
+ net_G = 'base_transformer_pos_s4_dd8_dedim8'
14
+ gpu_ids = [] # [] for CPU inference
15
+ img_size = 256
16
+
17
+ args = Args()
18
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
19
+
20
+ # --- 2. Load Model & Weights ---
21
+ print(f"Loading model on {device}...")
22
+ model = define_G(args=args, gpu_ids=args.gpu_ids)
23
+
24
+ checkpoint_path = os.path.join("checkpoints", "BIT_LEVIR", "best_ckpt.pt")
25
+ if not os.path.exists(checkpoint_path):
26
+ raise FileNotFoundError(f"Checkpoint not found at: {checkpoint_path}")
27
+
28
+ checkpoint = torch.load(checkpoint_path, map_location=device)
29
+ model.load_state_dict(checkpoint["model_G_state_dict"])
30
+ model.to(device)
31
+ model.eval()
32
+
33
+ # --- 3. Image Preprocessing ---
34
+ transform = transforms.Compose([
35
+ transforms.Resize((256, 256)),
36
+ transforms.ToTensor(),
37
+ transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
38
+ ])
39
+
40
+ # --- 4. Prediction Function ---
41
+ def predict_change(img_a_pil, img_b_pil):
42
+ if img_a_pil is None or img_b_pil is None:
43
+ return None, None
44
+
45
+ # Convert to RGB
46
+ img_a_rgb = img_a_pil.convert("RGB")
47
+ img_b_rgb = img_b_pil.convert("RGB")
48
+
49
+ # Transform to tensor
50
+ tensor_a = transform(img_a_rgb).unsqueeze(0).to(device)
51
+ tensor_b = transform(img_b_rgb).unsqueeze(0).to(device)
52
+
53
+ with torch.no_grad():
54
+ output = model(tensor_a, tensor_b)
55
+ pred = torch.argmax(output, dim=1).squeeze(0).cpu().numpy()
56
+
57
+ # Binary mask: 0 (No change, Black), 255 (Change, White)
58
+ mask = (pred * 255).astype(np.uint8)
59
+ mask_pil = Image.fromarray(mask, mode="L")
60
+
61
+ # Create a red change overlay on Image B for clear visualization
62
+ img_b_resized = img_b_rgb.resize((256, 256))
63
+ img_b_np = np.array(img_b_resized)
64
+ overlay_np = img_b_np.copy()
65
+ overlay_np[mask == 255] = [255, 50, 50] # Highlight changes in Red
66
+ blended = Image.blend(img_b_resized, Image.fromarray(overlay_np), alpha=0.5)
67
+
68
+ return mask_pil, blended
69
+
70
+ # --- 5. Gradio Web UI ---
71
+ demo = gr.Interface(
72
+ fn=predict_change,
73
+ inputs=[
74
+ gr.Image(type="pil", label="Image A (Before)"),
75
+ gr.Image(type="pil", label="Image B (After)")
76
+ ],
77
+ outputs=[
78
+ gr.Image(type="pil", label="Change Detection Mask"),
79
+ gr.Image(type="pil", label="Overlay on Image B (Red = Change)")
80
+ ],
81
+ title="🛰️ Remote Sensing Change Detection (BIT_CD)",
82
+ description="Upload two satellite/aerial images (Before & After) to detect structural and landscape changes.",
83
+ examples=[
84
+ ["samples/A/test_2_0000_0000.png", "samples/B/test_2_0000_0000.png"]
85
+ ] if os.path.exists("samples/A/test_2_0000_0000.png") else None
86
+ )
87
+
88
+ if __name__ == "__main__":
89
+ demo.launch()
requirements.txt CHANGED
@@ -7,4 +7,5 @@ scikit-learn==0.24.2
7
  matplotlib==3.3.4
8
  tensorboardX
9
  tifffile
 
10
 
 
7
  matplotlib==3.3.4
8
  tensorboardX
9
  tifffile
10
+ gradio
11