DrAbbas commited on
Commit
509ae44
·
verified ·
1 Parent(s): 90fb66a

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +53 -0
  2. app.py +326 -0
  3. requirements.txt +4 -0
README.md ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: SONAR-AI
3
+ emoji: 🔬
4
+ colorFrom: red
5
+ colorTo: blue
6
+ sdk: streamlit
7
+ sdk_version: 4.44.0
8
+ app_file: app.py
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ # 🔬 SONAR-AI
14
+
15
+ **نظام التحليل الذكي للأشعة السينية | Smart X-Ray Analysis System**
16
+
17
+ ## Author
18
+ **Dr. Abbas Fadhil Jasim Mohammed AL-Gburi**
19
+ - Iraqi General Customs Authority
20
+ - Universiti Kebangsaan Malaysia (UKM)
21
+
22
+ ## About
23
+ This system uses **Deep-DSOS** (Deep Dynamic Symbiotic Organisms Search) algorithm for intelligent X-ray image analysis and prohibited item detection.
24
+
25
+ ## Features
26
+ - 🔫 Gun Detection
27
+ - 🔪 Knife Detection
28
+ - ✂️ Scissors Detection
29
+ - 🔧 Tools Detection
30
+ - ✅ Safe Item Classification
31
+
32
+ ## Algorithm
33
+ Deep-DSOS is based on symbiotic relationships in nature:
34
+ - **Mutualism**: Both organisms benefit
35
+ - **Commensalism**: One benefits, other unaffected
36
+ - **Parasitism**: One benefits at expense of other
37
+
38
+ Enhanced with: Singer Map + Lévy Flight + Simulated Annealing
39
+
40
+ ## Usage
41
+ 1. Click "Train Model" to train the classifier
42
+ 2. Upload an X-ray image
43
+ 3. Click "Analyze" to get results
44
+
45
+ ## Citation
46
+ ```bibtex
47
+ @phdthesis{algburi2025,
48
+ author = {AL-Gburi, Abbas Fadhil Jasim},
49
+ title = {Hybridized Symbiotic Organisms Search with Simulated Annealing},
50
+ school = {Universiti Kebangsaan Malaysia},
51
+ year = {2025}
52
+ }
53
+ ```
app.py ADDED
@@ -0,0 +1,326 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ SONAR-AI - Smart X-Ray Analysis System
3
+ نظام التحليل الذكي للأشعة السينية
4
+
5
+ Dr. Abbas Fadhil Jasim AL-Gburi
6
+ Iraqi General Customs Authority & UKM
7
+ """
8
+
9
+ import streamlit as st
10
+ import numpy as np
11
+ from PIL import Image
12
+ import time
13
+
14
+ # Page config
15
+ st.set_page_config(
16
+ page_title="SONAR-AI",
17
+ page_icon="🔬",
18
+ layout="wide"
19
+ )
20
+
21
+ # Classes
22
+ CLASSES = {
23
+ 0: ("Gun", "سلاح ناري 🔫"),
24
+ 1: ("Knife", "سكين 🔪"),
25
+ 2: ("Wrench", "مفتاح ربط 🔧"),
26
+ 3: ("Pliers", "كماشة 🔧"),
27
+ 4: ("Scissors", "مقص ✂️"),
28
+ 5: ("Hammer", "مطرقة 🔨"),
29
+ 6: ("Safe", "آمن ✅")
30
+ }
31
+
32
+ # Singer Map
33
+ class SingerMap:
34
+ def __init__(self, mu=1.07, x0=0.7):
35
+ self.mu, self.x = mu, x0
36
+
37
+ def next(self):
38
+ x = self.x
39
+ self.x = self.mu * (7.86*x - 23.31*x**2 + 28.75*x**3 - 13.30*x**4)
40
+ self.x = max(0.001, min(0.999, abs(self.x)))
41
+ return self.x
42
+
43
+ # Feature Extractor
44
+ class FeatureExtractor:
45
+ def __init__(self, n_features=256):
46
+ self.n_features = n_features
47
+
48
+ def extract(self, image):
49
+ if len(image.shape) == 2:
50
+ image = np.stack([image]*3, axis=-1)
51
+
52
+ h, w = image.shape[:2]
53
+ features = []
54
+
55
+ for c in range(3):
56
+ hist, _ = np.histogram(image[:,:,c], bins=16, range=(0,255))
57
+ features.extend(hist / (hist.sum() + 1e-6))
58
+
59
+ gray = np.mean(image, axis=2)
60
+ gh, gw = h//4, w//4
61
+ for i in range(4):
62
+ for j in range(4):
63
+ patch = gray[i*gh:(i+1)*gh, j*gw:(j+1)*gw]
64
+ features.extend([np.mean(patch), np.std(patch)])
65
+
66
+ dark_ratio = np.sum(gray < 60) / gray.size
67
+ very_dark = np.sum(gray < 30) / gray.size
68
+ features.extend([dark_ratio, very_dark, np.mean(gray), np.std(gray)])
69
+
70
+ edges_h = np.abs(np.diff(gray, axis=0)).mean()
71
+ edges_v = np.abs(np.diff(gray, axis=1)).mean()
72
+ features.extend([edges_h, edges_v])
73
+
74
+ features = np.array(features)
75
+ if len(features) < self.n_features:
76
+ features = np.pad(features, (0, self.n_features - len(features)))
77
+ return features[:self.n_features]
78
+
79
+ # Deep-DSOS
80
+ class DeepDSOS:
81
+ def __init__(self, eco_size=20, max_iter=30, alpha=0.6):
82
+ self.eco_size = eco_size
83
+ self.max_iter = max_iter
84
+ self.alpha = alpha
85
+ self.singer = SingerMap()
86
+
87
+ def fitness(self, solution, X, y):
88
+ selected = np.where(solution == 1)[0]
89
+ if len(selected) == 0:
90
+ return 0.0
91
+
92
+ X_sel = X[:, selected]
93
+
94
+ from sklearn.neighbors import KNeighborsClassifier
95
+ from sklearn.model_selection import cross_val_score
96
+ try:
97
+ knn = KNeighborsClassifier(n_neighbors=3)
98
+ scores = cross_val_score(knn, X_sel, y, cv=3)
99
+ perf = scores.mean()
100
+ except:
101
+ perf = 0.5
102
+
103
+ reduction = 1 - len(selected) / len(solution)
104
+ return self.alpha * perf + (1 - self.alpha) * reduction
105
+
106
+ def optimize(self, X, y, progress_bar=None):
107
+ n_features = X.shape[1]
108
+
109
+ ecosystem = np.random.randint(0, 2, (self.eco_size, n_features))
110
+ for i in range(self.eco_size):
111
+ if np.sum(ecosystem[i]) == 0:
112
+ ecosystem[i, np.random.randint(n_features)] = 1
113
+
114
+ fitness_values = np.array([self.fitness(org, X, y) for org in ecosystem])
115
+ best_idx = np.argmax(fitness_values)
116
+ best = ecosystem[best_idx].copy()
117
+ best_fitness = fitness_values[best_idx]
118
+
119
+ for iteration in range(self.max_iter):
120
+ if progress_bar:
121
+ progress_bar.progress((iteration + 1) / self.max_iter)
122
+
123
+ chaos = self.singer.next()
124
+
125
+ for i in range(self.eco_size):
126
+ j = np.random.choice([x for x in range(self.eco_size) if x != i])
127
+
128
+ Xi = ecosystem[i].astype(float)
129
+ Xbest = best.astype(float)
130
+
131
+ Xi_new = Xi + np.random.random(n_features) * chaos * (Xbest - Xi)
132
+ sigmoid = 1 / (1 + np.exp(-np.clip(Xi_new, -500, 500)))
133
+ Xi_new = (sigmoid > 0.5).astype(int)
134
+ if np.sum(Xi_new) == 0:
135
+ Xi_new[np.argmax(sigmoid)] = 1
136
+
137
+ if self.fitness(Xi_new, X, y) > fitness_values[i]:
138
+ ecosystem[i] = Xi_new
139
+ fitness_values[i] = self.fitness(Xi_new, X, y)
140
+
141
+ current_best = np.argmax(fitness_values)
142
+ if fitness_values[current_best] > best_fitness:
143
+ best = ecosystem[current_best].copy()
144
+ best_fitness = fitness_values[current_best]
145
+
146
+ return best, best_fitness
147
+
148
+ # SONAR-AI Model
149
+ class SonarAI:
150
+ def __init__(self):
151
+ self.extractor = FeatureExtractor(256)
152
+ self.classifier = None
153
+ self.selected_features = None
154
+ self.is_trained = False
155
+
156
+ def generate_data(self, n_samples=300):
157
+ np.random.seed(42)
158
+ h, w = 224, 224
159
+ images, labels = [], []
160
+
161
+ samples_per_class = n_samples // 7
162
+
163
+ for class_id in range(6):
164
+ for _ in range(samples_per_class):
165
+ img = np.random.randint(80, 160, (h, w, 3), dtype=np.uint8)
166
+ x, y = np.random.randint(40, w-100), np.random.randint(40, h-80)
167
+ obj_h, obj_w = np.random.randint(30, 60), np.random.randint(50, 100)
168
+ img[y:y+obj_h, x:x+obj_w] = np.random.randint(5, 40, (obj_h, obj_w, 3), dtype=np.uint8)
169
+ images.append(img)
170
+ labels.append(class_id)
171
+
172
+ for _ in range(n_samples - len(images)):
173
+ img = np.random.randint(90, 170, (h, w, 3), dtype=np.uint8)
174
+ for _ in range(np.random.randint(2, 5)):
175
+ rx, ry = np.random.randint(10, w-60), np.random.randint(10, h-50)
176
+ rw, rh = np.random.randint(30, 70), np.random.randint(25, 50)
177
+ color = np.random.randint(100, 160)
178
+ img[ry:ry+rh, rx:rx+rw] = np.random.randint(color-20, color+20, (rh, rw, 3), dtype=np.uint8)
179
+ images.append(img)
180
+ labels.append(6)
181
+
182
+ indices = np.random.permutation(len(images))
183
+ return [images[i] for i in indices], [labels[i] for i in indices]
184
+
185
+ def train(self, progress_bar=None, status_text=None):
186
+ if status_text:
187
+ status_text.text("توليد البيانات...")
188
+ images, labels = self.generate_data()
189
+
190
+ if status_text:
191
+ status_text.text("استخلاص الميزات...")
192
+ X = np.array([self.extractor.extract(img) for img in images])
193
+ y = np.array(labels)
194
+
195
+ if status_text:
196
+ status_text.text("تشغيل Deep-DSOS...")
197
+ dsos = DeepDSOS(eco_size=15, max_iter=20, alpha=0.6)
198
+ solution, fitness = dsos.optimize(X, y, progress_bar)
199
+
200
+ self.selected_features = np.where(solution == 1)[0]
201
+ if len(self.selected_features) == 0:
202
+ self.selected_features = np.arange(min(50, X.shape[1]))
203
+
204
+ X_selected = X[:, self.selected_features]
205
+
206
+ if status_text:
207
+ status_text.text("تدريب المصنف...")
208
+ from sklearn.svm import SVC
209
+ from sklearn.model_selection import cross_val_score
210
+
211
+ self.classifier = SVC(kernel='rbf', C=10, gamma='scale',
212
+ class_weight='balanced', probability=True, random_state=42)
213
+
214
+ scores = cross_val_score(self.classifier, X_selected, y, cv=3)
215
+ accuracy = scores.mean()
216
+
217
+ self.classifier.fit(X_selected, y)
218
+ self.is_trained = True
219
+
220
+ return {
221
+ 'accuracy': accuracy,
222
+ 'features': f"{len(self.selected_features)}/{X.shape[1]}",
223
+ 'reduction': f"{(1 - len(self.selected_features)/X.shape[1])*100:.1f}%",
224
+ 'samples': len(images)
225
+ }
226
+
227
+ def analyze(self, image):
228
+ if not self.is_trained:
229
+ return None, None, None
230
+
231
+ img = Image.fromarray(image).resize((224, 224))
232
+ img_array = np.array(img)
233
+
234
+ features = self.extractor.extract(img_array)
235
+ features_selected = features[self.selected_features]
236
+
237
+ prediction = self.classifier.predict([features_selected])[0]
238
+ probabilities = self.classifier.predict_proba([features_selected])[0]
239
+ confidence = float(np.max(probabilities))
240
+
241
+ return prediction, confidence, probabilities
242
+
243
+ # Initialize model
244
+ if 'model' not in st.session_state:
245
+ st.session_state.model = SonarAI()
246
+
247
+ # UI
248
+ st.markdown("""
249
+ <h1 style='text-align: center; color: #e94560;'>🔬 SONAR-AI</h1>
250
+ <p style='text-align: center; color: #666;'>نظام التحليل الذكي للأشعة السينية | Smart X-Ray Analysis System</p>
251
+ <p style='text-align: center; color: #888; font-size: 0.9em;'>د. عباس فاضل جاسم محمد الجبوري | الهيئة العامة للكمارك - العراق</p>
252
+ <hr>
253
+ """, unsafe_allow_html=True)
254
+
255
+ col1, col2 = st.columns(2)
256
+
257
+ with col1:
258
+ st.markdown("### ⚙️ تدريب النموذج")
259
+
260
+ if st.session_state.model.is_trained:
261
+ st.success("✅ النموذج جاهز!")
262
+ else:
263
+ st.warning("⚠️ النموذج غير مدرب")
264
+
265
+ if st.button("🚀 تدريب النموذج", type="primary", use_container_width=True):
266
+ progress_bar = st.progress(0)
267
+ status_text = st.empty()
268
+
269
+ with st.spinner("جاري التدريب..."):
270
+ results = st.session_state.model.train(progress_bar, status_text)
271
+
272
+ status_text.empty()
273
+ progress_bar.empty()
274
+
275
+ st.success("✅ تم الت��ريب بنجاح!")
276
+ st.metric("الدقة", f"{results['accuracy']*100:.1f}%")
277
+ st.metric("الميزات", results['features'])
278
+ st.metric("التقليل", results['reduction'])
279
+ st.rerun()
280
+
281
+ st.markdown("---")
282
+ st.markdown("""
283
+ ### 📚 عن الخوارزمية
284
+ **Deep-DSOS** - خوارزمية الكائنات التكافلية الديناميكية العميقة
285
+
286
+ تحسينات: Singer Map + Lévy Flight + SA
287
+ """)
288
+
289
+ with col2:
290
+ st.markdown("### 📤 تحليل الصورة")
291
+
292
+ uploaded_file = st.file_uploader("ارفع صورة X-Ray", type=['png', 'jpg', 'jpeg'])
293
+
294
+ if uploaded_file is not None:
295
+ image = Image.open(uploaded_file).convert('RGB')
296
+ st.image(image, caption="الصورة المرفوعة", use_container_width=True)
297
+
298
+ if st.button("🔍 تحليل الصورة", type="secondary", use_container_width=True):
299
+ if not st.session_state.model.is_trained:
300
+ st.error("❌ الرجاء تدريب النموذج أولاً!")
301
+ else:
302
+ with st.spinner("جاري التحليل..."):
303
+ image_array = np.array(image)
304
+ prediction, confidence, probabilities = st.session_state.model.analyze(image_array)
305
+
306
+ class_en, class_ar = CLASSES[prediction]
307
+ is_prohibited = prediction != 6
308
+
309
+ if is_prohibited:
310
+ st.error(f"## ⚠️ تحذير: {class_ar}")
311
+ else:
312
+ st.success(f"## ✅ {class_ar}")
313
+
314
+ st.metric("نسبة الثقة", f"{confidence*100:.1f}%")
315
+
316
+ st.markdown("#### جميع الاحتمالات:")
317
+ for i, prob in enumerate(probabilities):
318
+ en, ar = CLASSES[i]
319
+ st.progress(prob, text=f"{ar} ({en}): {prob*100:.1f}%")
320
+
321
+ st.markdown("---")
322
+ st.markdown("""
323
+ <p style='text-align: center; color: #888;'>
324
+ © 2026 SONAR-AI | Dr. Abbas AL-Gburi | Iraqi General Customs Authority & UKM
325
+ </p>
326
+ """, unsafe_allow_html=True)
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ streamlit
2
+ numpy
3
+ scikit-learn
4
+ pillow