timnirmal commited on
Commit
a3bc3f4
·
verified ·
1 Parent(s): 3b1a998

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. .github/workflows/update_space.yml +28 -28
  2. main.py +206 -206
  3. requirements.txt +3 -0
.github/workflows/update_space.yml CHANGED
@@ -1,28 +1,28 @@
1
- name: Run Python script
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
-
8
- jobs:
9
- build:
10
- runs-on: ubuntu-latest
11
-
12
- steps:
13
- - name: Checkout
14
- uses: actions/checkout@v2
15
-
16
- - name: Set up Python
17
- uses: actions/setup-python@v2
18
- with:
19
- python-version: '3.9'
20
-
21
- - name: Install Gradio
22
- run: python -m pip install gradio
23
-
24
- - name: Log in to Hugging Face
25
- run: python -c 'import huggingface_hub; huggingface_hub.login(token="${{ secrets.hf_token }}")'
26
-
27
- - name: Deploy to Spaces
28
- run: gradio deploy
 
1
+ name: Run Python script
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout
14
+ uses: actions/checkout@v2
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v2
18
+ with:
19
+ python-version: '3.9'
20
+
21
+ - name: Install Gradio
22
+ run: python -m pip install gradio
23
+
24
+ - name: Log in to Hugging Face
25
+ run: python -c 'import huggingface_hub; huggingface_hub.login(token="${{ secrets.hf_token }}")'
26
+
27
+ - name: Deploy to Spaces
28
+ run: gradio deploy
main.py CHANGED
@@ -1,206 +1,206 @@
1
- # yolo11_gradio_single_textlist_enhance.py
2
- from ultralytics import YOLO
3
- import gradio as gr
4
- import cv2, numpy as np, random
5
-
6
- DEFAULT_MODEL = "weights/best.pt"
7
- _MODEL_CACHE = {}
8
-
9
- def get_model(path:str):
10
- if path not in _MODEL_CACHE:
11
- _MODEL_CACHE[path] = YOLO(path)
12
- return _MODEL_CACHE[path]
13
-
14
- # ---------- utilities ----------
15
- def class_color(cid:int):
16
- random.seed(int(cid) + 12345)
17
- return tuple(int(x) for x in np.array([random.randrange(60,255) for _ in range(3)]))
18
-
19
- def ensure_odd(v:int, minv:int=3):
20
- v = int(v)
21
- if v < minv: v = minv
22
- if v % 2 == 0: v += 1
23
- return v
24
-
25
- def to_bgr(img):
26
- if len(img.shape) == 2: # gray -> BGR
27
- return cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
28
- return img
29
-
30
- # ---------- enhancements (applied in this order) ----------
31
- def enhance_image(img_bgr,
32
- use_gray: bool,
33
- use_clahe: bool, clahe_clip: float, clahe_grid: int,
34
- use_bc: bool, alpha_gain: float, beta_bias: float,
35
- use_unsharp: bool, us_amount: float, us_radius: float,
36
- use_thresh: bool, th_block: int, th_C: int,
37
- use_morph: bool, morph_k: int, morph_iters: int,
38
- use_invert: bool):
39
- base = img_bgr.copy()
40
- work_gray = None
41
-
42
- if use_gray or use_clahe or use_thresh:
43
- work_gray = cv2.cvtColor(base, cv2.COLOR_BGR2GRAY)
44
-
45
- # CLAHE on gray
46
- if use_clahe:
47
- clahe = cv2.createCLAHE(clipLimit=float(clahe_clip),
48
- tileGridSize=(int(clahe_grid), int(clahe_grid)))
49
- work_gray = clahe.apply(work_gray)
50
-
51
- # Brightness/Contrast (linear gain/bias)
52
- if use_bc:
53
- if work_gray is not None:
54
- work_gray = cv2.convertScaleAbs(work_gray, alpha=float(alpha_gain), beta=float(beta_bias))
55
- else:
56
- base = cv2.convertScaleAbs(base, alpha=float(alpha_gain), beta=float(beta_bias))
57
-
58
- # Unsharp mask (detail boost)
59
- if use_unsharp:
60
- # apply on gray if exists, else on color
61
- if work_gray is not None:
62
- blur = cv2.GaussianBlur(work_gray, (0,0), sigmaX=float(us_radius), sigmaY=float(us_radius))
63
- work_gray = cv2.addWeighted(work_gray, 1.0 + float(us_amount), blur, -float(us_amount), 0)
64
- else:
65
- blur = cv2.GaussianBlur(base, (0,0), sigmaX=float(us_radius), sigmaY=float(us_radius))
66
- base = cv2.addWeighted(base, 1.0 + float(us_amount), blur, -float(us_amount), 0)
67
-
68
- # Adaptive threshold (great for floor plans)
69
- if use_thresh:
70
- bs = ensure_odd(int(th_block), 3)
71
- work_gray = cv2.adaptiveThreshold(
72
- work_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, bs, int(th_C)
73
- )
74
-
75
- # Merge back to BGR if we are working in gray
76
- if work_gray is not None:
77
- base = to_bgr(work_gray)
78
-
79
- # Morphological clean-up (OPEN to remove speckles)
80
- if use_morph:
81
- k = max(1, int(morph_k))
82
- kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (k, k))
83
- base = cv2.morphologyEx(base, cv2.MORPH_OPEN, kernel, iterations=int(morph_iters))
84
-
85
- # Invert black/white (sometimes better for plans)
86
- if use_invert:
87
- base = cv2.bitwise_not(base)
88
-
89
- return base
90
-
91
- # ---------- drawing ----------
92
- def draw_transparent_boxes(img_bgr, boxes, alpha=0.5):
93
- overlay = img_bgr.copy()
94
- if boxes is not None and len(boxes):
95
- xyxy = boxes.xyxy.cpu().numpy()
96
- cls = boxes.cls.cpu().numpy().astype(int)
97
- for bb, cl in zip(xyxy, cls):
98
- x1, y1, x2, y2 = [int(round(v)) for v in bb]
99
- cv2.rectangle(overlay, (x1, y1), (x2, y2), class_color(cl), thickness=-1)
100
- return cv2.addWeighted(overlay, float(alpha), img_bgr, 1 - float(alpha), 0.0)
101
-
102
- def detections_to_text(result):
103
- if result.boxes is None or len(result.boxes) == 0:
104
- return "Detections: 0"
105
- names = result.names
106
- xyxy = result.boxes.xyxy.cpu().numpy()
107
- conf = result.boxes.conf.cpu().numpy()
108
- cls = result.boxes.cls.cpu().numpy().astype(int)
109
- lines = [f"{i:02d}. {names.get(int(c), str(int(c)))}\t{cf:.2f}\t[{int(x1)},{int(y1)},{int(x2)},{int(y2)}]"
110
- for i, ((x1,y1,x2,y2), cf, c) in enumerate(zip(xyxy, conf, cls), start=1)]
111
- return "Detections: " + str(len(lines)) + "\n" + "\n".join(lines)
112
-
113
- # ---------- main inference ----------
114
- def infer(img_rgb, model_path, conf, iou, alpha,
115
- # toggles
116
- use_gray, use_clahe, use_bc, use_unsharp, use_thresh, use_morph, use_invert,
117
- detect_on_enh,
118
- # params
119
- clahe_clip, clahe_grid,
120
- alpha_gain, beta_bias,
121
- us_amount, us_radius,
122
- th_block, th_C,
123
- morph_k, morph_iters):
124
- if img_rgb is None:
125
- return None, "Upload an image to run inference."
126
-
127
- model = get_model(model_path)
128
- img_bgr = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)
129
-
130
- # Enhance image for visualization (and optionally for detection)
131
- enh_bgr = enhance_image(
132
- img_bgr,
133
- use_gray, use_clahe, clahe_clip, int(clahe_grid),
134
- use_bc, alpha_gain, beta_bias,
135
- use_unsharp, us_amount, us_radius,
136
- use_thresh, int(th_block), int(th_C),
137
- use_morph, int(morph_k), int(morph_iters),
138
- use_invert
139
- )
140
-
141
- det_input = enh_bgr if detect_on_enh else img_bgr
142
- r = model.predict(det_input, conf=float(conf), iou=float(iou), verbose=False)[0]
143
-
144
- # Draw only transparent boxes (no labels)
145
- out_bgr = draw_transparent_boxes(enh_bgr, r.boxes, alpha=float(alpha))
146
- out_rgb = cv2.cvtColor(out_bgr, cv2.COLOR_BGR2RGB)
147
-
148
- # Detection list in textbox
149
- det_text = detections_to_text(r)
150
- return out_rgb, det_text
151
-
152
- # ---------- UI ----------
153
- with gr.Blocks(title="YOLOv11 — Split View with Floor-Plan Enhancers") as demo:
154
- gr.Markdown("## MW Floor Plan")
155
- with gr.Row():
156
- with gr.Column(scale=1):
157
- inp = gr.Image(type="numpy", label="Upload image", height=520)
158
- model_path = gr.Textbox(value=DEFAULT_MODEL, label="Model (.pt)")
159
- with gr.Row():
160
- conf = gr.Slider(0, 1, value=0.25, step=0.01, label="Confidence")
161
- iou = gr.Slider(0, 1, value=0.45, step=0.01, label="IoU")
162
- alpha = gr.Slider(0, 1, value=0.50, step=0.05, label="Box transparency")
163
- with gr.Column(scale=1):
164
- out_img = gr.Image(label="Result (enhanced + transparent boxes)", height=520)
165
- det_box = gr.Textbox(label="Detections (class, conf, [x1,y1,x2,y2])",
166
- lines=12, interactive=False)
167
-
168
- gr.Markdown("### Enhancements (tick to enable) — ordered top→bottom for best floor-plan contrast")
169
- with gr.Row():
170
- use_gray = gr.Checkbox(value=True, label="Grayscale")
171
- use_clahe = gr.Checkbox(value=False, label="Auto-contrast (CLAHE)")
172
- use_bc = gr.Checkbox(value=False, label="Brightness/Contrast")
173
- use_unsharp = gr.Checkbox(value=True, label="Unsharp mask (sharpen)")
174
- use_thresh = gr.Checkbox(value=False, label="Adaptive threshold (binarize)")
175
- use_morph = gr.Checkbox(value=False, label="Morphological clean-up (OPEN)")
176
- use_invert = gr.Checkbox(value=False, label="Invert B/W")
177
- detect_on_enh= gr.Checkbox(value=True, label="Run detection on enhanced image")
178
-
179
- with gr.Row():
180
- clahe_clip = gr.Slider(1.0, 6.0, value=2.0, step=0.1, label="CLAHE clipLimit")
181
- clahe_grid = gr.Slider(4, 16, value=8, step=1, label="CLAHE tileGridSize")
182
- alpha_gain = gr.Slider(0.5, 2.0, value=1.2, step=0.05, label="Contrast gain (alpha)")
183
- beta_bias = gr.Slider(-64, 64, value=0, step=1, label="Brightness bias (beta)")
184
- with gr.Row():
185
- us_amount = gr.Slider(0.0, 2.0, value=0.8, step=0.05, label="Unsharp amount")
186
- us_radius = gr.Slider(0.3, 5.0, value=1.2, step=0.1, label="Unsharp radius (sigma)")
187
- th_block = gr.Slider(3, 51, value=25, step=2, label="Adaptive block size (odd)")
188
- th_C = gr.Slider(-15, 15, value=5, step=1, label="Adaptive C")
189
- with gr.Row():
190
- morph_k = gr.Slider(1, 9, value=3, step=1, label="Morph kernel size")
191
- morph_iters = gr.Slider(0, 5, value=1, step=1, label="Morph iterations")
192
-
193
- run = gr.Button("Run")
194
- # wire events
195
- inputs = [inp, model_path, conf, iou, alpha,
196
- use_gray, use_clahe, use_bc, use_unsharp, use_thresh, use_morph, use_invert,
197
- detect_on_enh,
198
- clahe_clip, clahe_grid, alpha_gain, beta_bias, us_amount, us_radius,
199
- th_block, th_C, morph_k, morph_iters]
200
- outputs = [out_img, det_box]
201
-
202
- run.click(infer, inputs, outputs)
203
- inp.change(infer, inputs, outputs) # auto-run on upload
204
-
205
- if __name__ == "__main__":
206
- demo.launch(share=True)
 
1
+ # yolo11_gradio_single_textlist_enhance.py
2
+ from ultralytics import YOLO
3
+ import gradio as gr
4
+ import cv2, numpy as np, random
5
+
6
+ DEFAULT_MODEL = "weights/best.pt"
7
+ _MODEL_CACHE = {}
8
+
9
+ def get_model(path:str):
10
+ if path not in _MODEL_CACHE:
11
+ _MODEL_CACHE[path] = YOLO(path)
12
+ return _MODEL_CACHE[path]
13
+
14
+ # ---------- utilities ----------
15
+ def class_color(cid:int):
16
+ random.seed(int(cid) + 12345)
17
+ return tuple(int(x) for x in np.array([random.randrange(60,255) for _ in range(3)]))
18
+
19
+ def ensure_odd(v:int, minv:int=3):
20
+ v = int(v)
21
+ if v < minv: v = minv
22
+ if v % 2 == 0: v += 1
23
+ return v
24
+
25
+ def to_bgr(img):
26
+ if len(img.shape) == 2: # gray -> BGR
27
+ return cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
28
+ return img
29
+
30
+ # ---------- enhancements (applied in this order) ----------
31
+ def enhance_image(img_bgr,
32
+ use_gray: bool,
33
+ use_clahe: bool, clahe_clip: float, clahe_grid: int,
34
+ use_bc: bool, alpha_gain: float, beta_bias: float,
35
+ use_unsharp: bool, us_amount: float, us_radius: float,
36
+ use_thresh: bool, th_block: int, th_C: int,
37
+ use_morph: bool, morph_k: int, morph_iters: int,
38
+ use_invert: bool):
39
+ base = img_bgr.copy()
40
+ work_gray = None
41
+
42
+ if use_gray or use_clahe or use_thresh:
43
+ work_gray = cv2.cvtColor(base, cv2.COLOR_BGR2GRAY)
44
+
45
+ # CLAHE on gray
46
+ if use_clahe:
47
+ clahe = cv2.createCLAHE(clipLimit=float(clahe_clip),
48
+ tileGridSize=(int(clahe_grid), int(clahe_grid)))
49
+ work_gray = clahe.apply(work_gray)
50
+
51
+ # Brightness/Contrast (linear gain/bias)
52
+ if use_bc:
53
+ if work_gray is not None:
54
+ work_gray = cv2.convertScaleAbs(work_gray, alpha=float(alpha_gain), beta=float(beta_bias))
55
+ else:
56
+ base = cv2.convertScaleAbs(base, alpha=float(alpha_gain), beta=float(beta_bias))
57
+
58
+ # Unsharp mask (detail boost)
59
+ if use_unsharp:
60
+ # apply on gray if exists, else on color
61
+ if work_gray is not None:
62
+ blur = cv2.GaussianBlur(work_gray, (0,0), sigmaX=float(us_radius), sigmaY=float(us_radius))
63
+ work_gray = cv2.addWeighted(work_gray, 1.0 + float(us_amount), blur, -float(us_amount), 0)
64
+ else:
65
+ blur = cv2.GaussianBlur(base, (0,0), sigmaX=float(us_radius), sigmaY=float(us_radius))
66
+ base = cv2.addWeighted(base, 1.0 + float(us_amount), blur, -float(us_amount), 0)
67
+
68
+ # Adaptive threshold (great for floor plans)
69
+ if use_thresh:
70
+ bs = ensure_odd(int(th_block), 3)
71
+ work_gray = cv2.adaptiveThreshold(
72
+ work_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, bs, int(th_C)
73
+ )
74
+
75
+ # Merge back to BGR if we are working in gray
76
+ if work_gray is not None:
77
+ base = to_bgr(work_gray)
78
+
79
+ # Morphological clean-up (OPEN to remove speckles)
80
+ if use_morph:
81
+ k = max(1, int(morph_k))
82
+ kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (k, k))
83
+ base = cv2.morphologyEx(base, cv2.MORPH_OPEN, kernel, iterations=int(morph_iters))
84
+
85
+ # Invert black/white (sometimes better for plans)
86
+ if use_invert:
87
+ base = cv2.bitwise_not(base)
88
+
89
+ return base
90
+
91
+ # ---------- drawing ----------
92
+ def draw_transparent_boxes(img_bgr, boxes, alpha=0.5):
93
+ overlay = img_bgr.copy()
94
+ if boxes is not None and len(boxes):
95
+ xyxy = boxes.xyxy.cpu().numpy()
96
+ cls = boxes.cls.cpu().numpy().astype(int)
97
+ for bb, cl in zip(xyxy, cls):
98
+ x1, y1, x2, y2 = [int(round(v)) for v in bb]
99
+ cv2.rectangle(overlay, (x1, y1), (x2, y2), class_color(cl), thickness=-1)
100
+ return cv2.addWeighted(overlay, float(alpha), img_bgr, 1 - float(alpha), 0.0)
101
+
102
+ def detections_to_text(result):
103
+ if result.boxes is None or len(result.boxes) == 0:
104
+ return "Detections: 0"
105
+ names = result.names
106
+ xyxy = result.boxes.xyxy.cpu().numpy()
107
+ conf = result.boxes.conf.cpu().numpy()
108
+ cls = result.boxes.cls.cpu().numpy().astype(int)
109
+ lines = [f"{i:02d}. {names.get(int(c), str(int(c)))}\t{cf:.2f}\t[{int(x1)},{int(y1)},{int(x2)},{int(y2)}]"
110
+ for i, ((x1,y1,x2,y2), cf, c) in enumerate(zip(xyxy, conf, cls), start=1)]
111
+ return "Detections: " + str(len(lines)) + "\n" + "\n".join(lines)
112
+
113
+ # ---------- main inference ----------
114
+ def infer(img_rgb, model_path, conf, iou, alpha,
115
+ # toggles
116
+ use_gray, use_clahe, use_bc, use_unsharp, use_thresh, use_morph, use_invert,
117
+ detect_on_enh,
118
+ # params
119
+ clahe_clip, clahe_grid,
120
+ alpha_gain, beta_bias,
121
+ us_amount, us_radius,
122
+ th_block, th_C,
123
+ morph_k, morph_iters):
124
+ if img_rgb is None:
125
+ return None, "Upload an image to run inference."
126
+
127
+ model = get_model(model_path)
128
+ img_bgr = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)
129
+
130
+ # Enhance image for visualization (and optionally for detection)
131
+ enh_bgr = enhance_image(
132
+ img_bgr,
133
+ use_gray, use_clahe, clahe_clip, int(clahe_grid),
134
+ use_bc, alpha_gain, beta_bias,
135
+ use_unsharp, us_amount, us_radius,
136
+ use_thresh, int(th_block), int(th_C),
137
+ use_morph, int(morph_k), int(morph_iters),
138
+ use_invert
139
+ )
140
+
141
+ det_input = enh_bgr if detect_on_enh else img_bgr
142
+ r = model.predict(det_input, conf=float(conf), iou=float(iou), verbose=False)[0]
143
+
144
+ # Draw only transparent boxes (no labels)
145
+ out_bgr = draw_transparent_boxes(enh_bgr, r.boxes, alpha=float(alpha))
146
+ out_rgb = cv2.cvtColor(out_bgr, cv2.COLOR_BGR2RGB)
147
+
148
+ # Detection list in textbox
149
+ det_text = detections_to_text(r)
150
+ return out_rgb, det_text
151
+
152
+ # ---------- UI ----------
153
+ with gr.Blocks(title="YOLOv11 — Split View with Floor-Plan Enhancers") as demo:
154
+ gr.Markdown("## MW Floor Plan")
155
+ with gr.Row():
156
+ with gr.Column(scale=1):
157
+ inp = gr.Image(type="numpy", label="Upload image", height=520)
158
+ model_path = gr.Textbox(value=DEFAULT_MODEL, label="Model (.pt)")
159
+ with gr.Row():
160
+ conf = gr.Slider(0, 1, value=0.25, step=0.01, label="Confidence")
161
+ iou = gr.Slider(0, 1, value=0.45, step=0.01, label="IoU")
162
+ alpha = gr.Slider(0, 1, value=0.50, step=0.05, label="Box transparency")
163
+ with gr.Column(scale=1):
164
+ out_img = gr.Image(label="Result (enhanced + transparent boxes)", height=520)
165
+ det_box = gr.Textbox(label="Detections (class, conf, [x1,y1,x2,y2])",
166
+ lines=12, interactive=False)
167
+
168
+ gr.Markdown("### Enhancements (tick to enable) — ordered top→bottom for best floor-plan contrast")
169
+ with gr.Row():
170
+ use_gray = gr.Checkbox(value=True, label="Grayscale")
171
+ use_clahe = gr.Checkbox(value=False, label="Auto-contrast (CLAHE)")
172
+ use_bc = gr.Checkbox(value=False, label="Brightness/Contrast")
173
+ use_unsharp = gr.Checkbox(value=True, label="Unsharp mask (sharpen)")
174
+ use_thresh = gr.Checkbox(value=False, label="Adaptive threshold (binarize)")
175
+ use_morph = gr.Checkbox(value=False, label="Morphological clean-up (OPEN)")
176
+ use_invert = gr.Checkbox(value=False, label="Invert B/W")
177
+ detect_on_enh= gr.Checkbox(value=True, label="Run detection on enhanced image")
178
+
179
+ with gr.Row():
180
+ clahe_clip = gr.Slider(1.0, 6.0, value=2.0, step=0.1, label="CLAHE clipLimit")
181
+ clahe_grid = gr.Slider(4, 16, value=8, step=1, label="CLAHE tileGridSize")
182
+ alpha_gain = gr.Slider(0.5, 2.0, value=1.2, step=0.05, label="Contrast gain (alpha)")
183
+ beta_bias = gr.Slider(-64, 64, value=0, step=1, label="Brightness bias (beta)")
184
+ with gr.Row():
185
+ us_amount = gr.Slider(0.0, 2.0, value=0.8, step=0.05, label="Unsharp amount")
186
+ us_radius = gr.Slider(0.3, 5.0, value=1.2, step=0.1, label="Unsharp radius (sigma)")
187
+ th_block = gr.Slider(3, 51, value=25, step=2, label="Adaptive block size (odd)")
188
+ th_C = gr.Slider(-15, 15, value=5, step=1, label="Adaptive C")
189
+ with gr.Row():
190
+ morph_k = gr.Slider(1, 9, value=3, step=1, label="Morph kernel size")
191
+ morph_iters = gr.Slider(0, 5, value=1, step=1, label="Morph iterations")
192
+
193
+ run = gr.Button("Run")
194
+ # wire events
195
+ inputs = [inp, model_path, conf, iou, alpha,
196
+ use_gray, use_clahe, use_bc, use_unsharp, use_thresh, use_morph, use_invert,
197
+ detect_on_enh,
198
+ clahe_clip, clahe_grid, alpha_gain, beta_bias, us_amount, us_radius,
199
+ th_block, th_C, morph_k, morph_iters]
200
+ outputs = [out_img, det_box]
201
+
202
+ run.click(infer, inputs, outputs)
203
+ inp.change(infer, inputs, outputs) # auto-run on upload
204
+
205
+ if __name__ == "__main__":
206
+ demo.launch(share=True)
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ ultralytics
2
+ gradio
3
+ opencv-python