Update app.py
Browse files
app.py
CHANGED
|
@@ -792,6 +792,11 @@ def physics_density_scan(img, n_regions=8):
|
|
| 792 |
|
| 793 |
overall_mean = np.mean(means)
|
| 794 |
overall_dark = np.mean(darks)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 795 |
|
| 796 |
anomalies = {}
|
| 797 |
for r in regions:
|
|
@@ -799,20 +804,23 @@ def physics_density_scan(img, n_regions=8):
|
|
| 799 |
mean_diff = abs(p['mean'] - overall_mean)
|
| 800 |
dark_diff = abs(p['dark_ratio'] - overall_dark)
|
| 801 |
|
| 802 |
-
# ═══ قواعد الكشف
|
| 803 |
|
| 804 |
-
# 1. فرق الكثافة عن المتوسط
|
| 805 |
-
density_anomaly = mean_diff > 25
|
| 806 |
|
| 807 |
-
# 2. فرق البكسلات الداكنة
|
| 808 |
-
dark_anomaly = dark_diff > 0.12
|
| 809 |
|
| 810 |
-
# 3. مطابقة بصمة الأدوية
|
| 811 |
-
|
|
|
|
| 812 |
PHARMA_SIGNATURE['mean_range'][0] <= p['mean'] <= PHARMA_SIGNATURE['mean_range'][1] and
|
| 813 |
PHARMA_SIGNATURE['dark_ratio_range'][0] <= p['dark_ratio'] <= PHARMA_SIGNATURE['dark_ratio_range'][1] and
|
| 814 |
PHARMA_SIGNATURE['entropy_range'][0] <= p['entropy'] <= PHARMA_SIGNATURE['entropy_range'][1]
|
| 815 |
)
|
|
|
|
|
|
|
| 816 |
|
| 817 |
# النتيجة المركّبة
|
| 818 |
score = 0
|
|
@@ -845,6 +853,8 @@ def physics_density_scan(img, n_regions=8):
|
|
| 845 |
'n_regions': len(regions),
|
| 846 |
'materials_found': materials_found,
|
| 847 |
'has_mixed_cargo': has_mixed,
|
|
|
|
|
|
|
| 848 |
'n_anomalies': len(anomalies),
|
| 849 |
'pharma_suspects': len(pharma_suspects),
|
| 850 |
'overall_mean': overall_mean,
|
|
@@ -1464,8 +1474,14 @@ def analyze_image(img, declared_text):
|
|
| 1464 |
physics_html += f"<div style='background:{p_color};color:white;padding:8px 12px;border-radius:8px;text-align:center;font-weight:bold;margin-bottom:8px;font-size:13px;'>🔬 التحليل الفيزيائي للكثافة (PBDAD) — {p_text}</div>"
|
| 1465 |
|
| 1466 |
# ملخص أرقام
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1467 |
physics_html += f"<div style='display:flex;gap:6px;margin-bottom:8px;flex-wrap:wrap;justify-content:center;'>"
|
| 1468 |
physics_html += f"<div style='background:white;padding:6px 12px;border-radius:8px;border:1px solid #ddd;text-align:center;'><div style='font-size:18px;font-weight:bold;color:#1565C0;'>{physics_summary.get('n_regions',0)}</div><div style='font-size:10px;color:#777;'>مناطق</div></div>"
|
|
|
|
| 1469 |
physics_html += f"<div style='background:white;padding:6px 12px;border-radius:8px;border:1px solid #ddd;text-align:center;'><div style='font-size:18px;font-weight:bold;color:#E65100;'>{len(physics_anomalies)}</div><div style='font-size:10px;color:#777;'>مشبوهة</div></div>"
|
| 1470 |
physics_html += f"<div style='background:white;padding:6px 12px;border-radius:8px;border:1px solid #ddd;text-align:center;'><div style='font-size:18px;font-weight:bold;color:#C62828;'>{len(pharma_suspects)}</div><div style='font-size:10px;color:#777;'>بصمة أدوية</div></div>"
|
| 1471 |
physics_html += f"<div style='background:white;padding:6px 12px;border-radius:8px;border:1px solid #ddd;text-align:center;'><div style='font-size:18px;font-weight:bold;color:#6A1B9A;'>{physics_summary.get('max_density_diff',0):.0f}</div><div style='font-size:10px;color:#777;'>فرق كثافة</div></div>"
|
|
@@ -1834,7 +1850,7 @@ with gr.Blocks(title=f"SONAR-AI v{VERSION}") as app:
|
|
| 1834 |
d_refresh.click(refresh_dashboard, outputs=[d_stats, d_tbl])
|
| 1835 |
|
| 1836 |
with gr.Tab("🔬 تحليل الصور"):
|
| 1837 |
-
gr.HTML("<div style='background:#E3F2FD;padding:10px 14px;border-radius:10px;margin-bottom:8px;border-right:4px solid #1565C0;'><b style='color:#1565C0;'>📷 Classification + Detection + HS Codes</b></div>")
|
| 1838 |
with gr.Row():
|
| 1839 |
with gr.Column(scale=1):
|
| 1840 |
a_img = gr.Image(label="📷 صورة الأشعة", type="pil", height=200)
|
|
@@ -1859,11 +1875,13 @@ with gr.Blocks(title=f"SONAR-AI v{VERSION}") as app:
|
|
| 1859 |
btn_contrast = gr.Button("🔆", elem_id="btn_contrast", size="sm", min_width=30)
|
| 1860 |
btn_bright = gr.Button("☀", elem_id="btn_bright", size="sm", min_width=30)
|
| 1861 |
a_dec = gr.Textbox(label="📋 البضاعة المصرّح بها", placeholder="SHOES + FABRIC + ...", lines=1)
|
| 1862 |
-
a_btn = gr.Button("🔍 تحليل شامل", variant="primary", size="lg")
|
| 1863 |
with gr.Column(scale=1):
|
| 1864 |
-
|
| 1865 |
-
|
| 1866 |
-
|
|
|
|
|
|
|
|
|
|
| 1867 |
a_btn.click(analyze_image, inputs=[a_img, a_dec], outputs=[a_res, a_tbl, a_det], api_name="analyze")
|
| 1868 |
btn_gray.click(apply_grayscale, inputs=[a_img], outputs=[a_img])
|
| 1869 |
btn_inv.click(apply_invert, inputs=[a_img], outputs=[a_img])
|
|
|
|
| 792 |
|
| 793 |
overall_mean = np.mean(means)
|
| 794 |
overall_dark = np.mean(darks)
|
| 795 |
+
mean_std = np.std(means) # تباين الكثافة بين المناطق
|
| 796 |
+
dark_std = np.std(darks)
|
| 797 |
+
|
| 798 |
+
# ✅ هل الحاوية متجانسة؟ (كثافة موحدة)
|
| 799 |
+
is_uniform = mean_std < 15 and dark_std < 0.08
|
| 800 |
|
| 801 |
anomalies = {}
|
| 802 |
for r in regions:
|
|
|
|
| 804 |
mean_diff = abs(p['mean'] - overall_mean)
|
| 805 |
dark_diff = abs(p['dark_ratio'] - overall_dark)
|
| 806 |
|
| 807 |
+
# ═══ قواعد الكشف — نسبية وليست مطلقة ═══
|
| 808 |
|
| 809 |
+
# 1. فرق الكثافة عن المتوسط (نسبي لهذه الحاوية)
|
| 810 |
+
density_anomaly = mean_diff > max(25, mean_std * 1.5)
|
| 811 |
|
| 812 |
+
# 2. فرق البكسلات الداكنة (نسبي)
|
| 813 |
+
dark_anomaly = dark_diff > max(0.12, dark_std * 1.5)
|
| 814 |
|
| 815 |
+
# 3. مطابقة بصمة الأدوية — فقط إذا المنطقة مختلفة عن الباقي!
|
| 816 |
+
# ✅ FIX: لا تحكم "أدوية" إذا كل الحاوية متشابهة
|
| 817 |
+
pharma_range_match = (
|
| 818 |
PHARMA_SIGNATURE['mean_range'][0] <= p['mean'] <= PHARMA_SIGNATURE['mean_range'][1] and
|
| 819 |
PHARMA_SIGNATURE['dark_ratio_range'][0] <= p['dark_ratio'] <= PHARMA_SIGNATURE['dark_ratio_range'][1] and
|
| 820 |
PHARMA_SIGNATURE['entropy_range'][0] <= p['entropy'] <= PHARMA_SIGNATURE['entropy_range'][1]
|
| 821 |
)
|
| 822 |
+
# بصمة الأدوية = مطابقة النطاق + اختلاف عن بقية الحاوية
|
| 823 |
+
is_pharma_match = pharma_range_match and (density_anomaly or dark_anomaly) and not is_uniform
|
| 824 |
|
| 825 |
# النتيجة المركّبة
|
| 826 |
score = 0
|
|
|
|
| 853 |
'n_regions': len(regions),
|
| 854 |
'materials_found': materials_found,
|
| 855 |
'has_mixed_cargo': has_mixed,
|
| 856 |
+
'is_uniform': is_uniform,
|
| 857 |
+
'density_variation': mean_std,
|
| 858 |
'n_anomalies': len(anomalies),
|
| 859 |
'pharma_suspects': len(pharma_suspects),
|
| 860 |
'overall_mean': overall_mean,
|
|
|
|
| 1474 |
physics_html += f"<div style='background:{p_color};color:white;padding:8px 12px;border-radius:8px;text-align:center;font-weight:bold;margin-bottom:8px;font-size:13px;'>🔬 التحليل الفيزيائي للكثافة (PBDAD) — {p_text}</div>"
|
| 1475 |
|
| 1476 |
# ملخص أرقام
|
| 1477 |
+
is_uniform = physics_summary.get('is_uniform', False)
|
| 1478 |
+
density_var = physics_summary.get('density_variation', 0)
|
| 1479 |
+
uniform_txt = "✅ متجانسة" if is_uniform else "⚠️ غير متجانسة"
|
| 1480 |
+
uniform_clr = "#2E7D32" if is_uniform else "#E65100"
|
| 1481 |
+
|
| 1482 |
physics_html += f"<div style='display:flex;gap:6px;margin-bottom:8px;flex-wrap:wrap;justify-content:center;'>"
|
| 1483 |
physics_html += f"<div style='background:white;padding:6px 12px;border-radius:8px;border:1px solid #ddd;text-align:center;'><div style='font-size:18px;font-weight:bold;color:#1565C0;'>{physics_summary.get('n_regions',0)}</div><div style='font-size:10px;color:#777;'>مناطق</div></div>"
|
| 1484 |
+
physics_html += f"<div style='background:white;padding:6px 12px;border-radius:8px;border:1px solid {uniform_clr};text-align:center;'><div style='font-size:14px;font-weight:bold;color:{uniform_clr};'>{uniform_txt}</div><div style='font-size:10px;color:#777;'>تباين: {density_var:.1f}</div></div>"
|
| 1485 |
physics_html += f"<div style='background:white;padding:6px 12px;border-radius:8px;border:1px solid #ddd;text-align:center;'><div style='font-size:18px;font-weight:bold;color:#E65100;'>{len(physics_anomalies)}</div><div style='font-size:10px;color:#777;'>مشبوهة</div></div>"
|
| 1486 |
physics_html += f"<div style='background:white;padding:6px 12px;border-radius:8px;border:1px solid #ddd;text-align:center;'><div style='font-size:18px;font-weight:bold;color:#C62828;'>{len(pharma_suspects)}</div><div style='font-size:10px;color:#777;'>بصمة أدوية</div></div>"
|
| 1487 |
physics_html += f"<div style='background:white;padding:6px 12px;border-radius:8px;border:1px solid #ddd;text-align:center;'><div style='font-size:18px;font-weight:bold;color:#6A1B9A;'>{physics_summary.get('max_density_diff',0):.0f}</div><div style='font-size:10px;color:#777;'>فرق كثافة</div></div>"
|
|
|
|
| 1850 |
d_refresh.click(refresh_dashboard, outputs=[d_stats, d_tbl])
|
| 1851 |
|
| 1852 |
with gr.Tab("🔬 تحليل الصور"):
|
| 1853 |
+
gr.HTML("<div style='background:#E3F2FD;padding:10px 14px;border-radius:10px;margin-bottom:8px;border-right:4px solid #1565C0;'><b style='color:#1565C0;'>📷 Classification + Detection + Physics Density Analysis + HS Codes</b></div>")
|
| 1854 |
with gr.Row():
|
| 1855 |
with gr.Column(scale=1):
|
| 1856 |
a_img = gr.Image(label="📷 صورة الأشعة", type="pil", height=200)
|
|
|
|
| 1875 |
btn_contrast = gr.Button("🔆", elem_id="btn_contrast", size="sm", min_width=30)
|
| 1876 |
btn_bright = gr.Button("☀", elem_id="btn_bright", size="sm", min_width=30)
|
| 1877 |
a_dec = gr.Textbox(label="📋 البضاعة المصرّح بها", placeholder="SHOES + FABRIC + ...", lines=1)
|
|
|
|
| 1878 |
with gr.Column(scale=1):
|
| 1879 |
+
a_det = gr.Image(label="📍 التحليل الفيزيائي / Detection", type="pil", height=250)
|
| 1880 |
+
# ✅ زر التحليل بعرض كامل
|
| 1881 |
+
a_btn = gr.Button("🔍 تحليل شامل — Classification + Detection + Physics Density", variant="primary", size="lg")
|
| 1882 |
+
# ✅ النتائج أسفل الزر بعرض كامل
|
| 1883 |
+
a_res = gr.HTML("<div style='text-align:center;padding:30px;color:#999;direction:rtl;'>📷 ارفع صورة للبدء</div>")
|
| 1884 |
+
a_tbl = gr.Dataframe(label="📋 الأصناف + HS + الرسوم", value=pd.DataFrame(), wrap=True)
|
| 1885 |
a_btn.click(analyze_image, inputs=[a_img, a_dec], outputs=[a_res, a_tbl, a_det], api_name="analyze")
|
| 1886 |
btn_gray.click(apply_grayscale, inputs=[a_img], outputs=[a_img])
|
| 1887 |
btn_inv.click(apply_invert, inputs=[a_img], outputs=[a_img])
|