Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -45,8 +45,9 @@ import threading
|
|
| 45 |
import io
|
| 46 |
from PIL import Image
|
| 47 |
|
| 48 |
-
# For
|
| 49 |
-
import
|
|
|
|
| 50 |
|
| 51 |
from google.oauth2 import service_account
|
| 52 |
from google.cloud import storage
|
|
@@ -176,6 +177,36 @@ def srgb_to_linear(img_tensor):
|
|
| 176 |
((img_tensor + 0.055) / 1.055).pow(2.4)
|
| 177 |
)
|
| 178 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
pipe, upscaler_2 = load_model()
|
| 180 |
|
| 181 |
fa_processor = FlashAttentionProcessor()
|
|
@@ -207,50 +238,22 @@ def generate_images(duration, prompt, neg_prompt_1, neg_prompt_2, neg_prompt_3,
|
|
| 207 |
guidance_scale=guidance, num_inference_steps=steps,
|
| 208 |
width=width, height=height, generator=generator,
|
| 209 |
max_sequence_length=384,
|
| 210 |
-
output_type="
|
| 211 |
-
|
| 212 |
|
| 213 |
# Convert the sRGB tensor [0,1] to a PIL Image for display and upscaling
|
| 214 |
sd_image_pil_srgb = Image.fromarray((sd_image_tensor_srgb.squeeze(0).permute(1, 2, 0).cpu().numpy() * 255).astype(np.uint8))
|
| 215 |
-
print('-- got image --')
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
# Convert the original sRGB tensor to linear space
|
| 227 |
-
sd_image_tensor_linear = srgb_to_linear(sd_image_tensor_srgb)
|
| 228 |
-
# Convert the linear tensor to a PIL Image (this will be HDR data)
|
| 229 |
-
sd_image_pil_linear = Image.fromarray((sd_image_tensor_linear.squeeze(0).permute(1, 2, 0).clamp(0, 1).cpu().numpy() * 255).astype(np.uint8))
|
| 230 |
-
|
| 231 |
-
# Save to a bytes buffer as JPEG Ultra HDR
|
| 232 |
-
buffer = io.BytesIO()
|
| 233 |
-
pillow_ultrahdr.save_ultrahdr(
|
| 234 |
-
sdr=sd_image_pil_srgb, # The standard dynamic range image
|
| 235 |
-
hdr=sd_image_pil_linear, # The linear (high dynamic range) image
|
| 236 |
-
outfile=buffer,
|
| 237 |
-
quality=90 # Standard JPEG quality setting
|
| 238 |
-
)
|
| 239 |
-
hdr_image_bytes = buffer.getvalue()
|
| 240 |
-
|
| 241 |
-
# For the upscaled image, we will do the same
|
| 242 |
-
# First convert upscaled PIL image to tensor, normalize to [0,1]
|
| 243 |
-
upscaled_tensor_srgb = torch.from_numpy(np.array(upscale2)).float().to(device) / 255.0
|
| 244 |
-
upscaled_tensor_srgb = upscaled_tensor_srgb.permute(2, 0, 1).unsqueeze(0) # HWC to BCHW
|
| 245 |
-
upscaled_tensor_linear = srgb_to_linear(upscaled_tensor_srgb)
|
| 246 |
-
upscaled_pil_linear = Image.fromarray((upscaled_tensor_linear.squeeze(0).permute(1, 2, 0).clamp(0, 1).cpu().numpy() * 255).astype(np.uint8))
|
| 247 |
-
|
| 248 |
-
upscaled_buffer = io.BytesIO()
|
| 249 |
-
pillow_ultrahdr.save_ultrahdr(sdr=upscale2, hdr=upscaled_pil_linear, outfile=upscaled_buffer, quality=95)
|
| 250 |
-
upscaled_hdr_image_bytes = upscaled_buffer.getvalue()
|
| 251 |
-
|
| 252 |
-
# Return the sRGB PIL image for display, and the HDR bytes for upload
|
| 253 |
-
return sd_image_pil_srgb, hdr_image_bytes, upscaled_hdr_image_bytes, prompt
|
| 254 |
|
| 255 |
return _generate()
|
| 256 |
|
|
|
|
| 45 |
import io
|
| 46 |
from PIL import Image
|
| 47 |
|
| 48 |
+
# For HDR
|
| 49 |
+
import pillow_avif
|
| 50 |
+
import cv2
|
| 51 |
|
| 52 |
from google.oauth2 import service_account
|
| 53 |
from google.cloud import storage
|
|
|
|
| 177 |
((img_tensor + 0.055) / 1.055).pow(2.4)
|
| 178 |
)
|
| 179 |
|
| 180 |
+
def create_hdr_avif_bytes(sdr_pil_image):
|
| 181 |
+
"""Converts an SDR PIL image to a 10-bit HDR AVIF byte buffer."""
|
| 182 |
+
# 1. Convert SDR PIL image to a float tensor [0, 1]
|
| 183 |
+
srgb_tensor = torch.from_numpy(np.array(sdr_pil_image)).float().to(device) / 255.0
|
| 184 |
+
srgb_tensor = srgb_tensor.permute(2, 0, 1).unsqueeze(0) # HWC to BCHW
|
| 185 |
+
|
| 186 |
+
# 2. Convert sRGB tensor to linear space
|
| 187 |
+
linear_tensor = srgb_to_linear(srgb_tensor)
|
| 188 |
+
|
| 189 |
+
# 3. Convert to 16-bit NumPy array for high-bit-depth processing
|
| 190 |
+
linear_numpy_float = linear_tensor.squeeze(0).permute(1, 2, 0).cpu().numpy()
|
| 191 |
+
hdr_16bit_array = (np.clip(linear_numpy_float, 0, 1) * 65535).astype(np.uint16)
|
| 192 |
+
|
| 193 |
+
# 4. Create a PIL image that holds the 16-bit data
|
| 194 |
+
hdr_pil_image = Image.fromarray(hdr_16bit_array)
|
| 195 |
+
|
| 196 |
+
# 5. Save to a bytes buffer as 10-bit AVIF with HDR10 metadata
|
| 197 |
+
buffer = io.BytesIO()
|
| 198 |
+
hdr_pil_image.save(
|
| 199 |
+
buffer,
|
| 200 |
+
format="AVIF",
|
| 201 |
+
quality=90,
|
| 202 |
+
depth=10, # Specify 10-bit depth
|
| 203 |
+
subsampling="4:4:4",
|
| 204 |
+
color_primaries=9, # BT.2020
|
| 205 |
+
transfer_characteristics=16, # PQ (Perceptual Quantizer)
|
| 206 |
+
matrix_coefficients=9, # BT.2020 non-constant luminance
|
| 207 |
+
)
|
| 208 |
+
return buffer.getvalue()
|
| 209 |
+
|
| 210 |
pipe, upscaler_2 = load_model()
|
| 211 |
|
| 212 |
fa_processor = FlashAttentionProcessor()
|
|
|
|
| 238 |
guidance_scale=guidance, num_inference_steps=steps,
|
| 239 |
width=width, height=height, generator=generator,
|
| 240 |
max_sequence_length=384,
|
| 241 |
+
output_type="pil" # Get PIL for display and easy upscaling
|
| 242 |
+
).images[0]
|
| 243 |
|
| 244 |
# Convert the sRGB tensor [0,1] to a PIL Image for display and upscaling
|
| 245 |
sd_image_pil_srgb = Image.fromarray((sd_image_tensor_srgb.squeeze(0).permute(1, 2, 0).cpu().numpy() * 255).astype(np.uint8))
|
| 246 |
+
print('-- got image, creating HDR AVIF version --')
|
| 247 |
+
sd_avif_bytes = create_hdr_avif_bytes(sd_image_srgb_pil)
|
| 248 |
+
|
| 249 |
+
print('-- upscaling image --')
|
| 250 |
+
with torch.no_grad():
|
| 251 |
+
upscale = upscaler_2(sd_image_srgb_pil, tiling=True, tile_width=256, tile_height=256)
|
| 252 |
+
upscale2 = upscaler_2(upscale, tiling=True, tile_width=256, tile_height=256)
|
| 253 |
+
print('-- got upscaled image, creating upscaled HDR AVIF --')
|
| 254 |
+
upscaled_avif_bytes = create_hdr_avif_bytes(upscale2)
|
| 255 |
+
|
| 256 |
+
return sd_image_srgb_pil, sd_avif_bytes, upscaled_avif_bytes, prompt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 257 |
|
| 258 |
return _generate()
|
| 259 |
|