hansen97 commited on
Commit
47547b1
·
1 Parent(s): 1f3466c

ZeroGPU optimize

Browse files
Files changed (2) hide show
  1. app.py +2 -2
  2. app_function.py +61 -74
app.py CHANGED
@@ -130,7 +130,7 @@ with gr.Blocks(title="YOND WebUI", css="""
130
  bl = gr.Number(label="Black Level", value=64.0, precision=1, scale=1)
131
  wp = gr.Number(label="White Point", value=1023.0, precision=1, scale=1)
132
  ratio = gr.Number(label="DGain (x Ratio)", value=1.0, precision=1, scale=1)
133
- ispgain = gr.Number(label="ISPGain", value=1.0, precision=1, scale=1)
134
  with gr.Row():
135
  image_btn = gr.Button("Load Image", variant="primary")
136
  image_update_btn = gr.Button("Update Image", variant="secondary")
@@ -144,7 +144,7 @@ with gr.Blocks(title="YOND WebUI", css="""
144
 
145
  est_btn = gr.Button("Noise Estimation", variant="primary")
146
 
147
- use_ddim = gr.Checkbox(label="DDIM Mode", value=False, scale=1)
148
  with gr.Row():
149
  patch_size = gr.Number(label="Patch Size", value=1024, precision=0)
150
  sigsnr = gr.Number(label="SigSNR", precision=2, value=1.03)
 
130
  bl = gr.Number(label="Black Level", value=64.0, precision=1, scale=1)
131
  wp = gr.Number(label="White Point", value=1023.0, precision=1, scale=1)
132
  ratio = gr.Number(label="DGain (x Ratio)", value=1.0, precision=1, scale=1)
133
+ ispgain = gr.Number(label="ISPGain (Visual Only)", value=1.0, precision=1, scale=1)
134
  with gr.Row():
135
  image_btn = gr.Button("Load Image", variant="primary")
136
  image_update_btn = gr.Button("Update Image", variant="secondary")
 
144
 
145
  est_btn = gr.Button("Noise Estimation", variant="primary")
146
 
147
+ use_ddim = gr.Checkbox(label="DDIM Mode (Please use large model, e.g., gru64n)", value=False, scale=1)
148
  with gr.Row():
149
  patch_size = gr.Number(label="Patch Size", value=1024, precision=0)
150
  sigsnr = gr.Number(label="SigSNR", precision=2, value=1.03)
app_function.py CHANGED
@@ -221,6 +221,40 @@ class YOND_Backend:
221
  raise RuntimeError(f"图像更新失败: {str(e)}") from e
222
 
223
  @spaces.GPU
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  def estimate_noise(self, double_est, ransac, patch_size):
225
  """执行噪声估计"""
226
  if not self.yond:
@@ -246,49 +280,30 @@ class YOND_Backend:
246
 
247
  if double_est:
248
  log(" 使用精估计")
249
- lr_raw_np = lr_raw * self.p['scale']
250
- ######## EM-VST矫正VST噪图期望偏差 ########
251
- bias_base = np.maximum(lr_raw_np, 0)
252
- bias = self.bias_lut.get_lut(bias_base, K=self.p['gain'], sigGs=self.p['sigma'])
253
- raw_vst = VST(lr_raw_np, self.p['sigma'], gain=self.p['gain'])
254
- raw_vst = raw_vst - bias
255
-
256
- ################# VST变换 #################
257
- lower = VST(0, self.p['sigma'], gain=self.p['gain'])
258
- upper = VST(self.p['scale'], self.p['sigma'], gain=self.p['gain'])
259
- nsr = 1 / (upper - lower)
260
- raw_vst = (raw_vst - lower) / (upper - lower)
261
-
262
- ################# 准备去噪 #################
263
- self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
264
- self.yond.net = self.yond.net.to(self.device)
265
- raw_vst = torch.from_numpy(raw_vst).float().to(self.device).permute(2,0,1)[None,]
266
- if 'guided' in self.yond.arch:
267
- sigma_corr = 1.03
268
- t = torch.tensor(nsr*sigma_corr, dtype=raw_vst.dtype, device=self.device)
269
-
270
- # Denoise & pad
271
- target_size = patch_size # 设置目标块大小,可以根据需要调整
272
- overlap_ratio = 1/8 # 设置重叠率,可以根据需要调整
273
-
274
- # 使用改进的 big_image_split 函数
275
- raw_inp, metadata = big_image_split(raw_vst, target_size, overlap_ratio)
276
-
277
- raw_dn = torch.zeros_like(raw_inp[:,:4])
278
- with torch.no_grad():
279
- for i in range(raw_inp.shape[0]): # 处理所有切块
280
- input_tensor = raw_inp[i][None,].clip(None, 2).to(self.device)
281
- raw_dn[i] = self.yond.net(input_tensor, t).clamp(0,None)
282
-
283
- # 使用改进的 big_image_merge 函数
284
- raw_dn = big_image_merge(raw_dn, metadata, blend_mode='avg')
285
-
286
- ################# VST逆变换 #################
287
- raw_vst = raw_dn[0].permute(1,2,0).detach().cpu().numpy()
288
- raw_vst = raw_vst * (upper - lower) + lower
289
- raw_vst = inverse_VST(raw_vst, self.p['sigma'], gain=self.p['gain']) / self.p['scale']
290
-
291
- reg, self.mask_data = SimpleNLF(rggb2bayer(lr_raw), rggb2bayer(raw_vst), k=13,
292
  setting={'mode':'collab', 'thr_mode':'score3', 'ransac': self.p['ransac']})
293
  self.p['gain'] = reg[0] * self.p['scale']
294
  self.p['sigma'] = np.sqrt(max(reg[1], 0)) * self.p['scale']
@@ -302,7 +317,6 @@ class YOND_Backend:
302
  gr.Error(f"噪声估计失败: {str(e)}")
303
  raise RuntimeError(f"噪声估计失败: {str(e)}") from e
304
 
305
- @spaces.GPU
306
  def enhance_image(self, gain, sigma, sigsnr, ddim_mode, patch_size):
307
  """执行图像增强"""
308
  if not self.yond:
@@ -335,38 +349,11 @@ class YOND_Backend:
335
  raw_vst = (raw_vst - lower) / (upper - lower)
336
 
337
  ################# 准备去噪 #################
338
- self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
339
- self.yond.net = self.yond.net.to(self.device)
340
- raw_vst = torch.from_numpy(raw_vst).float().to(self.device).permute(2,0,1)[None,]
341
- if 'guided' in self.yond.arch:
342
- t = torch.tensor(nsr*self.p['sigsnr'], dtype=raw_vst.dtype, device=self.device)
343
-
344
- # Denoise & pad
345
- target_size = patch_size # 设置目标块大小,可以根据需要调整 GPU:1024
346
- overlap_ratio = 1/8 # 设置重叠率,可以根据需要调整
347
-
348
- # 使用改进的 big_image_split 函数
349
- raw_inp, metadata = big_image_split(raw_vst, target_size, overlap_ratio)
350
-
351
- raw_dn = torch.zeros_like(raw_inp[:,:4])
352
- with torch.no_grad():
353
- if self.p['ddim_mode']:
354
- for i in range(raw_inp.shape[0]): # 处理所有切块
355
- print(f'Patch: {i+1}/{len(raw_dn)}')
356
- raw_dn[i] = ddim(raw_inp[i][None,].clip(None, 2), self.yond.net, t, epoch=self.p['epoch'],
357
- sigma_t=self.p['sigma_t'], eta=self.p['eta_t'], sigma_corr=1.00)
358
- else:
359
- for i in range(raw_inp.shape[0]): # 处理所有切块
360
- input_tensor = raw_inp[i][None,].clip(None, 2)
361
- raw_dn[i] = self.yond.net(input_tensor, t).clamp(0,None)
362
-
363
- # 使用改进的 big_image_merge 函数
364
- raw_dn = big_image_merge(raw_dn, metadata, blend_mode='avg')
365
 
366
  ################# VST逆变换 #################
367
- raw_vst = raw_dn[0].permute(1,2,0).detach().cpu().numpy()
368
- raw_vst = raw_vst * (upper - lower) + lower
369
- self.denoised_data = inverse_VST(raw_vst, self.p['sigma'], gain=self.p['gain']) / self.p['scale']
370
 
371
  self.denoised_npy = rggb2bayer(self.denoised_data)
372
  # 保存结果
 
221
  raise RuntimeError(f"图像更新失败: {str(e)}") from e
222
 
223
  @spaces.GPU
224
+ def denoise(self, raw_vst, patch_size, nsr):
225
+ ################# 准备去噪 #################
226
+ self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
227
+ self.yond.net = self.yond.net.to(self.device)
228
+ raw_vst = torch.from_numpy(raw_vst).float().to(self.device).permute(2,0,1)[None,]
229
+ if 'guided' in self.yond.arch:
230
+ t = torch.tensor(nsr*self.p['sigsnr'], dtype=raw_vst.dtype, device=self.device).view(-1,1,1,1)
231
+
232
+ # Denoise & pad
233
+ target_size = patch_size # 设置目标块大小,可以根据需要调整 GPU:1024
234
+ overlap_ratio = 1/8 # 设置重叠率,可以根据需要调整
235
+
236
+ # 使用改进的 big_image_split 函数
237
+ raw_inp, metadata = big_image_split(raw_vst, target_size, overlap_ratio)
238
+
239
+ raw_dn = torch.zeros_like(raw_inp[:,:4])
240
+ with torch.no_grad():
241
+ if self.p['ddim_mode']:
242
+ for i in range(raw_inp.shape[0]): # 处理所有切块
243
+ print(f'Patch: {i+1}/{len(raw_dn)}')
244
+ raw_dn[i] = ddim(raw_inp[i][None,].clip(None, 2), self.yond.net, t, epoch=self.p['epoch'],
245
+ sigma_t=self.p['sigma_t'], eta=self.p['eta_t'], sigma_corr=1.00)
246
+ else:
247
+ for i in range(raw_inp.shape[0]): # 处理所有切块
248
+ input_tensor = raw_inp[i][None,].clip(None, 2)
249
+ raw_dn[i] = self.yond.net(input_tensor, t).clamp(0,None)
250
+
251
+ # 使用改进的 big_image_merge 函数
252
+ raw_dn = big_image_merge(raw_dn, metadata, blend_mode='avg')
253
+
254
+ ################# VST逆变换 #################
255
+ raw_dn = raw_dn[0].permute(1,2,0).detach().cpu().numpy()
256
+ return raw_dn
257
+
258
  def estimate_noise(self, double_est, ransac, patch_size):
259
  """执行噪声估计"""
260
  if not self.yond:
 
280
 
281
  if double_est:
282
  log(" 使用精估计")
283
+ if self.denoised_npy is None:
284
+ log(" 之前没去噪,先去噪再估计")
285
+ lr_raw_np = lr_raw * self.p['scale']
286
+ ######## EM-VST矫正VST噪图期望偏差 ########
287
+ bias_base = np.maximum(lr_raw_np, 0)
288
+ bias = self.bias_lut.get_lut(bias_base, K=self.p['gain'], sigGs=self.p['sigma'])
289
+ raw_vst = VST(lr_raw_np, self.p['sigma'], gain=self.p['gain'])
290
+ raw_vst = raw_vst - bias
291
+
292
+ ################# VST变换 #################
293
+ lower = VST(0, self.p['sigma'], gain=self.p['gain'])
294
+ upper = VST(self.p['scale'], self.p['sigma'], gain=self.p['gain'])
295
+ nsr = 1 / (upper - lower)
296
+ raw_vst = (raw_vst - lower) / (upper - lower)
297
+
298
+ ################# 去噪 #################
299
+ raw_dn = self.denoise(raw_vst, patch_size, nsr)
300
+
301
+ ################# VST逆变换 #################
302
+ raw_dn = raw_dn * (upper - lower) + lower
303
+ self.denoised_data = inverse_VST(raw_dn, self.p['sigma'], gain=self.p['gain']) / self.p['scale']
304
+ self.denoised_npy = rggb2bayer(self.denoised_data)
305
+
306
+ reg, self.mask_data = SimpleNLF(rggb2bayer(lr_raw), self.denoised_npy, k=13,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  setting={'mode':'collab', 'thr_mode':'score3', 'ransac': self.p['ransac']})
308
  self.p['gain'] = reg[0] * self.p['scale']
309
  self.p['sigma'] = np.sqrt(max(reg[1], 0)) * self.p['scale']
 
317
  gr.Error(f"噪声估计失败: {str(e)}")
318
  raise RuntimeError(f"噪声估计失败: {str(e)}") from e
319
 
 
320
  def enhance_image(self, gain, sigma, sigsnr, ddim_mode, patch_size):
321
  """执行图像增强"""
322
  if not self.yond:
 
349
  raw_vst = (raw_vst - lower) / (upper - lower)
350
 
351
  ################# 准备去噪 #################
352
+ raw_dn = self.denoise(raw_vst, patch_size, nsr)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
 
354
  ################# VST逆变换 #################
355
+ raw_dn = raw_dn * (upper - lower) + lower
356
+ self.denoised_data = inverse_VST(raw_dn, self.p['sigma'], gain=self.p['gain']) / self.p['scale']
 
357
 
358
  self.denoised_npy = rggb2bayer(self.denoised_data)
359
  # 保存结果