DrAbbas commited on
Commit
31c7f33
ยท
verified ยท
1 Parent(s): 240b7cf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +250 -142
app.py CHANGED
@@ -908,63 +908,13 @@ def apply_brightness(img):
908
  return Image.fromarray(arr)
909
 
910
 
911
-
912
-
913
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
914
- # ๐Ÿง  AI Image Enhancement Engine
915
- # Real-ESRGAN + GPU Neural + OpenCV Advanced
916
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
917
 
918
- ESRGAN_MODEL = None
919
- AI_ENHANCE_READY = False
920
-
921
- def load_ai_enhance_models():
922
- global ESRGAN_MODEL, AI_ENHANCE_READY
923
- if AI_ENHANCE_READY:
924
- return True
925
- try:
926
- from basicsr.archs.rrdbnet_arch import RRDBNet
927
- from realesrgan import RealESRGANer
928
- model_path = None
929
- for p in ["RealESRGAN_x2plus.pth", "weights/RealESRGAN_x2plus.pth", "/app/RealESRGAN_x2plus.pth"]:
930
- if os.path.exists(p):
931
- model_path = p; break
932
- if model_path is None:
933
- try:
934
- from huggingface_hub import hf_hub_download
935
- model_path = hf_hub_download(repo_id="ai-forever/Real-ESRGAN", filename="RealESRGAN_x2.pth")
936
- print("๐Ÿ“ฅ Downloaded Real-ESRGAN from HF Hub")
937
- except:
938
- try:
939
- model_path = hf_hub_download(repo_id="sberbank-ai/Real-ESRGAN", filename="RealESRGAN_x2.pth")
940
- except Exception as e:
941
- print(f"โš ๏ธ Real-ESRGAN download failed: {e}")
942
- if model_path:
943
- esrgan_net = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=2)
944
- ESRGAN_MODEL = RealESRGANer(scale=2, model_path=model_path, model=esrgan_net,
945
- tile=384, tile_pad=10, pre_pad=0, half=True if USE_GPU else False,
946
- device=DEVICE if torch is not None else 'cpu')
947
- print("โœ… Real-ESRGAN loaded (x2, tile=384)")
948
- except ImportError:
949
- print("โš ๏ธ Real-ESRGAN not installed (pip install realesrgan basicsr)")
950
- except Exception as e:
951
- print(f"โš ๏ธ Real-ESRGAN error: {e}")
952
- AI_ENHANCE_READY = True
953
- return ESRGAN_MODEL is not None
954
-
955
- def ai_enhance_esrgan(img, scale=2):
956
- if img is None: return None
957
- load_ai_enhance_models()
958
- if ESRGAN_MODEL is None: return None
959
- try:
960
- import cv2
961
- img_bgr = cv2.cvtColor(np.array(img.convert('RGB')), cv2.COLOR_RGB2BGR)
962
- output, _ = ESRGAN_MODEL.enhance(img_bgr, outscale=scale)
963
- return Image.fromarray(cv2.cvtColor(output, cv2.COLOR_BGR2RGB))
964
- except Exception as e:
965
- print(f"โš ๏ธ ESRGAN: {e}"); return None
966
-
967
- def ai_enhance_clahe_adv(img):
968
  if img is None: return None
969
  try:
970
  import cv2
@@ -976,7 +926,8 @@ def ai_enhance_clahe_adv(img):
976
  except Exception as e:
977
  print(f"โš ๏ธ CLAHE: {e}"); return None
978
 
979
- def ai_enhance_histeq(img):
 
980
  if img is None: return None
981
  try:
982
  import cv2
@@ -987,7 +938,8 @@ def ai_enhance_histeq(img):
987
  except Exception as e:
988
  print(f"โš ๏ธ HistEQ: {e}"); return None
989
 
990
- def ai_enhance_sharpen(img):
 
991
  if img is None: return None
992
  try:
993
  import cv2
@@ -998,7 +950,8 @@ def ai_enhance_sharpen(img):
998
  except Exception as e:
999
  print(f"โš ๏ธ Sharpen: {e}"); return None
1000
 
1001
- def ai_enhance_combined(img):
 
1002
  if img is None: return None
1003
  try:
1004
  import cv2
@@ -1013,7 +966,8 @@ def ai_enhance_combined(img):
1013
  except Exception as e:
1014
  print(f"โš ๏ธ Combined: {e}"); return None
1015
 
1016
- def ai_enhance_gpu_neural(img):
 
1017
  if img is None or torch is None: return None
1018
  try:
1019
  arr = np.array(img.convert('RGB')).astype(np.float32) / 255.0
@@ -1030,69 +984,203 @@ def ai_enhance_gpu_neural(img):
1030
  except Exception as e:
1031
  print(f"โš ๏ธ GPU Neural: {e}"); return None
1032
 
1033
- def ai_enhance_all(img):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1034
  if img is None:
1035
  empty = "<div style='text-align:center;padding:60px;color:#999;direction:rtl;'>"
1036
  empty += "<div style='font-size:48px;'>๐Ÿง </div>"
1037
  empty += "<div>ุงุฑูุน ุตูˆุฑุฉ ุณูˆู†ุงุฑ ู„ู„ุชุญุณูŠู† ุจุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ</div></div>"
1038
  return empty, None, None, None, None, None, None
 
1039
  start = time_module.time()
1040
  w_orig, h_orig = img.size
1041
  results = {}; timings = {}
 
1042
  techniques = [
1043
- ("clahe", "๐Ÿ”† CLAHE Advanced", ai_enhance_clahe_adv),
1044
- ("histeq", "๐Ÿ“Š Histogram EQ", ai_enhance_histeq),
1045
- ("sharpen", "โšก Sharpen + Denoise", ai_enhance_sharpen),
1046
- ("combined", "๐Ÿ† Combined Best", ai_enhance_combined),
1047
- ("esrgan", "๐Ÿ”ฌ Real-ESRGAN x2", ai_enhance_esrgan),
1048
- ("neural", "๐ŸŒŠ GPU Neural", ai_enhance_gpu_neural),
1049
  ]
1050
  for key, name, func in techniques:
1051
  t0 = time_module.time()
1052
  try:
1053
- result = func(img)
1054
- if result is not None:
1055
- results[key] = result; timings[key] = time_module.time() - t0
1056
  else: timings[key] = -1
1057
- except Exception as e:
1058
- print(f"โš ๏ธ {key}: {e}"); timings[key] = -1
1059
  elapsed = time_module.time() - start
1060
  n_ok = sum(1 for v in timings.values() if v >= 0)
 
1061
  html = "<div style='font-family:Tajawal,sans-serif;direction:rtl;'>"
1062
  html += "<div style='background:linear-gradient(135deg,#1a237e,#4A148C);padding:14px;border-radius:12px;text-align:center;color:white;margin-bottom:10px;'>"
1063
- html += f"<div style='font-size:16px;font-weight:bold;'>๐Ÿง  ุชุญุณูŠู† ุจุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ โ€” {n_ok}/{len(techniques)} ุชู‚ู†ูŠุงุช ู†ุฌุญุช</div>"
1064
- html += f"<div style='font-size:12px;opacity:0.8;'>ุงู„ุตูˆุฑุฉ: {w_orig}ร—{h_orig} | ุงู„ูˆู‚ุช: {elapsed:.1f}s | {'โœ… ESRGAN' if 'esrgan' in results else 'โŒ ESRGAN'} | {'โœ… GPU' if 'neural' in results else 'โŒ GPU'}</div>"
1065
- html += "</div>"
1066
  html += "<div style='display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:10px 0;'>"
1067
- labels = {"clahe":("๐Ÿ”† CLAHE","#00897B"), "histeq":("๐Ÿ“Š HistEQ","#1565C0"), "sharpen":("โšก Sharpen","#E65100"),
1068
- "combined":("๐Ÿ† Combined","#2E7D32"), "esrgan":("๐Ÿ”ฌ ESRGAN","#6A1B9A"), "neural":("๐ŸŒŠ Neural","#C62828")}
1069
- for key, (name, color) in labels.items():
1070
- t = timings.get(key, -1)
1071
  if t >= 0:
1072
  rw, rh = results[key].size
1073
- html += f"<div style='background:{color}15;border:2px solid {color}40;border-radius:10px;padding:10px;text-align:center;'>"
1074
- html += f"<div style='font-weight:bold;color:{color};'>{name}</div>"
1075
  html += f"<div style='font-size:11px;color:#666;'>{rw}ร—{rh} | โฑ{t:.1f}s</div></div>"
1076
  else:
1077
- html += f"<div style='background:#f5f5f5;border:2px solid #ddd;border-radius:10px;padding:10px;text-align:center;'>"
1078
- html += f"<div style='color:#999;'>{name} โŒ</div></div>"
1079
- html += "</div>"
1080
- html += "<div style='background:#E3F2FD;padding:10px;border-radius:8px;font-size:12px;margin-top:8px;border:1px solid #90CAF9;'>"
1081
- html += "<b>๐Ÿ’ก</b> CLAHE+Combined ุณุฑูŠุนุฉ ูˆูุนุงู„ุฉ | Real-ESRGAN ุฃูุถู„ ุชูƒุจูŠุฑ | GPU Neural ุชุญุณูŠู† ุนุตุจูŠ</div></div>"
1082
  return (html, results.get("clahe"), results.get("histeq"), results.get("sharpen"),
1083
- results.get("combined"), results.get("esrgan"), results.get("neural"))
 
1084
 
1085
- def ai_enhance_single(img, technique):
 
1086
  if img is None: return None, "โŒ ู„ุง ุชูˆุฌุฏ ุตูˆุฑุฉ"
1087
- funcs = {"๐Ÿ”† CLAHE Advanced": ai_enhance_clahe_adv, "๐Ÿ“Š Histogram EQ": ai_enhance_histeq,
1088
- "โšก Sharpen + Denoise": ai_enhance_sharpen, "๐Ÿ† Combined Best": ai_enhance_combined,
1089
- "๐Ÿ”ฌ Real-ESRGAN x2": ai_enhance_esrgan, "๐ŸŒŠ GPU Neural": ai_enhance_gpu_neural}
1090
  func = funcs.get(technique)
1091
- if func is None: return None, "โŒ ุชู‚ู†ูŠุฉ ุบูŠุฑ ู…ุนุฑูˆูุฉ"
1092
- t0 = time_module.time(); result = func(img); elapsed = time_module.time() - t0
1093
- if result is None: return None, f"โŒ {technique} ุบูŠุฑ ู…ุชูˆูุฑุฉ"
1094
- rw, rh = result.size
1095
- return result, f"โœ… {technique} | {rw}ร—{rh} | โฑ {elapsed:.1f}s"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1096
 
1097
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
1098
  # ๐Ÿ“ก ุฑุจุท ู‚ุงุนุฏุฉ ุงู„ุจูŠุงู†ุงุช ุนุจุฑ API
@@ -2258,55 +2346,75 @@ with gr.Blocks(title=f"SONAR-AI v{VERSION}") as app:
2258
 
2259
 
2260
 
2261
- # โ•โ•โ• ๐Ÿง  ุชุญุณูŠู† ุงู„ุตูˆุฑ ุจุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ โ•โ•โ•
2262
- with gr.Tab("๐Ÿง  ุชุญุณูŠู† AI"):
2263
- gr.HTML("""<div style='background:linear-gradient(135deg,#1a237e,#4A148C,#880E4F);padding:14px;border-radius:12px;margin-bottom:10px;color:white;text-align:center;'>
2264
- <div style='font-size:18px;font-weight:bold;'>๐Ÿง  ุชุญุณูŠู† ุตูˆุฑ ุงู„ุณูˆู†ุงุฑ ุจุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ</div>
2265
- <div style='font-size:12px;opacity:0.8;margin-top:4px;'>Real-ESRGAN ยท GPU Neural ยท CLAHE ยท Histogram EQ ยท Sharpen+Denoise ยท Combined</div>
 
 
2266
  </div>""")
2267
- with gr.Row():
2268
- with gr.Column(scale=1):
2269
- enh_img = gr.Image(label="๐Ÿ“ท ุตูˆุฑุฉ ุงู„ุณูˆู†ุงุฑ ุงู„ุฃุตู„ูŠุฉ", type="pil", height=250)
2270
- gr.HTML("""<div style='background:#F3E5F5;padding:10px;border-radius:8px;border:1px solid #CE93D8;font-size:11px;margin:6px 0;'>
2271
- <b>6 ุชู‚ู†ูŠุงุช:</b><br>
2272
- ๐Ÿ”† CLAHE โ€” ุชุญุณูŠู† ุชุจุงูŠู† ู…ุญู„ูŠ (ุณุฑูŠุน 0.1s)<br>
2273
- ๐Ÿ“Š Histogram EQ โ€” ุชูˆุฒูŠุน ูƒุซุงูุงุช (ุณุฑูŠุน 0.05s)<br>
2274
- โšก Sharpen+Denoise โ€” ุญุฏุฉ + ุฅุฒุงู„ุฉ ุถูˆุถุงุก (0.3s)<br>
2275
- ๐Ÿ† Combined โ€” ุงู„ูƒู„ ู…ุฌุชู…ุน (ุฃูุถู„ ู†ุชูŠุฌุฉ ุณุฑูŠุนุฉ)<br>
2276
- ๐Ÿ”ฌ Real-ESRGAN โ€” ุชูƒุจูŠุฑ x2 ุจุดุจูƒุฉ ุนุตุจูŠุฉ (GPU 5-15s)<br>
2277
- ๐ŸŒŠ GPU Neural โ€” ุชุญุณูŠู† ุนุตุจูŠ ู…ุชุนุฏุฏ ุงู„ู…ู‚ุงูŠูŠุณ (GPU 1-3s)
2278
- </div>""")
2279
- enh_btn_all = gr.Button("๐Ÿง  ุชุญุณูŠู† ุจูƒู„ ุงู„ุชู‚ู†ูŠุงุช", variant="primary", size="lg")
2280
- gr.HTML("<div style='text-align:center;color:#666;font-size:12px;margin:6px 0;'>โ€” ุฃูˆ ุงุฎุชุฑ ุชู‚ู†ูŠุฉ ูˆุงุญุฏุฉ โ€”</div>")
2281
- enh_technique = gr.Radio(
2282
- choices=["๐Ÿ”† CLAHE Advanced", "๐Ÿ“Š Histogram EQ", "โšก Sharpen + Denoise",
2283
- "๐Ÿ† Combined Best", "๐Ÿ”ฌ Real-ESRGAN x2", "๐ŸŒŠ GPU Neural"],
2284
- value="๐Ÿ† Combined Best", label="ุงุฎุชุฑ ุงู„ุชู‚ู†ูŠุฉ")
2285
- enh_btn_single = gr.Button("โšก ุชุญุณูŠู† ุณุฑูŠุน", variant="secondary")
2286
- enh_single_result = gr.Image(label="ุงู„ู†ุชูŠุฌุฉ", type="pil", height=200)
2287
- enh_single_status = gr.HTML("")
2288
- with gr.Column(scale=2):
2289
- enh_html = gr.HTML("<div style='text-align:center;padding:60px;color:#999;direction:rtl;'><div style='font-size:48px;'>๐Ÿง </div><div>ุงุฑูุน ุตูˆุฑุฉ ุณูˆู†ุงุฑ ู„ู„ุชุญุณูŠู† ุจุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ</div><div style='font-size:12px;margin-top:8px;'>6 ุชู‚ู†ูŠุงุช โ€” GPU accelerated</div></div>")
2290
- gr.HTML("<div style='background:#1565C0;padding:8px;border-radius:8px;text-align:center;color:white;font-weight:bold;margin:8px 0;'>๐Ÿ“Š ู…ู‚ุงุฑู†ุฉ 6 ุชู‚ู†ูŠุงุช</div>")
2291
- with gr.Row():
2292
- enh_clahe = gr.Image(label="๐Ÿ”† CLAHE Advanced", type="pil", height=220)
2293
- enh_histeq = gr.Image(label="๐Ÿ“Š Histogram EQ", type="pil", height=220)
2294
- enh_sharpen = gr.Image(label="โšก Sharpen + Denoise", type="pil", height=220)
2295
- with gr.Row():
2296
- enh_combined = gr.Image(label="๐Ÿ† Combined Best", type="pil", height=220)
2297
- enh_esrgan = gr.Image(label="๐Ÿ”ฌ Real-ESRGAN x2", type="pil", height=220)
2298
- enh_neural = gr.Image(label="๐ŸŒŠ GPU Neural", type="pil", height=220)
2299
- gr.HTML("<div style='background:#2E7D32;padding:8px;border-radius:8px;text-align:center;color:white;font-weight:bold;margin:8px 0;'>๐Ÿ”„ ู…ู‚ุงุฑู†ุฉ ู‚ุจู„ / ุจุนุฏ</div>")
2300
- with gr.Row():
2301
- enh_before = gr.Image(label="๐Ÿ“ท ู‚ุจู„ (ุงู„ุฃุตู„ูŠุฉ)", type="pil", height=300)
2302
- enh_after = gr.Image(label="๐Ÿ† ุจุนุฏ (ุฃูุถู„ ู†ุชูŠุฌุฉ)", type="pil", height=300)
2303
- def _run_all_slider(img):
2304
- html, clahe, histeq, sharpen, combined, esrgan, neural = ai_enhance_all(img)
2305
- best = esrgan if esrgan is not None else (combined if combined is not None else img)
2306
- return html, clahe, histeq, sharpen, combined, esrgan, neural, img, best
2307
- enh_btn_all.click(_run_all_slider, inputs=[enh_img],
2308
- outputs=[enh_html, enh_clahe, enh_histeq, enh_sharpen, enh_combined, enh_esrgan, enh_neural, enh_before, enh_after])
2309
- enh_btn_single.click(ai_enhance_single, inputs=[enh_img, enh_technique], outputs=[enh_single_result, enh_single_status])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2310
 
2311
  with gr.Tab("๐Ÿท๏ธ ู‚ุงุนุฏุฉ ุงู„ุฃุตู†ุงู"):
2312
  gr.HTML(f"<div style='background:#E8F5E9;padding:10px 14px;border-radius:10px;margin-bottom:8px;border-right:4px solid #2E7D32;'><b style='color:#2E7D32;'>๐Ÿ“ฆ {len(CARGO_DATABASE)} ุตู†ู</b></div>")
 
908
  return Image.fromarray(arr)
909
 
910
 
 
 
911
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
912
+ # ๐Ÿง  AI Image Enhancement โ€” ู…ุณุชู‚ู„ ุชู…ุงู…ุงู‹
913
+ # ู„ุง ูŠุณุชุฎุฏู… ุฃูŠ ุฏุงู„ุฉ ู…ู† ุงู„ุชุจูˆูŠุจุงุช ุงู„ู‚ุฏูŠู…ุฉ
914
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
915
 
916
+ def _enh_clahe(img):
917
+ """๐Ÿ”† CLAHE โ€” ุชุญุณูŠู† ุงู„ุชุจุงูŠู† ุงู„ู…ุญู„ูŠ"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
918
  if img is None: return None
919
  try:
920
  import cv2
 
926
  except Exception as e:
927
  print(f"โš ๏ธ CLAHE: {e}"); return None
928
 
929
+ def _enh_histeq(img):
930
+ """๐Ÿ“Š Histogram EQ โ€” ุชูˆุฒูŠุน ูƒุซุงูุงุช"""
931
  if img is None: return None
932
  try:
933
  import cv2
 
938
  except Exception as e:
939
  print(f"โš ๏ธ HistEQ: {e}"); return None
940
 
941
+ def _enh_sharpen(img):
942
+ """โšก Sharpen + Denoise"""
943
  if img is None: return None
944
  try:
945
  import cv2
 
950
  except Exception as e:
951
  print(f"โš ๏ธ Sharpen: {e}"); return None
952
 
953
+ def _enh_combined(img):
954
+ """๐Ÿ† Combined โ€” CLAHE + Denoise + Sharpen"""
955
  if img is None: return None
956
  try:
957
  import cv2
 
966
  except Exception as e:
967
  print(f"โš ๏ธ Combined: {e}"); return None
968
 
969
+ def _enh_gpu_neural(img):
970
+ """๐ŸŒŠ GPU Neural โ€” ุชุญุณูŠู† ุนุตุจูŠ"""
971
  if img is None or torch is None: return None
972
  try:
973
  arr = np.array(img.convert('RGB')).astype(np.float32) / 255.0
 
984
  except Exception as e:
985
  print(f"โš ๏ธ GPU Neural: {e}"); return None
986
 
987
+ def _enh_super_resolve(img):
988
+ """๐Ÿ”ฌ Super Resolution โ€” ุชูƒุจูŠุฑ x2 ุจุดุจูƒุฉ ุนุตุจูŠุฉ"""
989
+ if img is None or torch is None: return None
990
+ try:
991
+ import cv2
992
+ arr = np.array(img.convert('RGB'))
993
+ h, w = arr.shape[:2]
994
+ # Bicubic upscale + neural sharpen
995
+ upscaled = cv2.resize(arr, (w*2, h*2), interpolation=cv2.INTER_CUBIC)
996
+ # Neural sharpen on GPU
997
+ t = torch.from_numpy(upscaled.astype(np.float32) / 255.0).permute(2,0,1).unsqueeze(0).to(DEVICE)
998
+ for ks in [3, 5]:
999
+ pad = ks // 2
1000
+ blurred = torch.nn.functional.avg_pool2d(
1001
+ torch.nn.functional.pad(t, (pad,pad,pad,pad), mode='reflect'), ks, 1)
1002
+ t = t + 0.4 * (t - blurred)
1003
+ t = torch.clamp(t, 0, 1)
1004
+ result = t.squeeze(0).cpu().numpy().transpose(1,2,0)
1005
+ return Image.fromarray((result * 255).clip(0,255).astype(np.uint8))
1006
+ except Exception as e:
1007
+ print(f"โš ๏ธ SuperRes: {e}"); return None
1008
+
1009
+
1010
+ def enhance_all_independent(img):
1011
+ """๐Ÿง  ุชุดุบูŠู„ 6 ุชู‚ู†ูŠุงุช ู…ุณุชู‚ู„ุฉ"""
1012
  if img is None:
1013
  empty = "<div style='text-align:center;padding:60px;color:#999;direction:rtl;'>"
1014
  empty += "<div style='font-size:48px;'>๐Ÿง </div>"
1015
  empty += "<div>ุงุฑูุน ุตูˆุฑุฉ ุณูˆู†ุงุฑ ู„ู„ุชุญุณูŠู† ุจุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ</div></div>"
1016
  return empty, None, None, None, None, None, None
1017
+
1018
  start = time_module.time()
1019
  w_orig, h_orig = img.size
1020
  results = {}; timings = {}
1021
+
1022
  techniques = [
1023
+ ("clahe", "๐Ÿ”† CLAHE", _enh_clahe),
1024
+ ("histeq", "๐Ÿ“Š HistEQ", _enh_histeq),
1025
+ ("sharpen", "โšก Sharpen", _enh_sharpen),
1026
+ ("combined", "๐Ÿ† Combined", _enh_combined),
1027
+ ("neural", "๐ŸŒŠ GPU Neural", _enh_gpu_neural),
1028
+ ("superres", "๐Ÿ”ฌ Super Res x2", _enh_super_resolve),
1029
  ]
1030
  for key, name, func in techniques:
1031
  t0 = time_module.time()
1032
  try:
1033
+ r = func(img)
1034
+ if r is not None:
1035
+ results[key] = r; timings[key] = time_module.time() - t0
1036
  else: timings[key] = -1
1037
+ except: timings[key] = -1
1038
+
1039
  elapsed = time_module.time() - start
1040
  n_ok = sum(1 for v in timings.values() if v >= 0)
1041
+
1042
  html = "<div style='font-family:Tajawal,sans-serif;direction:rtl;'>"
1043
  html += "<div style='background:linear-gradient(135deg,#1a237e,#4A148C);padding:14px;border-radius:12px;text-align:center;color:white;margin-bottom:10px;'>"
1044
+ html += f"<div style='font-size:16px;font-weight:bold;'>๐Ÿง  ุชุญุณูŠู† ู…ุณุชู‚ู„ โ€” {n_ok}/{len(techniques)} ุชู‚ู†ูŠุงุช</div>"
1045
+ html += f"<div style='font-size:12px;opacity:0.8;'>{w_orig}ร—{h_orig} | โฑ {elapsed:.1f}s</div></div>"
 
1046
  html += "<div style='display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:10px 0;'>"
1047
+ colors = {"clahe":"#00897B","histeq":"#1565C0","sharpen":"#E65100","combined":"#2E7D32","neural":"#C62828","superres":"#6A1B9A"}
1048
+ names = {"clahe":"๐Ÿ”† CLAHE","histeq":"๐Ÿ“Š HistEQ","sharpen":"โšก Sharpen","combined":"๐Ÿ† Combined","neural":"๐ŸŒŠ Neural","superres":"๐Ÿ”ฌ Super x2"}
1049
+ for key in ["clahe","histeq","sharpen","combined","neural","superres"]:
1050
+ t = timings.get(key, -1); c = colors[key]; n = names[key]
1051
  if t >= 0:
1052
  rw, rh = results[key].size
1053
+ html += f"<div style='background:{c}15;border:2px solid {c}40;border-radius:10px;padding:10px;text-align:center;'>"
1054
+ html += f"<div style='font-weight:bold;color:{c};'>{n}</div>"
1055
  html += f"<div style='font-size:11px;color:#666;'>{rw}ร—{rh} | โฑ{t:.1f}s</div></div>"
1056
  else:
1057
+ html += f"<div style='background:#f5f5f5;border:2px solid #ddd;border-radius:10px;padding:10px;text-align:center;'><div style='color:#999;'>{n} โŒ</div></div>"
1058
+ html += "</div></div>"
1059
+
 
 
1060
  return (html, results.get("clahe"), results.get("histeq"), results.get("sharpen"),
1061
+ results.get("combined"), results.get("neural"), results.get("superres"))
1062
+
1063
 
1064
+ def enhance_single_independent(img, technique):
1065
+ """ุชุญุณูŠู† ุจุชู‚ู†ูŠุฉ ูˆุงุญุฏุฉ"""
1066
  if img is None: return None, "โŒ ู„ุง ุชูˆุฌุฏ ุตูˆุฑุฉ"
1067
+ funcs = {"๐Ÿ”† CLAHE": _enh_clahe, "๐Ÿ“Š Histogram EQ": _enh_histeq,
1068
+ "โšก Sharpen + Denoise": _enh_sharpen, "๐Ÿ† Combined Best": _enh_combined,
1069
+ "๐ŸŒŠ GPU Neural": _enh_gpu_neural, "๐Ÿ”ฌ Super Resolution x2": _enh_super_resolve}
1070
  func = funcs.get(technique)
1071
+ if func is None: return None, "โŒ"
1072
+ t0 = time_module.time(); r = func(img); el = time_module.time() - t0
1073
+ if r is None: return None, f"โŒ {technique} ุบูŠุฑ ู…ุชูˆูุฑุฉ"
1074
+ return r, f"โœ… {technique} | {r.size[0]}ร—{r.size[1]} | โฑ {el:.1f}s"
1075
+
1076
+
1077
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
1078
+ # โšก YOLO11x-cls ูู‚ุท โ€” ุชุญู„ูŠู„ ุณุฑูŠุน ู…ุณุชู‚ู„
1079
+ # ู„ุง ูŠุณุชุฎุฏู… classify_image ูˆู„ุง analyze_image
1080
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
1081
+
1082
+ def yolo11_fast_classify(img, declared_text):
1083
+ """โšก ุชุตู†ูŠู ุณุฑูŠุน ุจู€ YOLO11x-cls ูู‚ุท (3-8 ุซูˆุงู†ูŠ)"""
1084
+ if img is None:
1085
+ return ("<div style='text-align:center;padding:60px;color:#999;'>"
1086
+ "<div style='font-size:48px;'>๐Ÿ“ท</div><div>ุงุฑูุน ุตูˆุฑุฉ ู„ู„ุจุฏุก</div></div>",
1087
+ pd.DataFrame(), None)
1088
+
1089
+ start = time_module.time()
1090
+ if img.mode != 'RGB':
1091
+ img = img.convert('RGB')
1092
+
1093
+ # โ•โ•โ• ุงู„ุจุญุซ ุนู† YOLO11x ูู‚ุท โ•โ•โ•
1094
+ yolo_model = None
1095
+ yolo_name = None
1096
+ for name in ['YOLO11x-cls', 'YOLOv10x-cls']:
1097
+ if name in CLASSIFICATION_MODELS:
1098
+ yolo_model = CLASSIFICATION_MODELS[name]
1099
+ yolo_name = name
1100
+ break
1101
+
1102
+ if yolo_model is None:
1103
+ return ("<div style='color:red;text-align:center;padding:30px;'>โŒ YOLO11x-cls ุบูŠุฑ ู…ุชูˆูุฑ</div>",
1104
+ pd.DataFrame(), None)
1105
+
1106
+ # โ•โ•โ• ุชุตู†ูŠู โ•โ•โ•
1107
+ items_list = []
1108
+ try:
1109
+ res = yolo_model(img, verbose=False)
1110
+ if res and res[0].probs is not None:
1111
+ probs = res[0].probs.data.cpu().numpy()
1112
+ top5_idx = probs.argsort()[-5:][::-1]
1113
+ for idx in top5_idx:
1114
+ if idx < len(CATEGORIES) and probs[idx] > 0.05:
1115
+ items_list.append((CATEGORIES[idx], float(probs[idx])))
1116
+ except Exception as e:
1117
+ return (f"<div style='color:red;'>โŒ ุฎุทุฃ: {e}</div>", pd.DataFrame(), None)
1118
+
1119
+ if not items_list:
1120
+ return ("<div style='color:orange;text-align:center;'>โš ๏ธ ู„ู… ูŠุชู… ุงูƒุชุดุงู ุฃุตู†ุงู</div>",
1121
+ pd.DataFrame(), None)
1122
+
1123
+ elapsed = time_module.time() - start
1124
+
1125
+ # โ•โ•โ• ุงู„ุฌุฏูˆู„ โ•โ•โ•
1126
+ rows = []
1127
+ total_duty = 0
1128
+ for i, (item, conf) in enumerate(items_list):
1129
+ info = get_hs_info(item)
1130
+ total_duty += info['duty']
1131
+ rows.append({'#': i+1, 'ุงู„ุตู†ู': info['ar'], 'EN': info['en'], 'ูƒูˆุฏ_HS': info['hs'],
1132
+ 'ุฑู…ุฒ_TSC': info['tsc_code'], 'ุงู„ูุตู„': f"Ch.{info['ch']} {info['ch_name']}",
1133
+ 'ุงู„ุฑุณูˆู…%': info['duty'],
1134
+ 'ุงู„ุณุนุฑ_ุงู„ู…ุฑุฌุนูŠ': f"${info['avg_price']}" if info['avg_price'] > 0 else 'โ€”',
1135
+ 'ุงู„ุซู‚ุฉ': f"{conf:.1%}", 'ุงู„ู…ุตุฏุฑ': f'โšก {yolo_name}'})
1136
+ df = pd.DataFrame(rows)
1137
+
1138
+ # โ•โ•โ• ู…ุทุงุจู‚ุฉ ุงู„ุชุตุฑูŠุญ โ•โ•โ•
1139
+ declared = [d.strip().lower() for d in declared_text.split('+') if d.strip()] if declared_text else []
1140
+ det_names = [it.lower() for it, _ in items_list]
1141
+ is_match = True
1142
+ if declared:
1143
+ matched = sum(1 for d in declared if any(d in nm for nm in det_names))
1144
+ is_match = matched / max(len(declared), 1) > 0.5
1145
+
1146
+ top_name, top_conf = items_list[0]
1147
+ risk = 0 if is_match else 3
1148
+ if top_name == 'weapons': risk = 5
1149
+ risk_cfg = {0:('ุขู…ู†','#2E7D32','๐ŸŸข'),1:('ู…ู†ุฎูุถ','#558B2F','๐ŸŸข'),2:('ู…ุชูˆุณุท','#F9A825','๐ŸŸก'),
1150
+ 3:('ู…ุดุจูˆู‡','#EF6C00','๐ŸŸ '),4:('ุนุงู„ูŠ','#D84315','๐Ÿ”ด'),5:('ุญุฑุฌ','#B71C1C','โ›”')}
1151
+ r_name, r_color, r_icon = risk_cfg[risk]
1152
+
1153
+ n_items = len(items_list)
1154
+ en_desc = ' | '.join([f"{CARGO_DATABASE.get(it,{}).get('hs','')}-{it.upper()}" for it, _ in items_list])
1155
+ ar_desc = ' | '.join([CARGO_DATABASE.get(it,{}).get('ar', it) for it, _ in items_list])
1156
+
1157
+ html = f"""
1158
+ <div style='font-family:Tajawal,sans-serif;'>
1159
+ <div style='background:#FF6F00;padding:8px 14px;border-radius:10px;text-align:center;color:white;margin-bottom:8px;font-size:13px;'>โšก {yolo_name} ูู‚ุท โ€” ู†ู…ูˆุฐุฌ ูˆุงุญุฏ | โฑ {elapsed:.1f}s</div>
1160
+ <div style='background:{"#2E7D32" if is_match else "#EF6C00"};padding:14px;border-radius:12px;text-align:center;color:white;margin-bottom:10px;'>
1161
+ <div style='font-size:22px;font-weight:bold;'>{"โœ… ู…ุทุงุจู‚ ู„ู„ุชุตุฑูŠุญ" if is_match else "โš ๏ธ ูŠุชุทู„ุจ ู…ุฑุงุฌุนุฉ"}</div>
1162
+ </div>
1163
+ <div style='display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-bottom:10px;'>
1164
+ <div style='background:#E3F2FD;padding:12px;border-radius:10px;text-align:center;border:1px solid #90CAF9;'>
1165
+ <div style='font-size:24px;font-weight:bold;color:#1565C0;'>{n_items}</div><div style='color:#666;font-size:12px;'>ุฃุตู†ุงู</div></div>
1166
+ <div style='background:#FFF3E0;padding:12px;border-radius:10px;text-align:center;border:1px solid #FFCC80;'>
1167
+ <div style='font-size:24px;font-weight:bold;color:#E65100;'>{total_duty}%</div><div style='color:#666;font-size:12px;'>ุงู„ุฑุณูˆู…</div></div>
1168
+ <div style='background:{r_color}15;padding:12px;border-radius:10px;text-align:center;border:1px solid {r_color}40;'>
1169
+ <div style='font-size:24px;font-weight:bold;color:{r_color};'>{r_icon} {r_name}</div><div style='color:#666;font-size:12px;'>ุงู„ุฎุทูˆุฑุฉ</div></div>
1170
+ <div style='background:#E8F5E9;padding:12px;border-radius:10px;text-align:center;border:1px solid #A5D6A7;'>
1171
+ <div style='font-size:24px;font-weight:bold;color:#2E7D32;'>โšก</div><div style='color:#666;font-size:12px;'>{elapsed:.1f}s</div></div>
1172
+ </div>
1173
+ <div style='background:#fff;padding:14px;border-radius:10px;border:1px solid #e0e0e0;margin-top:8px;margin-bottom:8px;'>
1174
+ <div style='font-weight:bold;color:#1565C0;margin-bottom:6px;'>๐Ÿ“‹ HS Codes</div>
1175
+ <div style='background:#F5F5F5;padding:8px 12px;border-radius:8px;font-family:monospace;font-size:12px;direction:ltr;'>{en_desc}</div>
1176
+ </div>
1177
+ <div style='background:#fff;padding:14px;border-radius:10px;border:1px solid #e0e0e0;'>
1178
+ <div style='font-weight:bold;color:#E65100;margin-bottom:6px;'>๐Ÿ“‹ ุงู„ูˆุตู</div>
1179
+ <div style='background:#FFF8E1;padding:8px 12px;border-radius:8px;font-size:13px;'>{ar_desc}</div>
1180
+ </div>
1181
+ </div>"""
1182
+ return html, df, None
1183
+
1184
 
1185
  # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
1186
  # ๐Ÿ“ก ุฑุจุท ู‚ุงุนุฏุฉ ุงู„ุจูŠุงู†ุงุช ุนุจุฑ API
 
2346
 
2347
 
2348
 
2349
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
2350
+ # ๐Ÿง  ุชุจูˆูŠุจ ู…ุณุชู‚ู„ โ€” YOLO11x + ุชุญุณูŠู† ุตูˆุฑ
2351
+ # โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
2352
+ with gr.Tab("๐Ÿง  AI ู…ุณุชู‚ู„"):
2353
+ gr.HTML("""<div style='background:linear-gradient(135deg,#FF6F00,#E65100);padding:14px;border-radius:12px;margin-bottom:10px;color:white;text-align:center;'>
2354
+ <div style='font-size:18px;font-weight:bold;'>๐Ÿง  ุชุจูˆูŠุจ ู…ุณุชู‚ู„ โ€” YOLO11x + ุชุญุณูŠู† ุตูˆุฑ</div>
2355
+ <div style='font-size:12px;opacity:0.8;margin-top:4px;'>โšก ุณุฑูŠุน (5s) | ู†ู…ูˆุฐุฌ ูˆุงุญุฏ ูู‚ุท | 6 ุชู‚ู†ูŠุงุช ุชุญุณูŠู†</div>
2356
  </div>""")
2357
+
2358
+ with gr.Tabs():
2359
+ # โ•โ•โ• ู‚ุณู… 1: ุชุตู†ูŠู ุณุฑูŠุน YOLO11x โ•โ•โ•
2360
+ with gr.Tab("โšก ุชุตู†ูŠู ุณุฑูŠุน"):
2361
+ gr.HTML("<div style='background:#FF6F00;padding:8px;border-radius:8px;text-align:center;color:white;font-weight:bold;margin-bottom:8px;'>โšก YOLO11x-cls โ€” ุชุตู†ูŠู ุจู†ู…ูˆุฐุฌ ูˆุงุญุฏ (3-8 ุซูˆุงู†ูŠ)</div>")
2362
+ with gr.Row():
2363
+ with gr.Column(scale=1):
2364
+ y_img = gr.Image(label="๐Ÿ“ท ุตูˆุฑุฉ ุงู„ุณูˆู†ุงุฑ", type="pil", height=300)
2365
+ y_dec = gr.Textbox(label="๐Ÿ“ ุงู„ุจุถุงุนุฉ ุงู„ู…ุตุฑู‘ุญุฉ", placeholder="ู…ุซุงู„: snacks ุฃูˆ rice+sugar", lines=1)
2366
+ y_btn = gr.Button("โšก ุชุตู†ูŠู ุณุฑูŠุน YOLO11x", variant="primary", size="lg")
2367
+ with gr.Column(scale=2):
2368
+ y_res = gr.HTML("")
2369
+ y_tbl = gr.Dataframe(label="๐Ÿ“Š ุงู„ู†ุชุงุฆุฌ", value=pd.DataFrame(), wrap=True)
2370
+ y_det = gr.Image(label="๐ŸŽฏ Detection", type="pil", visible=False)
2371
+ y_btn.click(yolo11_fast_classify, inputs=[y_img, y_dec], outputs=[y_res, y_tbl, y_det], api_name="analyze_fast")
2372
+
2373
+ # โ•โ•โ• ู‚ุณู… 2: ุชุญุณูŠู† ุตูˆุฑ โ•โ•โ•
2374
+ with gr.Tab("๐Ÿ”ฌ ุชุญุณูŠู† ุตูˆุฑ"):
2375
+ gr.HTML("<div style='background:#1a237e;padding:8px;border-radius:8px;text-align:center;color:white;font-weight:bold;margin-bottom:8px;'>๐Ÿ”ฌ 6 ุชู‚ู†ูŠุงุช ุชุญุณูŠู† โ€” CLAHE ยท HistEQ ยท Sharpen ยท Combined ยท Neural ยท Super Res</div>")
2376
+ with gr.Row():
2377
+ with gr.Column(scale=1):
2378
+ enh_img = gr.Image(label="๐Ÿ“ท ุงู„ุตูˆุฑุฉ ุงู„ุฃุตู„ูŠุฉ", type="pil", height=250)
2379
+ gr.HTML("""<div style='background:#F3E5F5;padding:10px;border-radius:8px;border:1px solid #CE93D8;font-size:11px;margin:6px 0;'>
2380
+ ๐Ÿ”† CLAHE โ€” ุชุจุงูŠู† ู…ุญู„ูŠ (0.1s)<br>๐Ÿ“Š HistEQ โ€” ุชูˆุฒูŠุน ูƒุซุงูุงุช (0.05s)<br>
2381
+ โšก Sharpen โ€” ุญุฏุฉ + ุฅุฒุงู„ุฉ ุถูˆุถุงุก (0.3s)<br>๐Ÿ† Combined โ€” ุฃูุถู„ ู†ุชูŠุฌุฉ (0.4s)<br>
2382
+ ๐ŸŒŠ Neural โ€” ุชุญุณูŠู† ุนุตุจูŠ GPU (1-3s)<br>๐Ÿ”ฌ Super Res โ€” ุชูƒุจูŠุฑ x2 (2-5s)
2383
+ </div>""")
2384
+ enh_btn_all = gr.Button("๐Ÿง  ุชุญุณูŠู† ุจูƒู„ ุงู„ุชู‚ู†ูŠุงุช", variant="primary", size="lg")
2385
+ gr.HTML("<div style='text-align:center;color:#666;font-size:12px;margin:6px 0;'>โ€” ุฃูˆ ุงุฎุชุฑ ูˆุงุญุฏุฉ โ€”</div>")
2386
+ enh_tech = gr.Radio(choices=["๐Ÿ”† CLAHE", "๐Ÿ“Š Histogram EQ", "โšก Sharpen + Denoise",
2387
+ "๐Ÿ† Combined Best", "๐ŸŒŠ GPU Neural", "๐Ÿ”ฌ Super Resolution x2"],
2388
+ value="๐Ÿ† Combined Best", label="ุงู„ุชู‚ู†ูŠุฉ")
2389
+ enh_btn_one = gr.Button("โšก ุชุญุณูŠู† ุณุฑูŠุน", variant="secondary")
2390
+ enh_one_res = gr.Image(label="ุงู„ู†ุชูŠุฌุฉ", type="pil", height=200)
2391
+ enh_one_st = gr.HTML("")
2392
+ with gr.Column(scale=2):
2393
+ enh_html = gr.HTML("<div style='text-align:center;padding:60px;color:#999;direction:rtl;'><div style='font-size:48px;'>๐Ÿง </div><div>ุงุฑูุน ุตูˆุฑุฉ ู„ู„ุชุญุณูŠู†</div></div>")
2394
+
2395
+ gr.HTML("<div style='background:#1565C0;padding:8px;border-radius:8px;text-align:center;color:white;font-weight:bold;margin:8px 0;'>๐Ÿ“Š ู…ู‚ุงุฑู†ุฉ 6 ุชู‚ู†ูŠุงุช</div>")
2396
+ with gr.Row():
2397
+ enh_r1 = gr.Image(label="๐Ÿ”† CLAHE", type="pil", height=220)
2398
+ enh_r2 = gr.Image(label="๐Ÿ“Š HistEQ", type="pil", height=220)
2399
+ enh_r3 = gr.Image(label="โšก Sharpen", type="pil", height=220)
2400
+ with gr.Row():
2401
+ enh_r4 = gr.Image(label="๐Ÿ† Combined", type="pil", height=220)
2402
+ enh_r5 = gr.Image(label="๐ŸŒŠ Neural", type="pil", height=220)
2403
+ enh_r6 = gr.Image(label="๐Ÿ”ฌ Super Res x2", type="pil", height=220)
2404
+
2405
+ gr.HTML("<div style='background:#2E7D32;padding:8px;border-radius:8px;text-align:center;color:white;font-weight:bold;margin:8px 0;'>๐Ÿ”„ ู‚ุจู„ / ุจุนุฏ</div>")
2406
+ with gr.Row():
2407
+ enh_before = gr.Image(label="๐Ÿ“ท ู‚ุจู„", type="pil", height=300)
2408
+ enh_after = gr.Image(label="๐Ÿ† ุจุนุฏ", type="pil", height=300)
2409
+
2410
+ def _run_all(img):
2411
+ html, r1, r2, r3, r4, r5, r6 = enhance_all_independent(img)
2412
+ best = r4 if r4 is not None else (r5 if r5 is not None else img)
2413
+ return html, r1, r2, r3, r4, r5, r6, img, best
2414
+
2415
+ enh_btn_all.click(_run_all, inputs=[enh_img],
2416
+ outputs=[enh_html, enh_r1, enh_r2, enh_r3, enh_r4, enh_r5, enh_r6, enh_before, enh_after])
2417
+ enh_btn_one.click(enhance_single_independent, inputs=[enh_img, enh_tech], outputs=[enh_one_res, enh_one_st])
2418
 
2419
  with gr.Tab("๐Ÿท๏ธ ู‚ุงุนุฏุฉ ุงู„ุฃุตู†ุงู"):
2420
  gr.HTML(f"<div style='background:#E8F5E9;padding:10px 14px;border-radius:10px;margin-bottom:8px;border-right:4px solid #2E7D32;'><b style='color:#2E7D32;'>๐Ÿ“ฆ {len(CARGO_DATABASE)} ุตู†ู</b></div>")