MCPcopy
hub / github.com/vladmandic/sdnext / grade_image

Function grade_image

modules/processing_grading.py:205–259  ·  view source on GitHub ↗

Full grading pipeline: PIL -> GPU tensor -> kornia ops -> PIL.

(image: Image.Image, params: GradingParams)

Source from the content-addressed store, hash-verified

203
204
205def grade_image(image: Image.Image, params: GradingParams) -> Image.Image:
206 """Full grading pipeline: PIL -> GPU tensor -> kornia ops -> PIL."""
207 log.debug(f"Grading: params={params}")
208 kornia = _ensure_kornia()
209 arr = np.array(image).astype(np.float32) / 255.0
210 tensor = torch.from_numpy(arr).permute(2, 0, 1).unsqueeze(0)
211 tensor = tensor.to(device=devices.device, dtype=devices.dtype)
212
213 # basic adjustments
214 if params.brightness != 0:
215 tensor = kornia.enhance.adjust_brightness(tensor, params.brightness)
216 if params.contrast != 0:
217 tensor = kornia.enhance.adjust_contrast(tensor, 1.0 + params.contrast)
218 if params.saturation != 0:
219 tensor = kornia.enhance.adjust_saturation(tensor, 1.0 + params.saturation)
220 if params.hue != 0:
221 tensor = kornia.enhance.adjust_hue(tensor, params.hue * math.pi)
222 if params.gamma != 1.0:
223 tensor = kornia.enhance.adjust_gamma(tensor, params.gamma)
224 if params.sharpness != 0:
225 tensor = kornia.enhance.sharpness(tensor, 1.0 + params.sharpness * 4.0)
226 if params.color_temp != 6500:
227 tensor = _apply_color_temp(tensor, params.color_temp)
228
229 # tone adjustments
230 if params.shadows != 0 or params.midtones != 0 or params.highlights != 0:
231 tensor = _apply_shadows_midtones_highlights(tensor, params.shadows, params.midtones, params.highlights)
232 if params.clahe_clip > 0:
233 lab = kornia.color.rgb_to_lab(tensor)
234 L = lab[:, 0:1, :, :] / 100.0
235 L = kornia.enhance.equalize_clahe(L, clip_limit=params.clahe_clip, grid_size=(params.clahe_grid, params.clahe_grid))
236 lab[:, 0:1, :, :] = L * 100.0
237 tensor = kornia.color.lab_to_rgb(lab).clamp(0, 1)
238
239 # split toning
240 if params.shadows_tint != "#000000" or params.highlights_tint != "#ffffff":
241 tensor = _apply_split_toning(tensor, params.shadows_tint, params.highlights_tint, params.split_tone_balance)
242
243 # effects
244 if params.vignette > 0:
245 tensor = _apply_vignette(tensor, params.vignette)
246 if params.grain > 0:
247 tensor = _apply_grain(tensor, params.grain)
248
249 # convert back to PIL
250 tensor = tensor.clamp(0, 1)
251 arr = (tensor.squeeze(0).permute(1, 2, 0).float().cpu().numpy() * 255).astype(np.uint8)
252 result = Image.fromarray(arr)
253 result.info = image.info.copy() # Image.fromarray drops info; preserve so Process-tab metadata survives grading
254
255 # LUT applied last (CPU, via pillow-lut-tools)
256 if params.lut_cube_file:
257 result = _apply_lut(result, params.lut_cube_file, params.lut_strength)
258
259 return result

Callers 2

Calls 9

_ensure_korniaFunction · 0.85
_apply_color_tempFunction · 0.85
_apply_split_toningFunction · 0.85
_apply_vignetteFunction · 0.85
_apply_grainFunction · 0.85
_apply_lutFunction · 0.85
toMethod · 0.45
copyMethod · 0.45

Tested by 2