muhammadhamza-stack commited on
Commit
4795176
·
1 Parent(s): d36ef68

refine the gradio app

Browse files
Files changed (3) hide show
  1. .gitignore +2 -0
  2. app.py +246 -43
  3. requirements.txt +3 -2
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ venv
2
+ gradio_cached_examples
app.py CHANGED
@@ -1,3 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import cv2
2
  import numpy as np
3
  from PIL import Image
@@ -6,18 +120,71 @@ from torchvision import models, transforms
6
  from ultralytics import YOLO
7
  import gradio as gr
8
  import torch.nn as nn
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  # Initialize device
11
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
12
 
13
  # Load models
14
- yolo_model = YOLO('best.pt') # Make sure this file is uploaded
15
- resnet = models.resnet50(pretrained=False)
16
- resnet.fc = nn.Linear(resnet.fc.in_features, 3)
17
- resnet.load_state_dict(torch.load('rice_resnet_model.pth', map_location=device))
18
- resnet = resnet.to(device)
19
- resnet.eval()
20
-
 
 
 
 
 
 
21
  # Class labels
22
  class_labels = ["c9", "kant", "superf"]
23
 
@@ -29,7 +196,9 @@ transform = transforms.Compose([
29
  ])
30
 
31
  def classify_crop(crop_img):
32
- """ایک چاول کے دانے کو درجہ بند کریں"""
 
 
33
  image = transform(crop_img).unsqueeze(0).to(device)
34
  with torch.no_grad():
35
  output = resnet(image)
@@ -37,43 +206,78 @@ def classify_crop(crop_img):
37
  return class_labels[predicted.item()]
38
 
39
  def detect_and_classify(input_image):
40
- """تصویر پر کارروائی کریں اور ہر دانے کو شناخت کریں"""
 
 
 
 
 
 
41
  image = np.array(input_image)
42
  image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
43
 
44
- results = yolo_model(image)[0]
 
45
  boxes = results.boxes.xyxy.cpu().numpy()
46
 
 
 
 
 
 
47
  for box in boxes:
48
  x1, y1, x2, y2 = map(int, box[:4])
49
  crop = image[y1:y2, x1:x2]
50
- crop_pil = Image.fromarray(cv2.cvtColor(crop, cv2.COLOR_BGR2RGB))
51
- predicted_label = classify_crop(crop_pil)
52
-
53
- cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
54
- cv2.putText(image,
55
- predicted_label,
56
- (x1, y1-10),
57
- cv2.FONT_HERSHEY_SIMPLEX,
58
- 0.9,
59
- (36, 255, 12),
60
- 2)
 
 
 
 
61
 
62
  return Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
63
 
64
- with gr.Blocks(title="چاول کی اقسام کی درجہ بندی") as demo:
65
- gr.Markdown("""
66
- ## 🍚 چاول کی اقسام کی شناخت کا نظام
67
- ایک تصویر اپ لوڈ کریں جس میں چاول کے دانے ہوں۔
68
- سسٹم ہر دانے کو شناخت اور درجہ بند کرے گا۔
69
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  with gr.Row():
72
- with gr.Column():
73
- image_input = gr.Image(type="pil", label="چاول کی تصویر اپ لوڈ کریں")
74
- submit_btn = gr.Button("تجزیہ شروع کریں", variant="primary")
75
- with gr.Column():
76
- output_image = gr.Image(label="نتائج", interactive=False)
 
 
77
 
78
  submit_btn.click(
79
  fn=detect_and_classify,
@@ -81,7 +285,11 @@ with gr.Blocks(title="چاول کی اقسام کی درجہ بندی") as demo:
81
  outputs=output_image
82
  )
83
 
84
- # ✅ Move this block inside the `with gr.Blocks(...)` scope
 
 
 
 
85
  gr.Examples(
86
  examples=[
87
  "samples/rice1.jpg",
@@ -92,16 +300,11 @@ with gr.Blocks(title="چاول کی اقسام کی درجہ بندی") as demo:
92
  "samples/rice6.jpg"
93
  ],
94
  inputs=image_input,
95
- label="مثال تصاویر"
 
 
 
96
  )
97
- gr.Markdown("""
98
- ### ℹ️ ہدایات:
99
- - ✅ واضح اور الگ الگ چاول کے دانے والی تصویر اپ لوڈ کریں۔
100
- - ⚠️ اگر دانے آپس میں جُڑے ہوں یا ایک دوسرے پر چڑھے ہوں، تو نتائج متاثر ہو سکتے ہیں۔
101
- - 📸 بہتر پہچان کے لیے تصویر کا پس منظر صاف اور دانے منتشر (پھیلے ہوئے) ہونے چاہئیں۔
102
- - 🖼️ آپ اوپر دی گئی مثال تصاویر کو بھی دیکھ سکتے ہیں۔
103
- """)
104
-
105
-
106
 
 
107
  demo.launch()
 
1
+ # import cv2
2
+ # import numpy as np
3
+ # from PIL import Image
4
+ # import torch
5
+ # from torchvision import models, transforms
6
+ # from ultralytics import YOLO
7
+ # import gradio as gr
8
+ # import torch.nn as nn
9
+
10
+ # # Initialize device
11
+ # device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
12
+
13
+ # # Load models
14
+ # yolo_model = YOLO('best.pt') # Make sure this file is uploaded
15
+ # resnet = models.resnet50(pretrained=False)
16
+ # resnet.fc = nn.Linear(resnet.fc.in_features, 3)
17
+ # resnet.load_state_dict(torch.load('rice_resnet_model.pth', map_location=device))
18
+ # resnet = resnet.to(device)
19
+ # resnet.eval()
20
+
21
+ # # Class labels
22
+ # class_labels = ["c9", "kant", "superf"]
23
+
24
+ # # Image transformations
25
+ # transform = transforms.Compose([
26
+ # transforms.Resize((224, 224)),
27
+ # transforms.ToTensor(),
28
+ # transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
29
+ # ])
30
+
31
+ # def classify_crop(crop_img):
32
+ # """ایک چاول کے دانے کو درجہ بند کریں"""
33
+ # image = transform(crop_img).unsqueeze(0).to(device)
34
+ # with torch.no_grad():
35
+ # output = resnet(image)
36
+ # _, predicted = torch.max(output, 1)
37
+ # return class_labels[predicted.item()]
38
+
39
+ # def detect_and_classify(input_image):
40
+ # """تصویر پر کارروائی کریں اور ہر دانے کو شناخت کریں"""
41
+ # image = np.array(input_image)
42
+ # image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
43
+
44
+ # results = yolo_model(image)[0]
45
+ # boxes = results.boxes.xyxy.cpu().numpy()
46
+
47
+ # for box in boxes:
48
+ # x1, y1, x2, y2 = map(int, box[:4])
49
+ # crop = image[y1:y2, x1:x2]
50
+ # crop_pil = Image.fromarray(cv2.cvtColor(crop, cv2.COLOR_BGR2RGB))
51
+ # predicted_label = classify_crop(crop_pil)
52
+
53
+ # cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
54
+ # cv2.putText(image,
55
+ # predicted_label,
56
+ # (x1, y1-10),
57
+ # cv2.FONT_HERSHEY_SIMPLEX,
58
+ # 0.9,
59
+ # (36, 255, 12),
60
+ # 2)
61
+
62
+ # return Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
63
+
64
+ # with gr.Blocks(title="چاول کی اقسام کی درجہ بندی") as demo:
65
+ # gr.Markdown("""
66
+ # ## 🍚 چاول کی اقسام کی شناخت کا نظام
67
+ # ایک تصویر اپ لوڈ کریں جس میں چاول کے دانے ہوں۔
68
+ # سسٹم ہر دانے کو شناخت اور درجہ بند کرے گا۔
69
+ # """)
70
+
71
+ # with gr.Row():
72
+ # with gr.Column():
73
+ # image_input = gr.Image(type="pil", label="چاول کی تصویر اپ لوڈ کریں")
74
+ # submit_btn = gr.Button("تجزیہ شروع کریں", variant="primary")
75
+ # with gr.Column():
76
+ # output_image = gr.Image(label="نتائج", interactive=False)
77
+
78
+ # submit_btn.click(
79
+ # fn=detect_and_classify,
80
+ # inputs=image_input,
81
+ # outputs=output_image
82
+ # )
83
+
84
+ # # ✅ Move this block inside the `with gr.Blocks(...)` scope
85
+ # gr.Examples(
86
+ # examples=[
87
+ # "samples/rice1.jpg",
88
+ # "samples/rice2.jpg",
89
+ # "samples/rice3.jpg",
90
+ # "samples/rice4.jpg",
91
+ # "samples/rice5.jpg",
92
+ # "samples/rice6.jpg"
93
+ # ],
94
+ # inputs=image_input,
95
+ # label="مثال تصاویر"
96
+ # )
97
+ # gr.Markdown("""
98
+ # ### ℹ️ ہدایات:
99
+ # - ✅ واضح اور الگ الگ چاول کے دانے والی تصویر اپ لوڈ کریں۔
100
+ # - ⚠️ اگر دانے آپس میں جُڑے ہوں یا ایک دوسرے پر چڑھے ہوں، تو نتائج متاثر ہو سکتے ہیں۔
101
+ # - 📸 بہتر پہچان کے لیے تصویر کا پس منظر صاف اور دانے منتشر (پھیلے ہوئے) ہونے چاہئیں۔
102
+ # - 🖼️ آپ اوپر دی گئی مثال تصاویر کو بھی دیکھ سکتے ہیں۔
103
+ # """)
104
+
105
+
106
+
107
+ # demo.launch()
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
  import cv2
116
  import numpy as np
117
  from PIL import Image
 
120
  from ultralytics import YOLO
121
  import gradio as gr
122
  import torch.nn as nn
123
+ import os
124
+
125
+ # --- DOCUMENTATION STRINGS (English and Urdu) ---
126
+
127
+ USAGE_GUIDELINES = """
128
+ ## 1. Quick Start Guide: Run Instructions
129
+
130
+ **English:**
131
+ 1. **Upload:** Click the 'Upload Rice Image' box and select your image (JPG or PNG).
132
+ 2. **Run:** Click the **"Run Analysis"** button.
133
+ 3. **Review:** The output image will show each detected rice grain marked with its predicted class label.
134
+
135
+ **Urdu (اردو):**
136
+ ## 1. فوری استعمال کی ہدایات: تجزیہ شروع کریں
137
+ 1. **تصویر اپ لوڈ کریں:** 'چاول کی تصویر اپ لوڈ کریں' کے باکس پر کلک کریں اور اپنی تصویر (JPG یا PNG) منتخب کریں۔
138
+ 2. **چلائیں:** **"تجزیہ شروع کریں"** بٹن پر کلک کریں۔
139
+ 3. **نتائج دیکھیں:** آؤٹ پٹ تصویر ہر شناخت شدہ چاول کے دانے کو اس کی پیش گوئی کردہ قسم کے لیبل کے ساتھ دکھائے گی۔
140
+ """
141
+
142
+ INPUT_EXPLANATION = """
143
+ ## 2. Expected Inputs / متوقع ان پٹ
144
+
145
+ | Input Field (ان پٹ فیلڈ) | Purpose (مقصد) | Requirement (ضرورت) |
146
+ | :--- | :--- | :--- |
147
+ | **Upload Image** / تصویر اپ لوڈ کریں | The image containing the rice grains for analysis. | Must be a single image file (JPG, PNG). The input should preferably contain clear, separated rice grains. |
148
+
149
+ **Important Note (اہم نوٹ):** For the best detection and classification accuracy, ensure the rice grains are scattered (not heavily overlapping) and the background is simple.
150
+ """
151
+
152
+ OUTPUT_EXPLANATION = """
153
+ ## 3. Expected Outputs (Detection and Classification) / متوقع آؤٹ پٹ
154
+
155
+ The output is the original image overlayed with results from the two-stage AI model:
156
+
157
+ * **Bounding Boxes:** Each individual rice grain detected by the YOLO model is enclosed in a **Green rectangle**.
158
+ * **Labels:** Above each rectangle, the predicted class label is displayed:
159
+ * **c9** (A specific rice variety)
160
+ * **kant** (Another specific rice variety)
161
+ * **superf** (A third specific rice variety)
162
+
163
+ **Urdu (اردو):**
164
+ آؤٹ پٹ اصل تصویر ہوگی جس پر دو مراحل پر مشتمل AI ماڈل کے نتائج لگائے گئے ہیں:
165
+ * **نشان زد ڈبے:** YOLO ماڈل سے تلاش کیے گئے ہر چاول کے دانے کے گرد **سبز رنگ کا مستطیل** لگایا جائے گا۔
166
+ * **لیبلز:** ہر مستطیل کے اوپر اس کی پیش گوئی کردہ قسم کا لیبل درج ہوگا: c9، kant، یا superf۔
167
+ """
168
+
169
+ # --- CORE LOGIC (KEPT AS IS) ---
170
 
171
  # Initialize device
172
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
173
 
174
  # Load models
175
+ # NOTE: These paths (best.pt, rice_resnet_model.pth) must exist in the execution directory.
176
+ try:
177
+ yolo_model = YOLO('best.pt')
178
+ resnet = models.resnet50(weights=None) # Use weights=None since we are loading custom weights
179
+ resnet.fc = nn.Linear(resnet.fc.in_features, 3)
180
+ resnet.load_state_dict(torch.load('rice_resnet_model.pth', map_location=device))
181
+ resnet = resnet.to(device)
182
+ resnet.eval()
183
+ except Exception as e:
184
+ print(f"Error loading models: {e}. Ensure 'best.pt' and 'rice_resnet_model.pth' are present.")
185
+ yolo_model = None
186
+ resnet = None
187
+
188
  # Class labels
189
  class_labels = ["c9", "kant", "superf"]
190
 
 
196
  ])
197
 
198
  def classify_crop(crop_img):
199
+ """Classify a single rice grain crop"""
200
+ if resnet is None:
201
+ return "Error"
202
  image = transform(crop_img).unsqueeze(0).to(device)
203
  with torch.no_grad():
204
  output = resnet(image)
 
206
  return class_labels[predicted.item()]
207
 
208
  def detect_and_classify(input_image):
209
+ """Process the image and classify each grain"""
210
+ if yolo_model is None or resnet is None:
211
+ raise gr.Error("Models failed to load. Cannot proceed with analysis.")
212
+
213
+ if input_image is None:
214
+ raise gr.Error("Please upload an image or select an example.")
215
+
216
  image = np.array(input_image)
217
  image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
218
 
219
+ # YOLO Detection
220
+ results = yolo_model(image, verbose=False)[0]
221
  boxes = results.boxes.xyxy.cpu().numpy()
222
 
223
+ if len(boxes) == 0:
224
+ gr.Warning("No rice grains detected in the image.")
225
+ return Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
226
+
227
+
228
  for box in boxes:
229
  x1, y1, x2, y2 = map(int, box[:4])
230
  crop = image[y1:y2, x1:x2]
231
+
232
+ # Check if crop is valid
233
+ if crop.shape[0] > 0 and crop.shape[1] > 0:
234
+ crop_pil = Image.fromarray(cv2.cvtColor(crop, cv2.COLOR_BGR2RGB))
235
+ predicted_label = classify_crop(crop_pil)
236
+
237
+ # Draw results
238
+ cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2) # Green box
239
+ cv2.putText(image,
240
+ predicted_label,
241
+ (x1, y1-10),
242
+ cv2.FONT_HERSHEY_SIMPLEX,
243
+ 0.9,
244
+ (36, 255, 12),
245
+ 2) # Green text
246
 
247
  return Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
248
 
249
+ # --- GRADIO UI (Single Tab) ---
250
+
251
+ with gr.Blocks(title="Rice Variety Classification") as demo:
252
+
253
+ gr.Markdown(
254
+ """
255
+ # Rice Variety Classification System / چاول کی اقسام کی شناخت کا نظام
256
+ Upload an image containing rice grains. The system will detect and classify each grain using a two-stage AI pipeline (YOLO for detection, ResNet for classification).
257
+ """
258
+ )
259
+
260
+ # 1. GUIDELINES SECTION
261
+ with gr.Accordion(" Tips & Guidelines (ہدایات)", open=False):
262
+ gr.Markdown(USAGE_GUIDELINES)
263
+ gr.Markdown("---")
264
+ gr.Markdown(INPUT_EXPLANATION)
265
+ gr.Markdown("---")
266
+ gr.Markdown(OUTPUT_EXPLANATION)
267
+
268
+ gr.Markdown("---")
269
+
270
+ # 2. APPLICATION INTERFACE
271
+ gr.Markdown("## Start Analysis / تجزیہ شروع کریں")
272
 
273
  with gr.Row():
274
+ with gr.Column(scale=1):
275
+ gr.Markdown("## Step 1: Upload an Image of Rice / چاول کی تصویر اپ لوڈ کریں")
276
+ image_input = gr.Image(type="pil")
277
+ gr.Markdown("## Step 2: Click Run Analysis /تجزیہ شروع کریں ")
278
+ submit_btn = gr.Button("Run Analysis / تجزیہ شروع کریں", variant="primary")
279
+ gr.Markdown("## Outputs / نتائج ")
280
+ output_image = gr.Image(scale=2, interactive=True)
281
 
282
  submit_btn.click(
283
  fn=detect_and_classify,
 
285
  outputs=output_image
286
  )
287
 
288
+ gr.Markdown("---")
289
+
290
+ # 3. EXAMPLES SECTION
291
+ gr.Markdown("## Example Images / مثال تصاویر")
292
+ # Ensure "samples/" directory exists and contains these images
293
  gr.Examples(
294
  examples=[
295
  "samples/rice1.jpg",
 
300
  "samples/rice6.jpg"
301
  ],
302
  inputs=image_input,
303
+ outputs=output_image, # Required for proper caching and execution
304
+ fn=detect_and_classify, # Required for proper caching and execution
305
+ cache_examples=True,
306
+ label="Click to load and run a sample image / نمونہ تصویر لوڈ اور رن کرنے کے لیے کلک کریں"
307
  )
 
 
 
 
 
 
 
 
 
308
 
309
+ demo.queue()
310
  demo.launch()
requirements.txt CHANGED
@@ -2,6 +2,7 @@ torch>=2.0.0
2
  torchvision>=0.15.0
3
  ultralytics>=8.0.0
4
  opencv-python-headless>=4.7.0
5
- gradio>=3.0.0
6
  numpy>=1.21.0
7
- Pillow>=9.0.0
 
 
 
2
  torchvision>=0.15.0
3
  ultralytics>=8.0.0
4
  opencv-python-headless>=4.7.0
 
5
  numpy>=1.21.0
6
+ Pillow>=9.0.
7
+ gradio==3.50.2
8
+ gradio-client==0.6.1