muhammadhamza-stack commited on
Commit
697fc7d
·
0 Parent(s):

Clean initial commit

Browse files
.DS_Store ADDED
Binary file (6.15 kB). View file
 
.gitattributes ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.jpg filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Rice-classification With Export Result Feature
3
+ emoji: 📉
4
+ colorFrom: green
5
+ colorTo: purple
6
+ sdk: gradio
7
+ sdk_version: 6.5.1
8
+ app_file: app.py
9
+ pinned: false
10
+ ---
11
+
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ import pandas as pd
10
+ from io import BytesIO
11
+
12
+ # ============================================
13
+ # RICE ANALYZER PRO
14
+ # Advanced Grain Analytics and Quality Assessment Platform
15
+ # ============================================
16
+
17
+ # --- SYSTEM CONFIGURATION ---
18
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
19
+
20
+ # Initialize detection and classification models
21
+ try:
22
+ detection_model = YOLO('best.pt')
23
+ classifier_network = models.resnet50(weights=None)
24
+ classifier_network.fc = nn.Linear(classifier_network.fc.in_features, 3)
25
+ classifier_network.load_state_dict(
26
+ torch.load('rice_resnet_model.pth', map_location=device)
27
+ )
28
+ classifier_network = classifier_network.to(device)
29
+ classifier_network.eval()
30
+ models_loaded = True
31
+ except Exception as e:
32
+ print(f"Model initialization failed: {e}")
33
+ detection_model = None
34
+ classifier_network = None
35
+ models_loaded = False
36
+
37
+ # --- VARIETY DEFINITIONS ---
38
+ VARIETY_MAP = {
39
+ 0: "C9 Premium",
40
+ 1: "Kant Special",
41
+ 2: "Superfine Grade"
42
+ }
43
+
44
+ VARIETY_COLORS = {
45
+ "C9 Premium": (255, 100, 100), # Red
46
+ "Kant Special": (100, 100, 255), # Blue
47
+ "Superfine Grade": (100, 255, 100) # Green
48
+ }
49
+
50
+ # --- IMAGE PREPROCESSING ---
51
+ image_preprocessor = transforms.Compose([
52
+ transforms.Resize((224, 224)),
53
+ transforms.ToTensor(),
54
+ transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
55
+ ])
56
+
57
+ # ============================================
58
+ # ANALYTICS FUNCTIONS
59
+ # ============================================
60
+
61
+ def classify_grain(grain_image):
62
+ """
63
+ Classify a single grain using the neural network.
64
+ Returns the grain variety label.
65
+ """
66
+ if not models_loaded:
67
+ return "System Error"
68
+
69
+ tensor_input = image_preprocessor(grain_image).unsqueeze(0).to(device)
70
+ with torch.no_grad():
71
+ output = classifier_network(tensor_input)
72
+ class_idx = torch.argmax(output, dim=1).item()
73
+ return VARIETY_MAP[class_idx]
74
+
75
+ def generate_distribution_report(variety_counts):
76
+ """
77
+ Generate a text-based summary of grain variety distribution
78
+ with total counts, percentages, and dominant variety.
79
+ """
80
+ total = sum(variety_counts.values())
81
+ if total == 0:
82
+ return "No grains detected for analysis."
83
+
84
+ report = ["## Grain Distribution Report\n"]
85
+ report.append(f"Total Grains Detected: **{total}**\n\n")
86
+ report.append("### Breakdown by Variety:\n")
87
+
88
+ for variety, count in sorted(variety_counts.items(), key=lambda x: x[1], reverse=True):
89
+ percentage = (count / total) * 100
90
+ bar_length = int(percentage / 5)
91
+ bar = "█" * bar_length + "░" * (20 - bar_length)
92
+ report.append(f"- {variety}: {count} ({percentage:.1f}%) {bar}\n")
93
+
94
+ dominant_variety = max(variety_counts.items(), key=lambda x: x[1])[0]
95
+ report.append(f"\nDominant Variety: **{dominant_variety}**\n")
96
+ return "".join(report)
97
+
98
+ def generate_csv_export(grain_details):
99
+ """
100
+ Convert grain detection results into CSV format for export.
101
+ """
102
+ if not grain_details:
103
+ return None
104
+
105
+ df = pd.DataFrame(grain_details)
106
+ csv_buffer = BytesIO()
107
+ df.to_csv(csv_buffer, index=False)
108
+ csv_buffer.seek(0)
109
+ return csv_buffer.getvalue().decode()
110
+
111
+ def analyze_rice_image(input_image):
112
+ """
113
+ Full analysis pipeline:
114
+ 1. Detect grains
115
+ 2. Classify each grain
116
+ 3. Annotate image
117
+ 4. Generate distribution report
118
+ 5. Generate CSV export
119
+ """
120
+ if not models_loaded:
121
+ raise gr.Error("Analysis engine not available. Check model files.")
122
+
123
+ if input_image is None:
124
+ raise gr.Error("Please upload an image to start analysis.")
125
+
126
+ # Convert PIL image to BGR array for OpenCV
127
+ img_array = np.array(input_image)
128
+ img_bgr = cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR)
129
+
130
+ # Step 1: Detect grains
131
+ results = detection_model(img_bgr, verbose=False)[0]
132
+ boxes = results.boxes.xyxy.cpu().numpy()
133
+
134
+ if len(boxes) == 0:
135
+ return (
136
+ Image.fromarray(cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)),
137
+ "No grains detected. Try a clearer image.",
138
+ None
139
+ )
140
+
141
+ # Step 2: Classify grains
142
+ variety_counts = {v: 0 for v in VARIETY_MAP.values()}
143
+ grain_details = []
144
+
145
+ for idx, box in enumerate(boxes):
146
+ x1, y1, x2, y2 = map(int, box[:4])
147
+ crop = img_bgr[y1:y2, x1:x2]
148
+
149
+ if crop.shape[0] > 0 and crop.shape[1] > 0:
150
+ pil_crop = Image.fromarray(cv2.cvtColor(crop, cv2.COLOR_BGR2RGB))
151
+ variety_label = classify_grain(pil_crop)
152
+ variety_counts[variety_label] += 1
153
+
154
+ # Save details for CSV export
155
+ grain_details.append({
156
+ "Grain_ID": f"G{idx+1:04d}",
157
+ "Variety": variety_label,
158
+ "X_center": (x1 + x2)//2,
159
+ "Y_center": (y1 + y2)//2
160
+ })
161
+
162
+ # Annotate image
163
+ color = VARIETY_COLORS[variety_label]
164
+ cv2.rectangle(img_bgr, (x1, y1), (x2, y2), color, 3)
165
+ label = variety_label
166
+ (w, h), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2)
167
+ cv2.rectangle(img_bgr, (x1, y1-h-10), (x1+w, y1), color, -1)
168
+ cv2.putText(img_bgr, label, (x1, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255), 2)
169
+
170
+ # Step 3: Generate analytics report
171
+ report_text = generate_distribution_report(variety_counts)
172
+ csv_export = generate_csv_export(grain_details)
173
+
174
+ return (
175
+ Image.fromarray(cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)),
176
+ report_text,
177
+ csv_export
178
+ )
179
+
180
+ # ============================================
181
+ # GRADIO USER INTERFACE
182
+ # ============================================
183
+
184
+ custom_css = """
185
+ .gradio-container {
186
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
187
+ }
188
+ .header-box {
189
+ background: linear-gradient(135deg, #1e5631 0%, #4c9a2a 100%);
190
+ padding: 25px;
191
+ border-radius: 12px;
192
+ color: white;
193
+ text-align: center;
194
+ margin-bottom: 20px;
195
+ }
196
+ """
197
+
198
+ with gr.Blocks(css=custom_css, title="Rice Classifier") as app:
199
+
200
+ gr.HTML("""
201
+ <div class="header-box">
202
+ <h1>Rice Analyzer Pro</h1>
203
+ <p>Advanced Grain Classification | Rice Grain Locattor</p>
204
+ </div>
205
+ """)
206
+
207
+ with gr.Tabs():
208
+ # Analysis Tab
209
+ with gr.Tab("Analysis"):
210
+ gr.Markdown("""
211
+ ### How to Use
212
+ 1. Upload a clear image of rice grains.
213
+ 2. Click "Start Analysis".
214
+ 3. Review annotated results, distribution report, and export CSV.
215
+
216
+ **Color Coding:** Red = C9 Premium, Blue = Kant Special, Green = Superfine Grade
217
+ """)
218
+
219
+ with gr.Row():
220
+ with gr.Column(scale=1):
221
+ image_input = gr.Image(type="pil", label="Sample Image")
222
+ start_btn = gr.Button("Start Analysis", variant="primary", size="lg")
223
+
224
+ #show the annotated image in specific width and height
225
+ with gr.Column(scale=1):
226
+ annotated_output = gr.Image(label="Annotated Results", height=600, width=600)
227
+
228
+ with gr.Row():
229
+ report_output = gr.Markdown(label="Distribution Report")
230
+
231
+ with gr.Row():
232
+ csv_output = gr.Textbox(
233
+ label="CSV Export (Copy or Save)",
234
+ lines=8,
235
+ max_lines=15,
236
+ )
237
+
238
+ start_btn.click(
239
+ fn=analyze_rice_image,
240
+ inputs=image_input,
241
+ outputs=[annotated_output, report_output, csv_output]
242
+ )
243
+
244
+ # Documentation Tab
245
+ with gr.Tab("Documentation"):
246
+ gr.Markdown("""
247
+ ## System Overview
248
+
249
+ Rice Classifier uses a deep learning pipeline:
250
+
251
+ 1. **Grain Detection:** YOLO-based model identifies rice grains.
252
+ 2. **Grain Classification:** ResNet50 model classifies grains into three varieties.
253
+ 3. **CSV Export:** Detailed grain data available for download or copy.
254
+
255
+ ### Supported Varieties
256
+ | Variety | Description |
257
+ |---------|-------------|
258
+ | C9 Premium | High-quality long grain |
259
+ | Kant Special | Medium grain specialty |
260
+ | Superfine Grade | Ultra-refined grain |
261
+
262
+ ### Best Practices
263
+ - Use well-lit images without shadows
264
+ - Keep grains separated
265
+ - Use plain backgrounds
266
+ - Resolution: 1024x1024 or higher for best results
267
+
268
+ ### Technical Details
269
+ - Detection: YOLOv8
270
+ - Classification: ResNet50 fine-tuned
271
+ - GPU recommended for faster processing
272
+ """)
273
+
274
+ gr.Markdown("---")
275
+ gr.Markdown("### Sample Gallery")
276
+
277
+ gr.Examples(
278
+ examples=[
279
+ "samples/rice1.jpg",
280
+ "samples/rice2.jpg",
281
+ "samples/rice4.jpg",
282
+ "samples/rice5.jpg"
283
+ ],
284
+ inputs=image_input,
285
+ outputs=[annotated_output, report_output, csv_output],
286
+ fn=analyze_rice_image,
287
+ label="Click any sample to run analysis"
288
+ )
289
+
290
+ if __name__ == "__main__":
291
+ app.queue()
292
+ app.launch()
best.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:517d391d3ea5a490c9ef00112d735d85086449a1e8e30840a58183997bec6e48
3
+ size 5520595
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ numpy<2
2
+ Pillow>=9.0.0
3
+ gradio==3.50.2
4
+ gradio-client==0.6.1
5
+ torch>=2.0.0
6
+ torchvision>=0.15.0
7
+ ultralytics>=8.0.0
8
+ opencv-python-headless>=4.7.0
rice_resnet_model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:789b26cc9b71852782ba037086806ef006c83f931ccd9a37e7ee65eb28ce5575
3
+ size 94377562
samples/.DS_Store ADDED
Binary file (6.15 kB). View file
 
samples/rice1.jpg ADDED

Git LFS Details

  • SHA256: 4c0fd6a0afae3ffe977cd99fa77475b3298593888c51d738b1f390b6635ee285
  • Pointer size: 132 Bytes
  • Size of remote file: 3.61 MB
samples/rice2.jpg ADDED

Git LFS Details

  • SHA256: 0383e7978dbdadcebb413b9434ce77d326b0baa6d5a465e45526a262cb56ac13
  • Pointer size: 131 Bytes
  • Size of remote file: 695 kB
samples/rice3.jpg ADDED

Git LFS Details

  • SHA256: c4eeb8d6751c910a73b524c5074ebc6f527eaa3f209541fe9c73443f6ca6aa78
  • Pointer size: 131 Bytes
  • Size of remote file: 732 kB
samples/rice4.jpg ADDED

Git LFS Details

  • SHA256: c4a4e4670330d06749da9987317d32a7ebacbfe578781189fd218479313a928f
  • Pointer size: 132 Bytes
  • Size of remote file: 1.08 MB
samples/rice5.jpg ADDED

Git LFS Details

  • SHA256: 04f4f90ede869cccb1e86bc92487b565640ccd9657a730f4726d3e293b39da9b
  • Pointer size: 131 Bytes
  • Size of remote file: 552 kB