Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -77,14 +77,12 @@ class SuperUpscaler:
|
|
| 77 |
def preprocess_for_ai(self, image, max_size=512):
|
| 78 |
"""
|
| 79 |
تحضير الصورة للنموذج بدون تقليل الحجم الشديد.
|
| 80 |
-
- تحافظ على أكبر قدر من التفاصيل
|
| 81 |
-
- تجعل الأبعاد قابلة للقسمة على 4
|
| 82 |
"""
|
| 83 |
try:
|
| 84 |
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
| 85 |
h, w = rgb_image.shape[:2]
|
| 86 |
|
| 87 |
-
# تقليل فقط إذا كانت الصورة كبيرة جداً
|
| 88 |
if max(h, w) > max_size:
|
| 89 |
scale = max_size / max(h, w)
|
| 90 |
new_w = int(w * scale)
|
|
@@ -94,7 +92,7 @@ class SuperUpscaler:
|
|
| 94 |
|
| 95 |
h, w = rgb_image.shape[:2]
|
| 96 |
|
| 97 |
-
# جعل الأبعاد قابلة للقسمة على 4
|
| 98 |
new_h = ((h + 3) // 4) * 4
|
| 99 |
new_w = ((w + 3) // 4) * 4
|
| 100 |
|
|
@@ -186,13 +184,15 @@ class SuperUpscaler:
|
|
| 186 |
return None
|
| 187 |
|
| 188 |
def process_large_image_in_tiles(self, image, tile_size=512, overlap=64):
|
| 189 |
-
"""تقسيم الصورة الكبيرة إلى أجزاء ومعالجتها بشكل
|
| 190 |
try:
|
| 191 |
h, w = image.shape[:2]
|
| 192 |
print(f"📦 تقسيم صورة {w}x{h} إلى أجزاء {tile_size}x{tile_size}")
|
| 193 |
|
| 194 |
output_h, output_w = h * self.scale, w * self.scale
|
| 195 |
-
|
|
|
|
|
|
|
| 196 |
weight_map = np.zeros((output_h, output_w), dtype=np.float32)
|
| 197 |
|
| 198 |
processed_tiles = 0
|
|
@@ -226,15 +226,19 @@ class SuperUpscaler:
|
|
| 226 |
|
| 227 |
if fade_size > 0:
|
| 228 |
for i in range(fade_size):
|
| 229 |
-
|
| 230 |
-
fade[
|
| 231 |
-
fade[
|
| 232 |
-
fade[:,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 233 |
|
| 234 |
for c in range(3):
|
| 235 |
final_image[y_start:y_end_out, x_start:x_end_out, c] += (
|
| 236 |
-
|
| 237 |
-
)
|
| 238 |
|
| 239 |
weight_map[y_start:y_end_out, x_start:x_end_out] += fade
|
| 240 |
|
|
@@ -242,20 +246,23 @@ class SuperUpscaler:
|
|
| 242 |
if processed_tiles % 5 == 0:
|
| 243 |
print(f"📦 تمت معالجة {processed_tiles}/{total_tiles} من الأجزاء")
|
| 244 |
|
| 245 |
-
# تطبيع حسب الوزن
|
|
|
|
|
|
|
|
|
|
| 246 |
for c in range(3):
|
| 247 |
-
final_image[:, :, c] =
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
where=weight_map != 0
|
| 252 |
-
)
|
| 253 |
|
| 254 |
print("✅ تم دمج الأجزاء بنجاح!")
|
| 255 |
return final_image
|
| 256 |
|
| 257 |
except Exception as exc:
|
| 258 |
print(f"❌ خطأ أثناء معالجة الأجزاء: {exc}")
|
|
|
|
|
|
|
| 259 |
return None
|
| 260 |
|
| 261 |
def postprocess_from_ai(self, output):
|
|
|
|
| 77 |
def preprocess_for_ai(self, image, max_size=512):
|
| 78 |
"""
|
| 79 |
تحضير الصورة للنموذج بدون تقليل الحجم الشديد.
|
|
|
|
|
|
|
| 80 |
"""
|
| 81 |
try:
|
| 82 |
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
| 83 |
h, w = rgb_image.shape[:2]
|
| 84 |
|
| 85 |
+
# تقليل فقط إذا كانت الصورة كبيرة جداً
|
| 86 |
if max(h, w) > max_size:
|
| 87 |
scale = max_size / max(h, w)
|
| 88 |
new_w = int(w * scale)
|
|
|
|
| 92 |
|
| 93 |
h, w = rgb_image.shape[:2]
|
| 94 |
|
| 95 |
+
# جعل الأبعاد قابلة للقسمة على 4
|
| 96 |
new_h = ((h + 3) // 4) * 4
|
| 97 |
new_w = ((w + 3) // 4) * 4
|
| 98 |
|
|
|
|
| 184 |
return None
|
| 185 |
|
| 186 |
def process_large_image_in_tiles(self, image, tile_size=512, overlap=64):
|
| 187 |
+
"""تقسيم الصورة الكبيرة إلى أجزاء ومعالجتها بشكل محسّن - مع إصلاح خطأ الدمج."""
|
| 188 |
try:
|
| 189 |
h, w = image.shape[:2]
|
| 190 |
print(f"📦 تقسيم صورة {w}x{h} إلى أجزاء {tile_size}x{tile_size}")
|
| 191 |
|
| 192 |
output_h, output_w = h * self.scale, w * self.scale
|
| 193 |
+
|
| 194 |
+
# ✅ تغيير النوع إلى float32 لتجنب خطأ التحويل
|
| 195 |
+
final_image = np.zeros((output_h, output_w, 3), dtype=np.float32)
|
| 196 |
weight_map = np.zeros((output_h, output_w), dtype=np.float32)
|
| 197 |
|
| 198 |
processed_tiles = 0
|
|
|
|
| 226 |
|
| 227 |
if fade_size > 0:
|
| 228 |
for i in range(fade_size):
|
| 229 |
+
alpha = i / fade_size
|
| 230 |
+
fade[i, :] *= alpha
|
| 231 |
+
fade[-i-1, :] *= alpha
|
| 232 |
+
fade[:, i] *= alpha
|
| 233 |
+
fade[:, -i-1] *= alpha
|
| 234 |
+
|
| 235 |
+
# ✅ تحويل enhanced_tile إلى float32 للدمج
|
| 236 |
+
enhanced_tile_float = enhanced_tile[:actual_tile_h, :actual_tile_w].astype(np.float32)
|
| 237 |
|
| 238 |
for c in range(3):
|
| 239 |
final_image[y_start:y_end_out, x_start:x_end_out, c] += (
|
| 240 |
+
enhanced_tile_float[:, :, c] * fade
|
| 241 |
+
)
|
| 242 |
|
| 243 |
weight_map[y_start:y_end_out, x_start:x_end_out] += fade
|
| 244 |
|
|
|
|
| 246 |
if processed_tiles % 5 == 0:
|
| 247 |
print(f"📦 تمت معالجة {processed_tiles}/{total_tiles} من الأجزاء")
|
| 248 |
|
| 249 |
+
# ✅ تطبيع حسب الوزن بشكل صحيح
|
| 250 |
+
# تجنب القسمة على صفر
|
| 251 |
+
weight_map = np.maximum(weight_map, 1e-6)
|
| 252 |
+
|
| 253 |
for c in range(3):
|
| 254 |
+
final_image[:, :, c] = final_image[:, :, c] / weight_map
|
| 255 |
+
|
| 256 |
+
# ✅ تحويل إلى uint8 في النهاية
|
| 257 |
+
final_image = np.clip(final_image, 0, 255).astype(np.uint8)
|
|
|
|
|
|
|
| 258 |
|
| 259 |
print("✅ تم دمج الأجزاء بنجاح!")
|
| 260 |
return final_image
|
| 261 |
|
| 262 |
except Exception as exc:
|
| 263 |
print(f"❌ خطأ أثناء معالجة الأجزاء: {exc}")
|
| 264 |
+
import traceback
|
| 265 |
+
traceback.print_exc()
|
| 266 |
return None
|
| 267 |
|
| 268 |
def postprocess_from_ai(self, output):
|