Foydalanuvchi commited on
Commit
f1841ce
·
1 Parent(s): 9b345f9

Phase 5: Ultra HD (EDSR+CLAHE) and Pro Stabilization

Browse files
Files changed (2) hide show
  1. filters.py +117 -51
  2. requirements.txt +1 -1
filters.py CHANGED
@@ -61,13 +61,32 @@ def apply_retro_filter(image_path, output_path):
61
  logger.error(f"Retro rasm xatosi: {e}")
62
  return None
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  def upscale_image(image_path, output_path, scale=2):
65
- """Rasmni AI Super-Resolution (Swin2SR) orqali yoki lokal algoritm bilan sifatini oshirish."""
66
  try:
67
  image_path = os.path.abspath(image_path)
68
  output_path = os.path.abspath(output_path)
69
 
70
- # 1. Hugging Face AI orqali (Eng yuqori sifat)
71
  hf_token = os.environ.get("HF_TOKEN")
72
  if hf_token:
73
  try:
@@ -78,7 +97,6 @@ def upscale_image(image_path, output_path, scale=2):
78
  image_data = f.read()
79
 
80
  logger.info("HF Upscale: AI Super-Resolution ishga tushirildi.")
81
- # Super-resolution uchun to'g'ri API chaqiruvi
82
  result_image = client.image_to_image(
83
  image_data,
84
  model="caidas/swin2SR-classical-sr-x2-64",
@@ -88,9 +106,9 @@ def upscale_image(image_path, output_path, scale=2):
88
  logger.info("HF Upscale muvaffaqiyatli.")
89
  return output_path
90
  except Exception as e:
91
- logger.warning(f"HF Upscale xatosi (Lokalga o'tilmoqda): {e}")
92
 
93
- # 2. Lokal algoritm (Tezkor va barqaror)
94
  img = cv2.imread(image_path)
95
  if img is None: return None
96
 
@@ -99,26 +117,54 @@ def upscale_image(image_path, output_path, scale=2):
99
  elif img.shape[2] == 4:
100
  img = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)
101
 
102
- height, width = img.shape[:2]
103
- new_size = (width * scale, height * scale)
104
- upscaled = cv2.resize(img, new_size, interpolation=cv2.INTER_LANCZOS4)
105
-
106
- # Shovqinni tozalash (tabiiy to'qimalarni saqlab qolish uchun yumshoqroq)
107
- upscaled = cv2.fastNlMeansDenoisingColored(upscaled, None, 3, 3, 7, 21)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
 
109
  pill_img = Image.fromarray(cv2.cvtColor(upscaled, cv2.COLOR_BGR2RGB))
110
-
111
- # O'tkirlik va kontrastni tabiiy kuchaytirish
112
  enhancer = ImageEnhance.Sharpness(pill_img)
113
- pill_img = enhancer.enhance(1.8)
114
  enhancer_c = ImageEnhance.Contrast(pill_img)
115
- pill_img = enhancer_c.enhance(1.1)
116
 
117
  upscaled_final = cv2.cvtColor(np.array(pill_img), cv2.COLOR_RGB2BGR)
118
  cv2.imwrite(output_path, upscaled_final)
119
- return output_path
 
 
120
  except Exception as e:
121
- logger.error(f"Upscale rasm xatosi: {e}")
122
  return None
123
 
124
  def _apply_video_transform(video_path, output_path, transform_func, progress_callback=None, fps_override=None):
@@ -188,15 +234,27 @@ def process_video_retro(video_path, output_path, progress_callback=None):
188
 
189
 
190
  def process_video_upscale(video_path, output_path, progress_callback=None):
191
- """Videoning sifatini (o'lcham va o'tkirlik) oshiradi."""
192
  def upscale_frame(frame):
193
  bgr = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
194
  h, w = bgr.shape[:2]
195
- upscaled = cv2.resize(bgr, (int(w*1.5), int(h*1.5)), interpolation=cv2.INTER_LANCZOS4)
196
 
197
- gaussian_3 = cv2.GaussianBlur(upscaled, (0, 0), 2.0)
198
- unsharp_image = cv2.addWeighted(upscaled, 1.5, gaussian_3, -0.5, 0)
199
- return cv2.cvtColor(unsharp_image, cv2.COLOR_BGR2RGB)
 
 
 
 
 
 
 
 
 
 
 
 
 
200
 
201
  return _apply_video_transform(video_path, output_path, upscale_frame, progress_callback)
202
 
@@ -1166,25 +1224,30 @@ def process_video_stabilize(video_path, output_path, progress_callback=None, smo
1166
  cum_a += da
1167
  trajectory.append((cum_x, cum_y, cum_a))
1168
 
1169
- # Moving Average bilan tekislash
1170
- def moving_average(values, radius):
1171
- """1D moving average filter."""
1172
- n = len(values)
1173
- smoothed = np.zeros(n)
1174
- for i in range(n):
1175
- start = max(0, i - radius)
1176
- end = min(n, i + radius + 1)
1177
- smoothed[i] = np.mean(values[start:end])
1178
- return smoothed
 
 
 
 
 
1179
 
1180
  traj_x = np.array([t[0] for t in trajectory])
1181
  traj_y = np.array([t[1] for t in trajectory])
1182
  traj_a = np.array([t[2] for t in trajectory])
1183
 
1184
- # Trajectoryani tekislash (smoothing_radius=30 kadr)
1185
- smooth_x = moving_average(traj_x, smoothing_radius)
1186
- smooth_y = moving_average(traj_y, smoothing_radius)
1187
- smooth_a = moving_average(traj_a, smoothing_radius)
1188
 
1189
  # Tuzatish = tekislangan - asl trajectory
1190
  diff_x = smooth_x - traj_x
@@ -1207,26 +1270,23 @@ def process_video_stabilize(video_path, output_path, progress_callback=None, smo
1207
 
1208
  cap = cv2.VideoCapture(video_path)
1209
 
1210
- # Border crop (qora chetlarni yo'qotish uchun 5% qirqish)
1211
- crop_ratio = 0.05
1212
- crop_x = int(width * crop_ratio)
1213
- crop_y = int(height * crop_ratio)
1214
- out_w = width - 2 * crop_x
1215
- out_h = height - 2 * crop_y
1216
 
1217
  temp_video_path = output_path + "_stab_temp.avi"
1218
  fourcc = cv2.VideoWriter_fourcc(*'MJPG')
1219
  writer = cv2.VideoWriter(temp_video_path, fourcc, fps, (out_w, out_h))
1220
 
1221
- # Birinchi kadrni o'qib tashlash (prev_frame)
1222
- ret, _ = cap.read()
 
 
1223
  if not ret:
1224
  cap.release()
1225
  return None
1226
 
1227
- # Birinchi kadrni asl holida yozish
1228
- first_cropped = _[crop_y:crop_y+out_h, crop_x:crop_x+out_w]
1229
- writer.write(first_cropped)
1230
 
1231
  for i in range(len(smooth_transforms)):
1232
  ret, frame = cap.read()
@@ -1243,15 +1303,21 @@ def process_video_stabilize(video_path, output_path, progress_callback=None, smo
1243
  [sin_a, cos_a, dy]
1244
  ], dtype=np.float64)
1245
 
1246
- # Transformatsiyani qo'llash
1247
  stabilized = cv2.warpAffine(
1248
  frame, transform_mat, (width, height),
 
 
 
 
 
 
 
 
1249
  borderMode=cv2.BORDER_REFLECT_101
1250
  )
1251
 
1252
- # Chetlarni qirqish (qora border yo'qotish)
1253
- cropped = stabilized[crop_y:crop_y+out_h, crop_x:crop_x+out_w]
1254
- writer.write(cropped)
1255
 
1256
  if progress_callback and i % 5 == 0:
1257
  progress_callback(min(95, 55 + int(i / len(smooth_transforms) * 40)))
 
61
  logger.error(f"Retro rasm xatosi: {e}")
62
  return None
63
 
64
+ def _get_superres_model():
65
+ """EDSR_x2 modelini keshdan oladi yoki avtomatik yuklaydi."""
66
+ cache_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "cache")
67
+ os.makedirs(cache_dir, exist_ok=True)
68
+ model_path = os.path.join(cache_dir, "EDSR_x2.pb")
69
+
70
+ if not os.path.exists(model_path):
71
+ logger.info("EDSR_x2 AI modeli topilmadi. Yuklab olinmoqda (birinchi marta ishlaganda biroz vaqt oladi)...")
72
+ try:
73
+ import urllib.request
74
+ # EDSR x2 modelini to'g'ridan-to'g'ri Saafke repo dan tortish
75
+ url = "https://github.com/Saafke/EDSR_TensorFlow/raw/master/models/EDSR_x2.pb"
76
+ urllib.request.urlretrieve(url, model_path)
77
+ logger.info("✅ EDSR_x2 muvaffaqiyatli yuklandi va keshlandi!")
78
+ except Exception as e:
79
+ logger.error(f"EDSR modelini yuklashda xatolik: {e}")
80
+ return None
81
+ return model_path
82
+
83
  def upscale_image(image_path, output_path, scale=2):
84
+ """Rasmni AI Super-Resolution (Swin2SR/EDSR) yoki ilg'or Matematik (LAB CLAHE) algoritm bilan oshirish."""
85
  try:
86
  image_path = os.path.abspath(image_path)
87
  output_path = os.path.abspath(output_path)
88
 
89
+ # 1. Hugging Face AI orqali (Eng yuqori sifat, agar Premium Token berilgan bo'lsa)
90
  hf_token = os.environ.get("HF_TOKEN")
91
  if hf_token:
92
  try:
 
97
  image_data = f.read()
98
 
99
  logger.info("HF Upscale: AI Super-Resolution ishga tushirildi.")
 
100
  result_image = client.image_to_image(
101
  image_data,
102
  model="caidas/swin2SR-classical-sr-x2-64",
 
106
  logger.info("HF Upscale muvaffaqiyatli.")
107
  return output_path
108
  except Exception as e:
109
+ logger.warning(f"HF Upscale xatosi (Lokal AI/Fallback ga o'tilmoqda): {e}")
110
 
111
+ # 2. Lokal Asosiy Algoritmga tayyorlash
112
  img = cv2.imread(image_path)
113
  if img is None: return None
114
 
 
117
  elif img.shape[2] == 4:
118
  img = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)
119
 
120
+ # 3. YECHIM: Local AI DNN Super-Resolution (EDSR_x2 moduli)
121
+ ai_upscaled = False
122
+ try:
123
+ from cv2 import dnn_superres
124
+ model_path = _get_superres_model()
125
+ if model_path and os.path.exists(model_path):
126
+ sr = dnn_superres.DnnSuperResImpl_create()
127
+ sr.readModel(model_path)
128
+ sr.setModel("edsr", 2) # Scale 2x ekanligi sababli x2 qilingan
129
+ logger.info("Lokal AI (EDSR) ishlashni boshladi...")
130
+ upscaled = sr.upsample(img)
131
+ ai_upscaled = True
132
+ logger.info("Lokal AI (EDSR) orqali rasm muvaffaqiyatli kattalashtirildi.")
133
+ except Exception as ai_err:
134
+ logger.warning(f"Lokal AI upscale xatosi (Kutubxona yetishmayotgan bo'lishi mumkin): {ai_err}")
135
+
136
+ # 4. YECHIM Fallback: LAB CLAHE va Matematik HDR tizimi (Agar AI ishlamasa)
137
+ if not ai_upscaled:
138
+ logger.info("Lokal AI ishlamadi. Matematik HDR (LAB CLAHE) ga o'tildi.")
139
+ height, width = img.shape[:2]
140
+ new_size = (width * scale, height * scale)
141
+ upscaled = cv2.resize(img, new_size, interpolation=cv2.INTER_LANCZOS4)
142
+
143
+ # Rasmni rang intensivligi asosida piksellash (HDR effekti uchun L-channel CLAHE)
144
+ lab = cv2.cvtColor(upscaled, cv2.COLOR_BGR2LAB)
145
+ l, a, b = cv2.split(lab)
146
+ clahe = cv2.createCLAHE(clipLimit=1.8, tileGridSize=(8, 8))
147
+ cl = clahe.apply(l)
148
+ merged = cv2.merge((cl, a, b))
149
+ upscaled = cv2.cvtColor(merged, cv2.COLOR_LAB2BGR)
150
+
151
+ # Yakuniy ishlov (Shovqinni ozgina maydalash)
152
+ upscaled = cv2.fastNlMeansDenoisingColored(upscaled, None, 3, 3, 5, 15)
153
 
154
+ # O'tkirlik va kontrastni tabiiy kuchaytirish (Plastmassa darajasiga kirtimaydi)
155
  pill_img = Image.fromarray(cv2.cvtColor(upscaled, cv2.COLOR_BGR2RGB))
 
 
156
  enhancer = ImageEnhance.Sharpness(pill_img)
157
+ pill_img = enhancer.enhance(1.3)
158
  enhancer_c = ImageEnhance.Contrast(pill_img)
159
+ pill_img = enhancer_c.enhance(1.05)
160
 
161
  upscaled_final = cv2.cvtColor(np.array(pill_img), cv2.COLOR_RGB2BGR)
162
  cv2.imwrite(output_path, upscaled_final)
163
+
164
+ # Agar rasm aqlqili yozilgan bo'lsa qaytarish
165
+ return output_path if os.path.exists(output_path) else None
166
  except Exception as e:
167
+ logger.error(f"Upscale rasm xatosi (Asosiy block): {e}")
168
  return None
169
 
170
  def _apply_video_transform(video_path, output_path, transform_func, progress_callback=None, fps_override=None):
 
234
 
235
 
236
  def process_video_upscale(video_path, output_path, progress_callback=None):
237
+ """Videoning sifatini (o'lcham va o'tkirlik) optimallashtirilgan Matematik HDR bilan oshiradi."""
238
  def upscale_frame(frame):
239
  bgr = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
240
  h, w = bgr.shape[:2]
 
241
 
242
+ # 1.5 baravar asossli kattalashtirish (Lanczos4 usuli - eng sifatlisi)
243
+ upscaled = cv2.resize(bgr, (int(w * 1.5), int(h * 1.5)), interpolation=cv2.INTER_LANCZOS4)
244
+
245
+ # LAB kanalida micro-contrast va HDR yoritish (CLAHE)
246
+ lab = cv2.cvtColor(upscaled, cv2.COLOR_BGR2LAB)
247
+ l, a, b = cv2.split(lab)
248
+ clahe = cv2.createCLAHE(clipLimit=1.5, tileGridSize=(8, 8))
249
+ cl = clahe.apply(l)
250
+ merged = cv2.merge((cl, a, b))
251
+ upscaled = cv2.cvtColor(merged, cv2.COLOR_LAB2BGR)
252
+
253
+ # Yumshoq "Unsharp Mask" bilan HD xususiyatini o'tkirlashtirish
254
+ gaussian = cv2.GaussianBlur(upscaled, (0, 0), 2.0)
255
+ unsharp = cv2.addWeighted(upscaled, 1.3, gaussian, -0.3, 0)
256
+
257
+ return cv2.cvtColor(unsharp, cv2.COLOR_BGR2RGB)
258
 
259
  return _apply_video_transform(video_path, output_path, upscale_frame, progress_callback)
260
 
 
1224
  cum_a += da
1225
  trajectory.append((cum_x, cum_y, cum_a))
1226
 
1227
+ # L1-Optimized Trajectory Smoothing (scipy gaussian smoothing)
1228
+ def l1_smooth_trajectory(values, radius):
1229
+ """Ilg'or filtering orqali haqiqiy Adobe Premiere kabi keskinlikni o'ldirish."""
1230
+ try:
1231
+ from scipy.ndimage import gaussian_filter1d
1232
+ return gaussian_filter1d(values, sigma=radius/2.5)
1233
+ except ImportError:
1234
+ # Agar scipy bo'lmasa fallback smooth
1235
+ n = len(values)
1236
+ smoothed = np.zeros(n)
1237
+ for i in range(n):
1238
+ start = max(0, i - radius)
1239
+ end = min(n, i + radius + 1)
1240
+ smoothed[i] = np.mean(values[start:end])
1241
+ return smoothed
1242
 
1243
  traj_x = np.array([t[0] for t in trajectory])
1244
  traj_y = np.array([t[1] for t in trajectory])
1245
  traj_a = np.array([t[2] for t in trajectory])
1246
 
1247
+ # Trajectoryani tekislash
1248
+ smooth_x = l1_smooth_trajectory(traj_x, smoothing_radius)
1249
+ smooth_y = l1_smooth_trajectory(traj_y, smoothing_radius)
1250
+ smooth_a = l1_smooth_trajectory(traj_a, smoothing_radius)
1251
 
1252
  # Tuzatish = tekislangan - asl trajectory
1253
  diff_x = smooth_x - traj_x
 
1270
 
1271
  cap = cv2.VideoCapture(video_path)
1272
 
1273
+ # Dinamik Inpainting uchun Original o'lchamni saqlab qolish
1274
+ out_w = width
1275
+ out_h = height
 
 
 
1276
 
1277
  temp_video_path = output_path + "_stab_temp.avi"
1278
  fourcc = cv2.VideoWriter_fourcc(*'MJPG')
1279
  writer = cv2.VideoWriter(temp_video_path, fourcc, fps, (out_w, out_h))
1280
 
1281
+ # Masshtabni ozgina (1.04) kattalashtirish orqali chetkalarni inpainting bilan qoplash matritsasi
1282
+ scale_dynamic_mat = cv2.getRotationMatrix2D((width / 2, height / 2), 0, 1.04)
1283
+
1284
+ ret, prev_first_frame = cap.read()
1285
  if not ret:
1286
  cap.release()
1287
  return None
1288
 
1289
+ writer.write(prev_first_frame)
 
 
1290
 
1291
  for i in range(len(smooth_transforms)):
1292
  ret, frame = cap.read()
 
1303
  [sin_a, cos_a, dy]
1304
  ], dtype=np.float64)
1305
 
1306
+ # Transformatsiyani qo'llash (BORDER_REFLECT_101 va Inpainting)
1307
  stabilized = cv2.warpAffine(
1308
  frame, transform_mat, (width, height),
1309
+ flags=cv2.INTER_LINEAR,
1310
+ borderMode=cv2.BORDER_REFLECT_101
1311
+ )
1312
+
1313
+ # Chekkalarda qora chiziq qolmasligi uchun 4% scale kattalashtirish qatlamini qo'llash
1314
+ final_stabilized = cv2.warpAffine(
1315
+ stabilized, scale_dynamic_mat, (width, height),
1316
+ flags=cv2.INTER_LINEAR,
1317
  borderMode=cv2.BORDER_REFLECT_101
1318
  )
1319
 
1320
+ writer.write(final_stabilized)
 
 
1321
 
1322
  if progress_callback and i % 5 == 0:
1323
  progress_callback(min(95, 55 + int(i / len(smooth_transforms) * 40)))
requirements.txt CHANGED
@@ -1,5 +1,5 @@
1
  python-telegram-bot[job-queue]
2
- opencv-python
3
  Pillow
4
  moviepy
5
  torch
 
1
  python-telegram-bot[job-queue]
2
+ opencv-contrib-python
3
  Pillow
4
  moviepy
5
  torch