@@ -1414,19 +1414,21 @@ def render(modelTA, modelPV, samples_ddim, device, H, W, pixelSize, pixelvae, ti
1414
1414
x_sample = torch .clamp ((x_sample .cpu ().float ()), min = 0.0 , max = 1.0 )
1415
1415
x_sample = x_sample .cpu ().movedim (1 , - 1 )
1416
1416
x_sample = 255.0 * x_sample [0 ].cpu ().numpy ()
1417
- x_sample = Image .fromarray (np .clip (x_sample , 0 , 255 ).astype (np .uint8 ))
1417
+ x_sample = np .clip (x_sample , 0 , 255 ).astype (np .uint8 )
1418
+
1419
+ # Denoise the generated image
1420
+ x_sample = cv2 .fastNlMeansDenoisingColored (x_sample , None , 6 , 6 , 3 , 21 )
1418
1421
1419
1422
# Color adjustments to account for Tiny Autoencoder
1420
- contrast = ImageEnhance .Contrast (x_sample )
1423
+ contrast = ImageEnhance .Contrast (Image . fromarray ( x_sample ) )
1421
1424
x_sample_contrast = contrast .enhance (1.3 )
1422
1425
saturation = ImageEnhance .Color (x_sample_contrast )
1423
1426
x_sample_saturation = saturation .enhance (1.2 )
1424
1427
1425
1428
# Convert back to NumPy array if necessary
1426
1429
x_sample = np .array (x_sample_saturation )
1427
1430
1428
- # Denoise the generated image
1429
- x_sample = cv2 .fastNlMeansDenoisingColored (x_sample , None , 6 , 6 , 3 , 21 )
1431
+
1430
1432
except :
1431
1433
if "torch.cuda.OutOfMemoryError" in traceback .format_exc () or "Invalid buffer size" in traceback .format_exc ():
1432
1434
rprint (f"\n [#ab333d]Ran out of VRAM during decode, switching to fast pixel decoder" )
@@ -1591,6 +1593,7 @@ def manageComposition(lighting, composition, loras):
1591
1593
1592
1594
1593
1595
def prepare_inference (
1596
+ title ,
1594
1597
prompt ,
1595
1598
negative ,
1596
1599
translate ,
@@ -1690,7 +1693,7 @@ def prepare_inference(
1690
1693
seed_everything (seed )
1691
1694
1692
1695
rprint (
1693
- f"\n [#48a971]Text to Image [white] generating [#48a971]{ total_images } [white] quality [#48a971]{ quality } [white] images over [#48a971]{ runs } [white] batches with [#48a971]{ wtile } [white]x[#48a971]{ htile } [white] attention tiles at [#48a971]{ W } [white]x[#48a971]{ H } [white] ([#48a971]{ W // pixelSize } [white]x[#48a971]{ H // pixelSize } [white] pixels)"
1696
+ f"\n [#48a971]{ title } [white] generating [#48a971]{ total_images } [white] quality [#48a971]{ quality } [white] images over [#48a971]{ runs } [white] batches with [#48a971]{ wtile } [white]x[#48a971]{ htile } [white] attention tiles at [#48a971]{ W } [white]x[#48a971]{ H } [white] ([#48a971]{ W // pixelSize } [white]x[#48a971]{ H // pixelSize } [white] pixels)"
1694
1697
)
1695
1698
1696
1699
global model
@@ -2322,7 +2325,7 @@ def txt2img(
2322
2325
}
2323
2326
2324
2327
2325
- def neural_img2img (modelFileString , controlnets , prompt , negative , input_image , autocaption , translate , promptTuning , W , H , pixelSize , upscale , quality , scale , strength , lighting , composition , seed , total_images , maxBatchSize , device , precision , loras , tilingX , tilingY , preview , pixelvae , post ):
2328
+ def neural_img2img (modelFileString , title , controlnets , prompt , negative , input_image , autocaption , translate , promptTuning , W , H , pixelSize , upscale , quality , scale , strength , lighting , composition , seed , total_images , maxBatchSize , device , precision , loras , tilingX , tilingY , preview , pixelvae , post ):
2326
2329
timer = time .time ()
2327
2330
global modelCS
2328
2331
global modelTA
@@ -2349,8 +2352,10 @@ def neural_img2img(modelFileString, controlnets, prompt, negative, input_image,
2349
2352
rprint (f"[#48a971]Caption: [#494b9b]{ prompt } " )
2350
2353
2351
2354
conditioning , negative_conditioning , image_embed , steps , scale , runs , data , negative_data , seeds , batch , raw_loras = prepare_inference (
2352
- prompt , negative , translate , promptTuning , W , H , pixelSize , quality , scale , lighting , composition , seed , total_images , maxBatchSize , device , precision , loras , tilingX , tilingY , input_image , True )
2355
+ title , prompt , negative , translate , promptTuning , W , H , pixelSize , quality , scale , lighting , composition , seed , total_images , maxBatchSize , device , precision , loras , tilingX , tilingY , input_image , True )
2353
2356
2357
+ title = title .lower ().replace (' ' , '_' )
2358
+
2354
2359
model_patcher , cldm_cond , cldm_uncond = load_controlnet (
2355
2360
controlnets ,
2356
2361
W ,
@@ -2398,14 +2403,14 @@ def neural_img2img(modelFileString, controlnets, prompt, negative, input_image,
2398
2403
displayOut .append ({"name" : name , "seed" : seed + i , "format" : "bytes" , "image" : encodeImage (x_sample_image , "bytes" ), "width" : x_sample_image .width , "height" : x_sample_image .height })
2399
2404
yield {
2400
2405
"action" : "display_title" ,
2401
- "type" : "neural_pixelate" ,
2406
+ "type" : title ,
2402
2407
"value" : {
2403
2408
"text" : f"Generating... { step } /{ steps } steps in batch { run + 1 } /{ runs } "
2404
2409
},
2405
2410
}
2406
2411
yield {
2407
2412
"action" : "display_image" ,
2408
- "type" : "neural_pixelate" ,
2413
+ "type" : title ,
2409
2414
"value" : {
2410
2415
"images" : displayOut ,
2411
2416
"prompts" : data ,
@@ -2443,7 +2448,27 @@ def neural_img2img(modelFileString, controlnets, prompt, negative, input_image,
2443
2448
del samples_ddim
2444
2449
2445
2450
if post :
2446
- output = palettizeOutput (output )
2451
+ # Reduce input image to key colors
2452
+ palette_img = input_image .resize ((W // 8 , H // 8 ), resample = Image .Resampling .BILINEAR )
2453
+ numColors = determine_best_k (palette_img , 96 )
2454
+ palette_img = palette_img .quantize (colors = numColors , method = 1 , kmeans = numColors , dither = 0 ).convert ("RGB" )
2455
+
2456
+ # Extract palette colors
2457
+ palette = np .concatenate ([x [1 ] for x in palette_img .getcolors (96 )]).tolist ()
2458
+
2459
+ # Create a new palette image
2460
+ tempPaletteImage = Image .new ("P" , (256 , 1 ))
2461
+ tempPaletteImage .putpalette (palette )
2462
+
2463
+ # Convert generated image to reduced input image palette
2464
+ temp_output = output
2465
+ output = []
2466
+ for image in temp_output :
2467
+ tempImage = image ["image" ]
2468
+ # Perform quantization without dithering
2469
+ image_indexed = tempImage .quantize (method = 1 , kmeans = numColors , palette = tempPaletteImage , dither = 0 ).convert ("RGB" )
2470
+
2471
+ output .append ({"name" : image ["name" ], "seed" : image ["seed" ], "format" : image ["format" ], "image" : image_indexed , "width" : image ["width" ], "height" : image ["height" ]})
2447
2472
2448
2473
final = []
2449
2474
for image in output :
@@ -2454,7 +2479,7 @@ def neural_img2img(modelFileString, controlnets, prompt, negative, input_image,
2454
2479
)
2455
2480
yield {
2456
2481
"action" : "display_image" ,
2457
- "type" : "neural_pixelate" ,
2482
+ "type" : title ,
2458
2483
"value" : {"images" : final , "prompts" : data , "negatives" : negative_data },
2459
2484
}
2460
2485
@@ -2731,7 +2756,7 @@ def img2img(
2731
2756
displayOut = []
2732
2757
for i in range (batch ):
2733
2758
x_sample_image = fastRender (modelPV , samples_ddim [i :i + 1 ], pixelSize , W , H )
2734
- name = str (hash (str ([data [i ], negative_data [i ], images [ 0 ] .resize ((16 , 16 ), resample = Image .Resampling .NEAREST ), strength , translate , promptTuning , W , H , quality , scale , device , loras , tilingX , tilingY , pixelvae , seed + i ])) & 0x7FFFFFFFFFFFFFFF )
2759
+ name = str (hash (str ([data [i ], negative_data [i ], init_img .resize ((16 , 16 ), resample = Image .Resampling .NEAREST ), strength , translate , promptTuning , W , H , quality , scale , device , loras , tilingX , tilingY , pixelvae , seed + i ])) & 0x7FFFFFFFFFFFFFFF )
2735
2760
displayOut .append ({"name" : name , "seed" : seed + i , "format" : "bytes" , "image" : encodeImage (x_sample_image , "bytes" ), "width" : x_sample_image .width , "height" : x_sample_image .height })
2736
2761
yield {
2737
2762
"action" : "display_title" ,
@@ -2771,7 +2796,7 @@ def img2img(
2771
2796
play ("iteration.wav" )
2772
2797
2773
2798
seeds .append (str (seed ))
2774
- name = str (hash (str ([data [i ], negative_data [i ], images [ 0 ] .resize ((16 , 16 ), resample = Image .Resampling .NEAREST ), strength , translate , promptTuning , W , H , quality , scale , device , loras , tilingX , tilingY , pixelvae , seed ])) & 0x7FFFFFFFFFFFFFFF )
2799
+ name = str (hash (str ([data [i ], negative_data [i ], init_img .resize ((16 , 16 ), resample = Image .Resampling .NEAREST ), strength , translate , promptTuning , W , H , quality , scale , device , loras , tilingX , tilingY , pixelvae , seed ])) & 0x7FFFFFFFFFFFFFFF )
2775
2800
output .append ({"name" : name , "seed" : seed , "format" : "png" , "image" : x_sample_image , "width" : x_sample_image .width , "height" : x_sample_image .height })
2776
2801
2777
2802
seed += 1
@@ -3098,6 +3123,8 @@ async def server(websocket):
3098
3123
)
3099
3124
3100
3125
# Neural pixelate
3126
+ title = "Neural Pixelate"
3127
+
3101
3128
# Decode input image
3102
3129
init_img = decodeImage (values ["images" ][0 ])
3103
3130
@@ -3114,10 +3141,11 @@ async def server(websocket):
3114
3141
autocaption = True
3115
3142
3116
3143
# Net models, images, and weights in order
3117
- controlnets = [{"model_file" : "./models/controllora/Composition .safetensors" , "image" : image_blur , "weight" : 0.4 }]
3144
+ controlnets = [{"model_file" : "./models/controllora/Tile .safetensors" , "image" : image_blur , "weight" : 1.0 }, { "model_file" : "./models/controllora/Composition.safetensors" , "image" : image , "weight" : 0.7 }]
3118
3145
3119
3146
for result in neural_img2img (
3120
3147
modelData ["file" ],
3148
+ title ,
3121
3149
controlnets ,
3122
3150
values ["prompt" ],
3123
3151
values ["negative" ],
0 commit comments