Update app.py
Browse files
app.py
CHANGED
|
@@ -668,6 +668,9 @@ def classify_image(img):
|
|
| 668 |
if img.mode != 'RGB':
|
| 669 |
img = img.convert('RGB')
|
| 670 |
|
|
|
|
|
|
|
|
|
|
| 671 |
input_224 = transform_224(img).unsqueeze(0).to(DEVICE)
|
| 672 |
input_256 = transform_256(img).unsqueeze(0).to(DEVICE) if transform_256 else input_224
|
| 673 |
|
|
@@ -1079,6 +1082,63 @@ def enhance_single_independent(img, technique):
|
|
| 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:
|
|
@@ -1087,64 +1147,16 @@ def yolo11_fast_classify(img, declared_text):
|
|
| 1087 |
pd.DataFrame(), None)
|
| 1088 |
|
| 1089 |
start = time_module.time()
|
| 1090 |
-
|
| 1091 |
-
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 1092 |
-
# ๐ DEBUG BLOCK โ ูู
ุนุฑูุฉ ู
ุง ุชุฑุงู Python ูุจู YOLO
|
| 1093 |
-
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 1094 |
-
import io as _io
|
| 1095 |
-
import os as _os
|
| 1096 |
-
|
| 1097 |
-
arr_orig = np.array(img)
|
| 1098 |
-
print(f"\n{'='*60}")
|
| 1099 |
-
print(f"๐ DEBUG yolo11_fast_classify โ ุตูุฑุฉ ู
ุณุชูุจููุฉ")
|
| 1100 |
-
print(f"{'='*60}")
|
| 1101 |
-
print(f"๐ ุงูุญุฌู
: {img.size[0]}x{img.size[1]}")
|
| 1102 |
-
print(f"๐จ Mode: {img.mode}")
|
| 1103 |
-
print(f"๐ Array shape: {arr_orig.shape}")
|
| 1104 |
-
print(f"๐ dtype: {arr_orig.dtype}")
|
| 1105 |
-
print(f"๐ min={arr_orig.min()} / max={arr_orig.max()} / mean={arr_orig.mean():.2f}")
|
| 1106 |
-
|
| 1107 |
-
# ูู ุงูุตูุฑุฉ ุฑู
ุงุฏูุฉ ู
ุฎููุฉ ุฏุงุฎู RGBุ
|
| 1108 |
-
if len(arr_orig.shape) == 3 and arr_orig.shape[2] == 3:
|
| 1109 |
-
r_eq_g = bool(np.all(arr_orig[:,:,0] == arr_orig[:,:,1]))
|
| 1110 |
-
g_eq_b = bool(np.all(arr_orig[:,:,1] == arr_orig[:,:,2]))
|
| 1111 |
-
print(f"๐ฌ R==G: {r_eq_g} | G==B: {g_eq_b}")
|
| 1112 |
-
print(f"๐ฌ ูู ุฑู
ุงุฏูุฉ ู
ุฎููุฉ (R=G=B): {r_eq_g and g_eq_b}")
|
| 1113 |
-
|
| 1114 |
-
# ูุญุต 5 pixels ู
ู ุงูู
ูุชุตู
|
| 1115 |
-
h, w = arr_orig.shape[:2]
|
| 1116 |
-
print(f"๐ฌ ุนููุฉ pixels ู
ู ุงูู
ูุชุตู:")
|
| 1117 |
-
for y in range(h//2 - 2, h//2 + 3, 2):
|
| 1118 |
-
for x in range(w//2 - 2, w//2 + 3, 2):
|
| 1119 |
-
r, g, b = arr_orig[y, x]
|
| 1120 |
-
print(f" [{y},{x}] โ R={r} G={g} B={b}")
|
| 1121 |
-
|
| 1122 |
-
# ูุญุต ุชูุฒูุน ุงููููุงุช
|
| 1123 |
-
r_mean = arr_orig[:,:,0].mean()
|
| 1124 |
-
g_mean = arr_orig[:,:,1].mean()
|
| 1125 |
-
b_mean = arr_orig[:,:,2].mean()
|
| 1126 |
-
print(f"๐ ู
ุชูุณุท ุงููููุงุช: R={r_mean:.1f} G={g_mean:.1f} B={b_mean:.1f}")
|
| 1127 |
-
print(f"๐ ูุฑู R-G={abs(r_mean-g_mean):.2f} G-B={abs(g_mean-b_mean):.2f}")
|
| 1128 |
-
|
| 1129 |
-
# ุญูุธ ุงูุตูุฑุฉ ุงููุงุฑุฏุฉ ููู
ูุงุฑูุฉ
|
| 1130 |
-
try:
|
| 1131 |
-
debug_path = "/tmp/debug_received.png"
|
| 1132 |
-
img.save(debug_path)
|
| 1133 |
-
size_kb = _os.path.getsize(debug_path) / 1024
|
| 1134 |
-
print(f"๐พ ุชู
ุญูุธ ุงูุตูุฑุฉ ุงููุงุฑุฏุฉ: {debug_path} ({size_kb:.1f}KB)")
|
| 1135 |
-
except Exception as _e:
|
| 1136 |
-
print(f"โ ๏ธ ุชุนุฐุฑ ุญูุธ: {_e}")
|
| 1137 |
-
|
| 1138 |
-
print(f"{'='*60}\n")
|
| 1139 |
-
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 1140 |
-
# ููุงูุฉ DEBUG BLOCK
|
| 1141 |
-
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 1142 |
-
|
| 1143 |
if img.mode != 'RGB':
|
| 1144 |
-
print(f"๐ ุชุญููู ู
ู {img.mode} ุฅูู RGB")
|
| 1145 |
img = img.convert('RGB')
|
| 1146 |
-
|
| 1147 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1148 |
|
| 1149 |
# โโโ ุงูุจุญุซ ุนู YOLO11x ููุท โโโ
|
| 1150 |
yolo_model = None
|
|
@@ -1159,23 +1171,6 @@ def yolo11_fast_classify(img, declared_text):
|
|
| 1159 |
return ("<div style='color:red;text-align:center;padding:30px;'>โ YOLO11x-cls ุบูุฑ ู
ุชููุฑ</div>",
|
| 1160 |
pd.DataFrame(), None)
|
| 1161 |
|
| 1162 |
-
# โโโ DEBUG: ุญูุธ ุงูุตูุฑุฉ ุงูุชู ุณุชูุฑุณู ูู YOLO โโโ
|
| 1163 |
-
try:
|
| 1164 |
-
debug_yolo_path = "/tmp/debug_to_yolo.png"
|
| 1165 |
-
img.save(debug_yolo_path)
|
| 1166 |
-
import os as _os2
|
| 1167 |
-
yolo_size_kb = _os2.path.getsize(debug_yolo_path) / 1024
|
| 1168 |
-
arr_yolo = np.array(img)
|
| 1169 |
-
print(f"\n๐ค ุงูุตูุฑุฉ ุงูู
ูุฑุณูุฉ ูู YOLO:")
|
| 1170 |
-
print(f" ๐ {img.size[0]}x{img.size[1]} | {img.mode}")
|
| 1171 |
-
print(f" ๐ R={arr_yolo[:,:,0].mean():.1f} G={arr_yolo[:,:,1].mean():.1f} B={arr_yolo[:,:,2].mean():.1f}")
|
| 1172 |
-
print(f" ๐พ PNG size: {yolo_size_kb:.1f}KB")
|
| 1173 |
-
r_eq_g2 = bool(np.all(arr_yolo[:,:,0] == arr_yolo[:,:,1]))
|
| 1174 |
-
g_eq_b2 = bool(np.all(arr_yolo[:,:,1] == arr_yolo[:,:,2]))
|
| 1175 |
-
print(f" ๐ฌ ุฑู
ุงุฏูุฉ ู
ุฎููุฉ: {r_eq_g2 and g_eq_b2}")
|
| 1176 |
-
except Exception as _e2:
|
| 1177 |
-
print(f"โ ๏ธ debug YOLO: {_e2}")
|
| 1178 |
-
|
| 1179 |
# โโโ ุชุตููู โโโ
|
| 1180 |
items_list = []
|
| 1181 |
try:
|
|
@@ -1183,12 +1178,6 @@ def yolo11_fast_classify(img, declared_text):
|
|
| 1183 |
if res and res[0].probs is not None:
|
| 1184 |
probs = res[0].probs.data.cpu().numpy()
|
| 1185 |
top5_idx = probs.argsort()[-5:][::-1]
|
| 1186 |
-
# โโโ DEBUG: ุทุจุงุนุฉ top-5 ูุชุงุฆุฌ YOLO โโโ
|
| 1187 |
-
print(f"\n๐ฏ ูุชุงุฆุฌ YOLO {yolo_name} โ top-5:")
|
| 1188 |
-
for rank, idx in enumerate(top5_idx[:5]):
|
| 1189 |
-
cat = CATEGORIES[idx] if idx < len(CATEGORIES) else f"idx_{idx}"
|
| 1190 |
-
print(f" {rank+1}. {cat}: {probs[idx]:.1%}")
|
| 1191 |
-
print()
|
| 1192 |
for idx in top5_idx:
|
| 1193 |
if idx < len(CATEGORIES) and probs[idx] > 0.05:
|
| 1194 |
items_list.append((CATEGORIES[idx], float(probs[idx])))
|
|
|
|
| 668 |
if img.mode != 'RGB':
|
| 669 |
img = img.convert('RGB')
|
| 670 |
|
| 671 |
+
# โ๏ธ ูุต ุงููุฑุงุบ ุงูุฃุฒุฑู ูุจู ุงูุชุญููู
|
| 672 |
+
img = crop_container(img)
|
| 673 |
+
|
| 674 |
input_224 = transform_224(img).unsqueeze(0).to(DEVICE)
|
| 675 |
input_256 = transform_256(img).unsqueeze(0).to(DEVICE) if transform_256 else input_224
|
| 676 |
|
|
|
|
| 1082 |
# ูุง ูุณุชุฎุฏู
classify_image ููุง analyze_image
|
| 1083 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 1084 |
|
| 1085 |
+
def crop_container(img):
|
| 1086 |
+
"""
|
| 1087 |
+
โ๏ธ ูุต ุงูุญุงููุฉ ูุฅุฒุงูุฉ ุงููุฑุงุบ ุงูุฃุฒุฑู ุงูุฎููู
|
| 1088 |
+
ูุจุญุซ ุนู ุญุฏูุฏ ุงูู
ุญุชูู ุงูุญูููู ูููุต ุงูุฎูููุฉ ุงูุฒุฑูุงุก
|
| 1089 |
+
"""
|
| 1090 |
+
import numpy as np
|
| 1091 |
+
arr = np.array(img)
|
| 1092 |
+
h, w = arr.shape[:2]
|
| 1093 |
+
|
| 1094 |
+
# ุงูุฎูููุฉ ุงูุฒุฑูุงุก: R<100, G<100, B>130
|
| 1095 |
+
# ุงูู
ุญุชูู: ุฃู ุจูุณู ููุณ ุฃุฒุฑู ุฎุงูุต
|
| 1096 |
+
if len(arr.shape) == 3:
|
| 1097 |
+
is_bg = (arr[:,:,0].astype(int) < 100) & \
|
| 1098 |
+
(arr[:,:,1].astype(int) < 100) & \
|
| 1099 |
+
(arr[:,:,2].astype(int) > 130)
|
| 1100 |
+
# ุฃูุถุงู ุงูุฃุจูุถ/ุงูุฑู
ุงุฏู ุงููุงุชุญ ุฌุฏุงู ูุฎูููุฉ
|
| 1101 |
+
is_bg_white = (arr[:,:,0] > 240) & (arr[:,:,1] > 240) & (arr[:,:,2] > 240)
|
| 1102 |
+
is_bg = is_bg | is_bg_white
|
| 1103 |
+
else:
|
| 1104 |
+
return img # grayscale โ ูุง crop
|
| 1105 |
+
|
| 1106 |
+
is_content = ~is_bg
|
| 1107 |
+
|
| 1108 |
+
# ุงูุจุญุซ ุนู ุญุฏูุฏ ุงูู
ุญุชูู
|
| 1109 |
+
rows_with_content = np.any(is_content, axis=1)
|
| 1110 |
+
cols_with_content = np.any(is_content, axis=0)
|
| 1111 |
+
|
| 1112 |
+
if not rows_with_content.any() or not cols_with_content.any():
|
| 1113 |
+
print("โ ๏ธ Crop: ูู
ููุนุซุฑ ุนูู ู
ุญุชููุ ุฅุฑุฌุงุน ุงูุฃุตููุฉ")
|
| 1114 |
+
return img
|
| 1115 |
+
|
| 1116 |
+
top = int(np.argmax(rows_with_content))
|
| 1117 |
+
bottom = int(len(rows_with_content) - np.argmax(rows_with_content[::-1]))
|
| 1118 |
+
left = int(np.argmax(cols_with_content))
|
| 1119 |
+
right = int(len(cols_with_content) - np.argmax(cols_with_content[::-1]))
|
| 1120 |
+
|
| 1121 |
+
# ูุงู
ุด 5 ุจูุณู
|
| 1122 |
+
margin = 5
|
| 1123 |
+
top = max(0, top - margin)
|
| 1124 |
+
bottom = min(h, bottom + margin)
|
| 1125 |
+
left = max(0, left - margin)
|
| 1126 |
+
right = min(w, right + margin)
|
| 1127 |
+
|
| 1128 |
+
crop_w = right - left
|
| 1129 |
+
crop_h = bottom - top
|
| 1130 |
+
|
| 1131 |
+
# ูุง crop ุฅุฐุง ูุงู ุงูู
ุญุชูู ุฃูู ู
ู 20% ู
ู ุงูุตูุฑุฉ (ุฎุทุฃ ูู ุงููุดู)
|
| 1132 |
+
if crop_w < w * 0.2 or crop_h < h * 0.2:
|
| 1133 |
+
print(f"โ ๏ธ Crop: ูุชูุฌุฉ ุตุบูุฑุฉ ุฌุฏุงู {crop_w}x{crop_h}ุ ุฅุฑุฌุงุน ุงูุฃุตููุฉ")
|
| 1134 |
+
return img
|
| 1135 |
+
|
| 1136 |
+
print(f"โ๏ธ Crop: {w}x{h} โ {crop_w}x{crop_h} | L={left} T={top} R={right} B={bottom}")
|
| 1137 |
+
print(f"โ๏ธ ุชู
ุญุฐู {w-crop_w} ุจูุณู ุฃูููุ {h-crop_h} ุจูุณู ุฑุฃุณู")
|
| 1138 |
+
|
| 1139 |
+
return img.crop((left, top, right, bottom))
|
| 1140 |
+
|
| 1141 |
+
|
| 1142 |
def yolo11_fast_classify(img, declared_text):
|
| 1143 |
"""โก ุชุตููู ุณุฑูุน ุจู YOLO11x-cls ููุท (3-8 ุซูุงูู)"""
|
| 1144 |
if img is None:
|
|
|
|
| 1147 |
pd.DataFrame(), None)
|
| 1148 |
|
| 1149 |
start = time_module.time()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1150 |
if img.mode != 'RGB':
|
|
|
|
| 1151 |
img = img.convert('RGB')
|
| 1152 |
+
|
| 1153 |
+
# โ๏ธ ูุต ุงููุฑุงุบ ุงูุฃุฒุฑู โ ููุณ ู
ุง ูุฑุงู ุงูู
ุณุชุฎุฏู
ูู ุงููุงุฌูุฉ
|
| 1154 |
+
img_original_size = img.size
|
| 1155 |
+
img = crop_container(img)
|
| 1156 |
+
if img.size != img_original_size:
|
| 1157 |
+
print(f"โ๏ธ ุจุนุฏ ุงูู Crop: {img.size[0]}x{img.size[1]}")
|
| 1158 |
+
else:
|
| 1159 |
+
print("โน๏ธ ูู
ูุชู
Crop (ุงูุตูุฑุฉ ุจุฏูู ูุฑุงุบ)")
|
| 1160 |
|
| 1161 |
# โโโ ุงูุจุญุซ ุนู YOLO11x ููุท โโโ
|
| 1162 |
yolo_model = None
|
|
|
|
| 1171 |
return ("<div style='color:red;text-align:center;padding:30px;'>โ YOLO11x-cls ุบูุฑ ู
ุชููุฑ</div>",
|
| 1172 |
pd.DataFrame(), None)
|
| 1173 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1174 |
# โโโ ุชุตููู โโโ
|
| 1175 |
items_list = []
|
| 1176 |
try:
|
|
|
|
| 1178 |
if res and res[0].probs is not None:
|
| 1179 |
probs = res[0].probs.data.cpu().numpy()
|
| 1180 |
top5_idx = probs.argsort()[-5:][::-1]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1181 |
for idx in top5_idx:
|
| 1182 |
if idx < len(CATEGORIES) and probs[idx] > 0.05:
|
| 1183 |
items_list.append((CATEGORIES[idx], float(probs[idx])))
|