File size: 62,449 Bytes
c4b726c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 |
import gradio as gr
import subprocess
import os
import imageio
import numpy as np
from gradio.outputs import Image
from PIL import Image
import sys
import cv2
import shutil
import time
import math
from modules import shared
from modules import scripts
from modules import script_callbacks
class Script(scripts.Script):
def title(self):
return "Abysz LAB"
def show(self, is_img2img):
return scripts.AlwaysVisible
def ui(self, is_img2img):
return []
def main(ruta_entrada_1, ruta_entrada_2, ruta_salida, denoise_blur, dfi_strength, dfi_deghost, test_mode, inter_denoise, inter_denoise_size, inter_denoise_speed, fine_blur, frame_refresh_frequency, refresh_strength, smooth, frames_limit):
maskD = os.path.join(os.getcwd(), 'extensions', 'Abysz-LAB-Ext', 'scripts', 'Run', 'MaskD')
maskS = os.path.join(os.getcwd(), 'extensions', 'Abysz-LAB-Ext', 'scripts', 'Run', 'MaskS')
#output = os.path.join(os.getcwd(), 'extensions', 'Abysz-LAB-Ext', 'scripts', 'Run', 'Output')
source = os.path.join(os.getcwd(), 'extensions', 'Abysz-LAB-Ext', 'scripts', 'Run', 'Source')
#gen = os.path.join(os.getcwd(), 'extensions', 'Abysz-LAB-Ext', 'scripts', 'Run', 'Gen')
# verificar si las carpetas existen y eliminarlas si es el caso
if os.path.exists(source): # verificar si existe la carpeta source
shutil.rmtree(source) # eliminar la carpeta source y su contenido
if os.path.exists(maskS): # verificar si existe la carpeta maskS
shutil.rmtree(maskS) # eliminar la carpeta maskS y su contenido
if os.path.exists(maskD): # verificar si existe la carpeta maskS
shutil.rmtree(maskD) # eliminar la carpeta maskS y su contenido
os.makedirs(source, exist_ok=True)
os.makedirs(maskS, exist_ok=True)
os.makedirs(ruta_salida, exist_ok=True)
os.makedirs(maskD, exist_ok=True)
#os.makedirs(gen, exist_ok=True)
def copy_images(ruta_entrada_1, ruta_entrada_2, frames_limit=0):
# Copiar todas las imágenes de la carpeta ruta_entrada_1 a la carpeta Source
count = 0
archivos = os.listdir(ruta_entrada_1)
archivos_ordenados = sorted(archivos)
for i, file in enumerate(archivos_ordenados):
if file.endswith(".jpg") or file.endswith(".jpeg") or file.endswith(".png"):
img = Image.open(os.path.join(ruta_entrada_1, file))
rgb_img = img.convert('RGB')
rgb_img.save(os.path.join("./extensions/Abysz-LAB-Ext/scripts/Run/Source", "{:04d}.jpeg".format(i+1)), "jpeg", quality=100)
count += 1
if frames_limit > 0 and count >= frames_limit:
break
# Llamar a la función copy_images para copiar las imágenes
copy_images(ruta_entrada_1,ruta_salida, frames_limit)
def sresize(ruta_entrada_2):
gen_folder = ruta_entrada_2
# Carpeta donde se encuentran las imágenes de FULL
full_folder = "./extensions/Abysz-LAB-Ext/scripts/Run/Source"
# Obtener la primera imagen en la carpeta Gen
gen_images = os.listdir(gen_folder)
gen_image_path = os.path.join(gen_folder, gen_images[0])
gen_image = cv2.imread(gen_image_path)
gen_height, gen_width = gen_image.shape[:2]
gen_aspect_ratio = gen_width / gen_height
# Recorrer todas las imágenes en la carpeta FULL
for image_name in sorted(os.listdir(full_folder)):
image_path = os.path.join(full_folder, image_name)
image = cv2.imread(image_path)
height, width = image.shape[:2]
aspect_ratio = width / height
if aspect_ratio != gen_aspect_ratio:
if aspect_ratio > gen_aspect_ratio:
# La imagen es más ancha que la imagen de Gen
crop_width = int(height * gen_aspect_ratio)
x = int((width - crop_width) / 2)
image = image[:, x:x+crop_width]
else:
# La imagen es más alta que la imagen de Gen
crop_height = int(width / gen_aspect_ratio)
y = int((height - crop_height) / 2)
image = image[y:y+crop_height, :]
# Redimensionar la imagen de FULL a la resolución de la imagen de Gen
image = cv2.resize(image, (gen_width, gen_height))
# Guardar la imagen redimensionada en la carpeta FULL
cv2.imwrite(os.path.join(full_folder, image_name), image)
sresize(ruta_entrada_2)
def s_g_rename(ruta_entrada_2):
gen_dir = ruta_entrada_2 # ruta de la carpeta "Source"
# Obtener una lista de los nombres de archivo en la carpeta ruta_entrada_2
files2 = os.listdir(gen_dir)
files2 = sorted(files2) # ordenar alfabéticamente la lista
# Renombrar cada archivo
for i, file_name in enumerate(files2):
old_path = os.path.join(gen_dir, file_name) # ruta actual del archivo
new_file_name = f"{i+1:04d}rename" # nuevo nombre de archivo con formato %04d
new_path = os.path.join(gen_dir, new_file_name + os.path.splitext(file_name)[1]) # nueva ruta del archivo
try:
os.rename(old_path, new_path)
except FileExistsError:
print(f"El archivo {new_file_name} ya existe. Se omite su renombre.")
# Obtener una lista de los nombres de archivo en la carpeta ruta_entrada_2
files2 = os.listdir(gen_dir)
files2 = sorted(files2) # ordenar alfabéticamente la lista
# Renombrar cada archivo
for i, file_name in enumerate(files2):
old_path = os.path.join(gen_dir, file_name) # ruta actual del archivo
new_file_name = f"{i+1:04d}" # nuevo nombre de archivo con formato %04d
new_path = os.path.join(gen_dir, new_file_name + os.path.splitext(file_name)[1]) # nueva ruta del archivo
try:
os.rename(old_path, new_path)
except FileExistsError:
print(f"El archivo {new_file_name} ya existe. Se omite su renombre.")
s_g_rename(ruta_entrada_2)
# Obtener el primer archivo de la carpeta ruta_entrada_2
gen_files = os.listdir(ruta_entrada_2)
if gen_files:
first_gen_file = gen_files[0]
# Copiar el archivo a la carpeta "Output" y reemplazar si ya existe
#output_file = "Output" + first_gen_file
#shutil.copyfile(ruta_entrada_2 + first_gen_file, output_file)
output_file = os.path.join(ruta_salida, first_gen_file)
shutil.copyfile(os.path.join(ruta_entrada_2, first_gen_file), output_file)
#subprocess call
def denoise(denoise_blur):
if denoise_blur < 1: # Condición 1: strength debe ser mayor a 1
return
denoise_kernel = denoise_blur
# Obtener la lista de nombres de archivos en la carpeta source
files = os.listdir("./extensions/Abysz-LAB-Ext/scripts/Run/Source")
# Crear una carpeta destino si no existe
#if not os.path.exists("dest"):
# os.mkdir("dest")
# Recorrer cada archivo en la carpeta source
for file in files:
# Leer la imagen con opencv
img = cv2.imread(os.path.join("./extensions/Abysz-LAB-Ext/scripts/Run/Source", file))
# Aplicar el filtro de blur con un tamaño de kernel 5x5
dst = cv2.bilateralFilter(img, denoise_kernel, 31, 31)
# Eliminar el archivo original
#os.remove(os.path.join("SourceDFI", file))
# Guardar la imagen resultante en la carpeta destino con el mismo nombre
cv2.imwrite(os.path.join("./extensions/Abysz-LAB-Ext/scripts/Run/Source", file), dst)
denoise(denoise_blur)
# Definir la carpeta donde están los archivos
carpeta = './extensions/Abysz-LAB-Ext/scripts/Run/Source'
# Crear la carpeta MaskD si no existe
os.makedirs('./extensions/Abysz-LAB-Ext/scripts/Run/MaskD', exist_ok=True)
# Inicializar contador
contador = 1
umbral_size = dfi_strength
# Iterar a través de los archivos de imagen en la carpeta Source
for filename in sorted(os.listdir(carpeta)):
# Cargar la imagen actual y la siguiente en escala de grises
if contador > 1:
siguiente = cv2.imread(os.path.join(carpeta, filename), cv2.IMREAD_GRAYSCALE)
diff = cv2.absdiff(anterior, siguiente)
# Aplicar un umbral y guardar la imagen resultante en la carpeta MaskD. Menos es más.
umbral = umbral_size
umbralizado = cv2.threshold(diff, umbral, 255, cv2.THRESH_BINARY_INV)[1] # Invertir los colores
cv2.imwrite(os.path.join('./extensions/Abysz-LAB-Ext/scripts/Run/MaskD', f'{contador-1:04d}.png'), umbralizado)
anterior = cv2.imread(os.path.join(carpeta, filename), cv2.IMREAD_GRAYSCALE)
contador += 1
#Actualmente, el tipo de umbralización es cv2.THRESH_BINARY_INV, que invierte los colores de la imagen umbralizada.
#Puedes cambiarlo a otro tipo de umbralización,
#como cv2.THRESH_BINARY, cv2.THRESH_TRUNC, cv2.THRESH_TOZERO o cv2.THRESH_TOZERO_INV.
# Obtener la lista de los nombres de los archivos en la carpeta MaskD
files = os.listdir("./extensions/Abysz-LAB-Ext/scripts/Run/MaskD")
# Definir la carpeta donde están los archivos
carpeta = "./extensions/Abysz-LAB-Ext/scripts/Run/MaskD"
blur_kernel = smooth
# Iterar sobre cada archivo
for file in files:
if dfi_deghost == 0:
continue
# Leer la imagen de la carpeta MaskD
#img = cv2.imread("MaskD" + file)
img = cv2.imread(os.path.join("./extensions/Abysz-LAB-Ext/scripts/Run/MaskD", file))
# Invertir la imagen usando la función bitwise_not()
img_inv = cv2.bitwise_not(img)
kernel_size = dfi_deghost
# Dilatar la imagen usando la función dilate()
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernel_size, kernel_size)) # Puedes cambiar el tamaño y la forma del kernel según tus preferencias
img_dil = cv2.dilate(img_inv, kernel)
# Volver a invertir la imagen usando la función bitwise_not()
img_out = cv2.bitwise_not(img_dil)
# Sobrescribir la imagen en la carpeta MaskD con el mismo nombre que el original
#cv2.imwrite("MaskD" + file, img_out)
#cv2.imwrite(os.path.join("MaskD", file, img_out))
filename = os.path.join("./extensions/Abysz-LAB-Ext/scripts/Run/MaskD", file)
cv2.imwrite(filename, img_out)
# Iterar a través de los archivos de imagen en la carpeta MaskD
if smooth > 1:
for imagen in os.listdir(carpeta):
if imagen.endswith(".jpg") or imagen.endswith(".png") or imagen.endswith(".jpeg"):
# Leer la imagen
img = cv2.imread(os.path.join(carpeta, imagen))
# Aplicar el filtro
img = cv2.GaussianBlur(img, (blur_kernel,blur_kernel),0)
# Guardar la imagen con el mismo nombre
cv2.imwrite(os.path.join(carpeta, imagen), img)
# INICIO DEL BATCH Obtener el nombre del archivo en MaskD sin ninguna extensión
# Agregar una variable de contador de bucles
loop_count = 0
# Agregar un bucle while para ejecutar el código en bucle infinito
while True:
mask_files = sorted(os.listdir(maskD))
if not mask_files:
print(f"No frames left")
# Eliminar las carpetas Source, MaskS y MaskD si no hay más archivos para procesar
shutil.rmtree(maskD)
shutil.rmtree(maskS)
shutil.rmtree(source)
break
extra_mod = fine_blur
mask = mask_files[0]
maskname = os.path.splitext(mask)[0]
maskp_path = os.path.join(maskD, mask)
img = cv2.imread(maskp_path, cv2.IMREAD_GRAYSCALE) # leer la imagen en escala de grises
n_white_pix = np.sum(img == 255) # contar los píxeles que son iguales a 255 (blanco)
total_pix = img.size # obtener el número total de píxeles en la imagen
percentage = (n_white_pix / total_pix) * 100 # calcular el porcentaje de píxeles blancos
percentage = round(percentage, 1) # redondear el porcentaje a 1 decimal
# calcular la variable extra
extra = 100 - percentage # restar el porcentaje a 100
extra = extra / 3 # dividir el resultado por 3
extra = math.ceil(extra) # redondear hacia arriba al entero más cercano
if extra % 2 == 0: # verificar si el número es par
extra = extra + 1 # sumarle 1 para hacerlo impar
# Dynamic Blur
imgb = cv2.imread(maskp_path) # leer la imagen con opencv
img_blur = cv2.GaussianBlur(imgb, (extra,extra),0)
# guardar la imagen modificada con el mismo nombre y ruta
cv2.imwrite(maskp_path, img_blur)
# Obtener la ruta de la imagen en la subcarpeta de output que tiene el mismo nombre que la imagen en MaskD
output_files = [f for f in os.listdir(ruta_salida) if os.path.splitext(f)[0] == maskname]
if not output_files:
print(f"No se encontró en {ruta_salida} una imagen con el mismo nombre que {maskname}.")
exit(1)
output_file = os.path.join(ruta_salida, output_files[0])
# Aplicar el comando magick composite con las opciones deseadas
composite_command = f"magick composite -compose CopyOpacity {os.path.join(maskD, mask)} {output_file} {os.path.join(maskS, 'result.png')}"
os.system(composite_command)
# Obtener el nombre del archivo en output sin ninguna extensión
name = os.path.splitext(os.path.basename(output_file))[0]
# Renombrar el archivo result.png con el nombre del archivo en output y la extensión .png
os.rename(os.path.join(maskS, 'result.png'), os.path.join(maskS, f"{name}.png"))
#Guardar el directorio actual en una variable
original_dir = os.getcwd()
#Cambiar al directorio de la carpeta MaskS
os.chdir(maskS)
#Iterar a través de los archivos de imagen en la carpeta MaskS
for imagen in sorted(os.listdir(".")):
# Obtener el nombre de la imagen sin la extensión
nombre, extension = os.path.splitext(imagen)
# Obtener solo el número de la imagen
numero = ''.join(filter(str.isdigit, nombre))
# Definir el nombre de la siguiente imagen
siguiente = f"{int(numero)+1:0{len(numero)}}{extension}"
# Renombrar la imagen
os.rename(imagen, siguiente)
# Volver al directorio original
os.chdir(original_dir)
# Establecer un valor predeterminado para disolución
if frame_refresh_frequency < 1:
dissolve = percentage
else:
dissolve = 100 if loop_count % frame_refresh_frequency != 0 else refresh_strength
# Obtener el nombre del archivo en MaskS sin la extensión
maskS_files = [f for f in os.listdir(maskS) if os.path.isfile(os.path.join(maskS, f)) and f.endswith('.png')]
if maskS_files:
filename = os.path.splitext(maskS_files[0])[0]
else:
print(f"No se encontraron archivos de imagen en la carpeta '{maskS}'")
filename = ''[0]
# Salir del bucle si no hay más imágenes que procesar
if not filename:
break
# Obtener la extensión del archivo en Gen con el mismo nombre
gen_files = [f for f in os.listdir(ruta_entrada_2) if os.path.isfile(os.path.join(ruta_entrada_2, f)) and f.startswith(filename)]
if gen_files:
ext = os.path.splitext(gen_files[0])[1]
else:
print(f"No se encontró ningún archivo con el nombre '{filename}' en la carpeta '{ruta_entrada_2}'")
ext = ''
# Componer la imagen de MaskS y Gen con disolución (si está definido) y guardarla en la carpeta de salida
os.system(f"magick composite {'-dissolve ' + str(dissolve) + '%' if dissolve is not None else ''} {maskS}/{filename}.png {ruta_entrada_2}/{filename}{ext} {ruta_salida}/{filename}{ext}")
denoise_loop = inter_denoise_speed
kernel1 = inter_denoise
kernel2 = inter_denoise_size
# Demo plus bilateral
if loop_count % denoise_loop == 0:
# listar archivos en la carpeta de salida
archivos = os.listdir(ruta_salida)
# obtener el último archivo
ultimo_archivo = os.path.join(ruta_salida, archivos[-1])
# cargar imagen con opencv
imagen = cv2.imread(ultimo_archivo)
# aplicar filtro bilateral
imagen_filtrada = cv2.bilateralFilter(imagen, kernel1, kernel2, kernel2)
# sobreescribir el original
cv2.imwrite(ultimo_archivo, imagen_filtrada)
# Obtener el nombre del archivo más bajo en la carpeta MaskD
maskd_files = [f for f in os.listdir(maskD) if os.path.isfile(os.path.join(maskD, f)) and f.startswith('')]
if maskd_files:
maskd_file = os.path.join(maskD, sorted(maskd_files)[0])
os.remove(maskd_file)
# Obtener el nombre del archivo más bajo en la carpeta MaskS
masks_files = [f for f in os.listdir(maskS) if os.path.isfile(os.path.join(maskS, f)) and f.startswith('')]
if masks_files:
masks_file = os.path.join(maskS, sorted(masks_files)[0])
os.remove(masks_file)
# Aumentar el contador de bucles
loop_count += 1
def dyndef(ruta_entrada_3, ruta_salida_1, ddf_strength):
if ddf_strength <= 0: # Condición 1: strength debe ser mayor a 0
return
imgs = []
files = sorted(os.listdir(ruta_entrada_3))
for file in files:
img = cv2.imread(os.path.join(ruta_entrada_3, file))
imgs.append(img)
for idx in range(len(imgs)-1, 0, -1):
current_img = imgs[idx]
prev_img = imgs[idx-1]
alpha = ddf_strength
current_img = cv2.addWeighted(current_img, alpha, prev_img, 1-alpha, 0)
imgs[idx] = current_img
if not os.path.exists(ruta_salida_1):
os.makedirs(ruta_salida_1)
output_path = os.path.join(ruta_salida_1, files[idx]) # Usa el mismo nombre que el original
cv2.imwrite(output_path, current_img)
# Copia el primer archivo de los originales al finalizar el proceso
shutil.copy(os.path.join(ruta_entrada_3, files[0]), os.path.join(ruta_salida_1, files[0]))
def overlay_images(image1_path, image2_path, over_strength):
opacity = over_strength
# Abrir las imágenes
image1 = Image.open(image1_path).convert('RGBA')
image2 = Image.open(image2_path).convert('RGBA')
# Alinear el tamaño de las imágenes
if image1.size != image2.size:
image2 = image2.resize(image1.size)
# Convertir las imágenes en matrices NumPy
np_image1 = np.array(image1).astype(np.float64) / 255.0
np_image2 = np.array(image2).astype(np.float64) / 255.0
# Aplicar el método de fusión "overlay" a las imágenes
def basic(target, blend, opacity):
return target * opacity + blend * (1-opacity)
def blender(func):
def blend(target, blend, opacity=1, *args):
res = func(target, blend, *args)
res = basic(res, blend, opacity)
return np.clip(res, 0, 1)
return blend
class Blend:
@classmethod
def method(cls, name):
return getattr(cls, name)
normal = basic
@staticmethod
@blender
def overlay(target, blend, *args):
return (target>0.5) * (1-(2-2*target)*(1-blend)) +\
(target<=0.5) * (2*target*blend)
blended_image = Blend.overlay(np_image1, np_image2, opacity)
# Convertir la matriz de vuelta a una imagen PIL
blended_image = Image.fromarray((blended_image * 255).astype(np.uint8), 'RGBA').convert('RGB')
# Guardar la imagen resultante
return blended_image
def overlay_images2(image1_path, image2_path, fuse_strength):
opacity = fuse_strength
try:
image1 = Image.open(image1_path).convert('RGBA')
image2 = Image.open(image2_path).convert('RGBA')
except:
print("No more frames to fuse.")
return
# Alinear el tamaño de las imágenes
if image1.size != image2.size:
image1 = image1.resize(image2.size)
# Convertir las imágenes en matrices NumPy
np_image1 = np.array(image1).astype(np.float64) / 255.0
np_image2 = np.array(image2).astype(np.float64) / 255.0
# Aplicar el método de fusión "overlay" a las imágenes
def basic(target, blend, opacity):
return target * opacity + blend * (1-opacity)
def blender(func):
def blend(target, blend, opacity=1, *args):
res = func(target, blend, *args)
res = basic(res, blend, opacity)
return np.clip(res, 0, 1)
return blend
class Blend:
@classmethod
def method(cls, name):
return getattr(cls, name)
normal = basic
@staticmethod
@blender
def overlay(target, blend, *args):
return (target>0.5) * (1-(2-2*target)*(1-blend)) +\
(target<=0.5) * (2*target*blend)
blended_image = Blend.overlay(np_image1, np_image2, opacity)
# Convertir la matriz de vuelta a una imagen PIL
blended_image = Image.fromarray((blended_image * 255).astype(np.uint8), 'RGBA').convert('RGB')
# Guardar la imagen resultante
return blended_image
def overlay_run(ruta_entrada_3, ruta_salida_1, ddf_strength, over_strength):
if over_strength <= 0: # Condición 1: strength debe ser mayor a 0
return
# Si ddf_strength y/o over_strength son mayores a 0, utilizar ruta_salida_1 en lugar de ruta_entrada_3
if ddf_strength > 0:
ruta_entrada_3 = ruta_salida_1
if not os.path.exists("overtemp"):
os.makedirs("overtemp")
if not os.path.exists(ruta_salida_1):
os.makedirs(ruta_salida_1)
gen_path = ruta_entrada_3
images = sorted(os.listdir(gen_path))
image1_path = os.path.join(gen_path, images[0])
image2_path = os.path.join(gen_path, images[1])
fused_image = overlay_images(image1_path, image2_path, over_strength)
fuseover_path = "overtemp"
filename = os.path.basename(image1_path)
fused_image.save(os.path.join(fuseover_path, filename))
# Obtener una lista de todos los archivos en la carpeta "Gen"
gen_files = sorted(os.listdir(ruta_entrada_3))
for i in range(len(gen_files) - 1):
image1_path = os.path.join(ruta_entrada_3, gen_files[i])
image2_path = os.path.join(ruta_entrada_3, gen_files[i+1])
blended_image = overlay_images(image1_path, image2_path, over_strength)
blended_image.save(os.path.join("overtemp", gen_files[i+1]))
# Definimos la ruta de la carpeta "overtemp"
ruta_overtemp = "overtemp"
# Movemos todos los archivos de la carpeta "overtemp" a la carpeta "ruta_salida"
for archivo in os.listdir(ruta_overtemp):
origen = os.path.join(ruta_overtemp, archivo)
destino = os.path.join(ruta_salida_1, archivo)
shutil.move(origen, destino)
# Ajustar contraste y brillo para cada imagen en la carpeta de entrada
if over_strength >= 0.4:
for nombre_archivo in os.listdir(ruta_salida_1):
# Cargar imagen
ruta_archivo = os.path.join(ruta_salida_1, nombre_archivo)
img = cv2.imread(ruta_archivo)
# Ajustar contraste y brillo
alpha = 1 # Factor de contraste (mayor que 1 para aumentar el contraste)
beta = 10 # Valor de brillo (entero positivo para aumentar el brillo)
img_contrast = cv2.convertScaleAbs(img, alpha=alpha, beta=beta)
# Guardar imagen resultante en la carpeta de salida
ruta_salida = os.path.join(ruta_salida_1, nombre_archivo)
cv2.imwrite(ruta_salida, img_contrast)
def over_fuse(ruta_entrada_4, ruta_entrada_5, ruta_salida_2, fuse_strength):
# Obtener una lista de todos los archivos en la carpeta "Gen"
gen_files = os.listdir(ruta_entrada_4)
# Ordenar la lista de archivos alfabéticamente
gen_files.sort()
# Obtener una lista de todos los archivos en la carpeta "Source"
source_files = os.listdir(ruta_entrada_5)
# Ordenar la lista de archivos alfabéticamente
source_files.sort()
if not os.path.exists(ruta_salida_2):
os.makedirs(ruta_salida_2)
for i in range(len(gen_files)):
image1_path = os.path.join(ruta_entrada_4, gen_files[i])
image2_path = os.path.join(ruta_entrada_5, source_files[i])
blended_image = overlay_images2(image1_path, image2_path, fuse_strength)
try:
blended_image.save(os.path.join(ruta_salida_2, gen_files[i]))
except Exception as e:
print("Error al guardar la imagen:", str(e))
print("No more frames to fuse")
break
def norm(ruta_entrada_3, ruta_salida_1, ddf_strength, over_strength, norm_strength):
if norm_strength <= 0: # Condición 1: Norm_strength debe ser mayor a 0
return
# Si ddf_strength y/o over_strength son mayores a 0, utilizar ruta_salida_1 en lugar de ruta_entrada_3
if ddf_strength > 0 or over_strength > 0:
ruta_entrada_3 = ruta_salida_1
# Crear la carpeta GenOverNorm si no existe
if not os.path.exists("normtemp"):
os.makedirs("normtemp")
if not os.path.exists(ruta_salida_1):
os.makedirs(ruta_salida_1)
# Obtener una lista de todas las imágenes en la carpeta FuseOver
img_list = os.listdir(ruta_entrada_3)
img_list.sort() # Ordenar la lista en orden ascendente
# Iterar a través de las imágenes
for i in range(len(img_list)-1):
# Cargar las dos imágenes a fusionar
img1 = cv2.imread(os.path.join(ruta_entrada_3, img_list[i]))
img2 = cv2.imread(os.path.join(ruta_entrada_3, img_list[i+1]))
# Calcular la luminosidad promedio de cada imagen
avg1 = np.mean(cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY))
avg2 = np.mean(cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY))
# Calcular los pesos para cada imagen
weight1 = avg1 / (avg1 + avg2)
weight2 = avg2 / (avg1 + avg2)
# Fusionar las imágenes utilizando los pesos
result = cv2.addWeighted(img1, weight1, img2, weight2, 0)
# Guardar la imagen resultante en la carpeta GenOverNorm con el mismo nombre que la imagen original
cv2.imwrite(os.path.join("normtemp", img_list[i+1]), result)
# Copiar la primera imagen en la carpeta GenOverNorm para mantener la secuencia completa
img0 = cv2.imread(os.path.join(ruta_entrada_3, img_list[0]))
cv2.imwrite(os.path.join("normtemp", img_list[0]), img0)
# Definimos la ruta de la carpeta "overtemp"
ruta_overtemp = "normtemp"
# Movemos todos los archivos de la carpeta "overtemp" a la carpeta "ruta_salida"
for archivo in os.listdir(ruta_overtemp):
origen = os.path.join(ruta_overtemp, archivo)
destino = os.path.join(ruta_salida_1, archivo)
shutil.move(origen, destino)
def deflickers(ruta_entrada_3, ruta_salida_1, ddf_strength, over_strength, norm_strength):
dyndef(ruta_entrada_3, ruta_salida_1, ddf_strength)
overlay_run(ruta_entrada_3, ruta_salida_1, ddf_strength, over_strength)
norm(ruta_entrada_3, ruta_salida_1, ddf_strength, over_strength, norm_strength)
def extract_video(ruta_entrada_6, ruta_salida_3, fps_count):
# Ruta del archivo de video
filename = ruta_entrada_6
# Directorio donde se guardarán los frames extraídos
output_dir = ruta_salida_3
# Abrir el archivo de video
cap = cv2.VideoCapture(filename)
# Obtener los FPS originales del video
fps = cap.get(cv2.CAP_PROP_FPS)
# Si fps_count es 0, utilizar los FPS originales
if fps_count == 0:
fps_count = fps
# Calcular el tiempo entre cada frame a extraer en milisegundos
frame_time = int(round(1000 / fps_count))
# Crear el directorio de salida si no existe
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# Inicializar el contador de frames
frame_count = 0
# Inicializar el tiempo del último frame extraído
last_frame_time = 0
# Iterar sobre los frames del video
while True:
# Leer el siguiente frame
ret, frame = cap.read()
# Si no se pudo leer un frame, salir del loop
if not ret:
break
# Calcular el tiempo actual del frame en milisegundos
current_frame_time = int(round(cap.get(cv2.CAP_PROP_POS_MSEC)))
# Si todavía no ha pasado suficiente tiempo desde el último frame extraído, saltar al siguiente frame
if current_frame_time - last_frame_time < frame_time:
continue
# Incrementar el contador de frames
frame_count += 1
# Construir el nombre del archivo de salida
output_filename = os.path.join(output_dir, 'frame_{:04d}.jpeg'.format(frame_count))
# Guardar el frame como una imagen
cv2.imwrite(output_filename, frame)
# Actualizar el tiempo del último frame extraído
last_frame_time = current_frame_time
# Cerrar el archivo de video
cap.release()
# Mostrar información sobre el proceso finalizado
print("Extracted {} frames.".format(frame_count))
def test_dfi(ruta_entrada_1, ruta_entrada_2, denoise_blur, dfi_strength, dfi_deghost, test_mode, smooth):
maskD = os.path.join(os.getcwd(), 'extensions', 'Abysz-LAB-Ext', 'scripts', 'Run', 'MaskDT')
#maskS = os.path.join(os.getcwd(), 'extensions', 'Abysz-LAB-Ext', 'scripts', 'Run', 'MaskST')
#output = os.path.join(os.getcwd(), 'extensions', 'Abysz-lab', 'scripts', 'Run', 'Output')
source = os.path.join(os.getcwd(), 'extensions', 'Abysz-LAB-Ext', 'scripts', 'Run', 'SourceT')
#gen = os.path.join(os.getcwd(), 'extensions', 'Abysz-LAB-Ext', 'scripts', 'Run', 'GenT')
# verificar si las carpetas existen y eliminarlas si es el caso
if os.path.exists(source): # verificar si existe la carpeta source
shutil.rmtree(source) # eliminar la carpeta source y su contenido
#if os.path.exists(maskS): # verificar si existe la carpeta maskS
# shutil.rmtree(maskS) # eliminar la carpeta maskS y su contenido
if os.path.exists(maskD): # verificar si existe la carpeta maskS
shutil.rmtree(maskD) # eliminar la carpeta maskS y su contenido
#if os.path.exists(gen): # verificar si existe la carpeta maskS
# shutil.rmtree(gen) # eliminar la carpeta maskS y su contenido
#if os.path.exists(output): # verificar si existe la carpeta maskS
# shutil.rmtree(output) # eliminar la carpeta maskS y su contenido
os.makedirs(source, exist_ok=True)
#os.makedirs(maskS, exist_ok=True)
#os.makedirs(output, exist_ok=True)
os.makedirs(maskD, exist_ok=True)
#os.makedirs(gen, exist_ok=True)
def copy_images(ruta_entrada_1, ruta_entrada_2):
if test_mode == 0:
# Usar el primer formato
indices = [10, 11, 20, 21, 30, 31] # Los índices de las imágenes que quieres copiar
else:
test_frames = test_mode
# Usar el segundo formato
indices = list(range(test_frames)) # Los primeros 30 índices
# Copiar todas las imágenes de la carpeta ruta_entrada_1 a la carpeta Source
for i in indices:
file = os.listdir(ruta_entrada_1)[i] # Obtener el nombre del archivo en el índice i
if file.endswith(".jpg") or file.endswith(".jpeg") or file.endswith(".png"): # Verificar que sea una imagen
img = Image.open(os.path.join(ruta_entrada_1, file)) # Abrir la imagen
rgb_img = img.convert('RGB') # Convertir a RGB
rgb_img.save(os.path.join("./extensions/Abysz-LAB-Ext/scripts/Run/SourceT", "{:04d}.jpeg".format(i+1)), "jpeg", quality=100) # Guardar la imagen en la carpeta destino
# Llamar a la función copy_images para copiar las imágenes
copy_images(ruta_entrada_1, ruta_entrada_2)
# Carpeta donde se encuentran las imágenes de Gen
def sresize(ruta_entrada_2):
gen_folder = ruta_entrada_2
# Carpeta donde se encuentran las imágenes de FULL
full_folder = "./extensions/Abysz-LAB-Ext/scripts/Run/SourceT"
# Obtener la primera imagen en la carpeta Gen
gen_images = os.listdir(gen_folder)
gen_image_path = os.path.join(gen_folder, gen_images[0])
gen_image = cv2.imread(gen_image_path)
gen_height, gen_width = gen_image.shape[:2]
gen_aspect_ratio = gen_width / gen_height
# Recorrer todas las imágenes en la carpeta FULL
for image_name in os.listdir(full_folder):
image_path = os.path.join(full_folder, image_name)
image = cv2.imread(image_path)
height, width = image.shape[:2]
aspect_ratio = width / height
if aspect_ratio != gen_aspect_ratio:
if aspect_ratio > gen_aspect_ratio:
# La imagen es más ancha que la imagen de Gen
crop_width = int(height * gen_aspect_ratio)
x = int((width - crop_width) / 2)
image = image[:, x:x+crop_width]
else:
# La imagen es más alta que la imagen de Gen
crop_height = int(width / gen_aspect_ratio)
y = int((height - crop_height) / 2)
image = image[y:y+crop_height, :]
# Redimensionar la imagen de FULL a la resolución de la imagen de Gen
image = cv2.resize(image, (gen_width, gen_height))
# Guardar la imagen redimensionada en la carpeta FULL
cv2.imwrite(os.path.join(full_folder, image_name), image)
sresize(ruta_entrada_2)
def denoise(denoise_blur):
if denoise_blur < 1:
return
denoise_kernel = denoise_blur
# Obtener la lista de nombres de archivos en la carpeta source
files = os.listdir("./extensions/Abysz-LAB-Ext/scripts/Run/SourceT")
# Crear una carpeta destino si no existe
#if not os.path.exists("dest"):
# os.mkdir("dest")
# Recorrer cada archivo en la carpeta source
for file in files:
# Leer la imagen con opencv
img = cv2.imread(os.path.join("./extensions/Abysz-LAB-Ext/scripts/Run/SourceT", file))
# Aplicar el filtro de blur con un tamaño de kernel 5x5
dst = cv2.bilateralFilter(img, denoise_kernel, 31, 31)
# Eliminar el archivo original
#os.remove(os.path.join("SourceDFI", file))
# Guardar la imagen resultante en la carpeta destino con el mismo nombre
cv2.imwrite(os.path.join("./extensions/Abysz-LAB-Ext/scripts/Run/SourceT", file), dst)
denoise(denoise_blur)
# Definir la carpeta donde están los archivos
carpeta = './extensions/Abysz-LAB-Ext/scripts/Run/SourceT'
# Crear la carpeta MaskD si no existe
os.makedirs('./extensions/Abysz-LAB-Ext/scripts/Run/MaskDT', exist_ok=True)
# Inicializar número de imagen
numero = 1
umbral_size = dfi_strength
# Iterar a través de los archivos de imagen en la carpeta Source
for filename in sorted(os.listdir(carpeta)):
if test_mode == 0:
# Cargar la imagen actual en escala de grises
actual = cv2.imread(os.path.join(carpeta, filename), cv2.IMREAD_GRAYSCALE)
# Si el número de imagen es par, procesar la imagen actual y la anterior
if numero % 2 == 0:
diff = cv2.absdiff(anterior, actual)
# Aplicar un umbral y guardar la imagen resultante en la carpeta MaskD con el mismo nombre que el original. Menos es más.
umbral = umbral_size
umbralizado = cv2.threshold(diff, umbral, 255, cv2.THRESH_BINARY_INV)[1] # Invertir los colores
cv2.imwrite(os.path.join('./extensions/Abysz-LAB-Ext/scripts/Run/MaskDT', filename), umbralizado)
# Guardar la imagen actual como anterior para el siguiente ciclo
anterior = actual
# Incrementar el número de imagen para alternar entre pares e impares
numero += 1
else:
# Iterar a través de los archivos de imagen en la carpeta Source
for filename in sorted(os.listdir(carpeta)):
# Cargar la imagen actual y la siguiente en escala de grises
if numero > 1:
siguiente = cv2.imread(os.path.join(carpeta, filename), cv2.IMREAD_GRAYSCALE)
diff = cv2.absdiff(anterior, siguiente)
# Aplicar un umbral y guardar la imagen resultante en la carpeta MaskD. Menos es más.
umbral = umbral_size
umbralizado = cv2.threshold(diff, umbral, 255, cv2.THRESH_BINARY_INV)[1] # Invertir los colores
cv2.imwrite(os.path.join('./extensions/Abysz-LAB-Ext/scripts/Run/MaskDT', filename), umbralizado)
anterior = cv2.imread(os.path.join(carpeta, filename), cv2.IMREAD_GRAYSCALE)
numero += 1
# Obtener la lista de los nombres de los archivos en la carpeta MaskD
files = os.listdir("./extensions/Abysz-LAB-Ext/scripts/Run/MaskDT")
# Definir la carpeta donde están los archivos
carpeta = "./extensions/Abysz-LAB-Ext/scripts/Run/MaskDT"
blur_kernel = smooth
# Iterar sobre cada archivo
for file in files:
if dfi_deghost == 0:
continue
# Leer la imagen de la carpeta MaskD
#img = cv2.imread("MaskD" + file)
img = cv2.imread(os.path.join("./extensions/Abysz-LAB-Ext/scripts/Run/MaskDT", file))
# Invertir la imagen usando la función bitwise_not()
img_inv = cv2.bitwise_not(img)
kernel_size = dfi_deghost
# Dilatar la imagen usando la función dilate()
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernel_size, kernel_size)) # Puedes cambiar el tamaño y la forma del kernel según tus preferencias
img_dil = cv2.dilate(img_inv, kernel)
# Volver a invertir la imagen usando la función bitwise_not()
img_out = cv2.bitwise_not(img_dil)
# Sobrescribir la imagen en la carpeta MaskD con el mismo nombre que el original
#cv2.imwrite("MaskD" + file, img_out)
#cv2.imwrite(os.path.join("MaskD", file, img_out))
filename = os.path.join("./extensions/Abysz-LAB-Ext/scripts/Run/MaskDT", file)
cv2.imwrite(filename, img_out)
# Iterar a través de los archivos de imagen en la carpeta MaskD
if smooth > 1:
for imagen in os.listdir(carpeta):
if imagen.endswith(".jpg") or imagen.endswith(".png") or imagen.endswith(".jpeg"):
# Leer la imagen
img = cv2.imread(os.path.join(carpeta, imagen))
# Aplicar el filtro
img = cv2.GaussianBlur(img, (blur_kernel,blur_kernel),0)
# Guardar la imagen con el mismo nombre
cv2.imwrite(os.path.join(carpeta, imagen), img)
if test_mode == 0:
nombres = os.listdir("./extensions/Abysz-LAB-Ext/scripts/Run/MaskDT") # obtener los nombres de los archivos en la carpeta MaskDT
ancho = 0 # variable para guardar el ancho acumulado de las ventanas
for i, nombre in enumerate(nombres): # recorrer cada nombre de archivo
imagen = cv2.imread("./extensions/Abysz-LAB-Ext/scripts/Run/MaskDT/" + nombre) # leer la imagen correspondiente
h, w, c = imagen.shape # obtener el alto, ancho y canales de la imagen
aspect_ratio = w / h # calcular la relación de aspecto
cv2.namedWindow(nombre, cv2.WINDOW_NORMAL) # crear una ventana con el nombre del archivo
ancho_ventana = 630 # definir un ancho fijo para las ventanas
alto_ventana = int(ancho_ventana / aspect_ratio) # calcular el alto proporcional al ancho y a la relación de aspecto
cv2.resizeWindow(nombre, ancho_ventana, alto_ventana) # cambiar el tamaño de la ventana según las dimensiones calculadas
cv2.moveWindow(nombre, ancho, 0) # mover la ventana a una posición horizontal según el ancho acumulado
cv2.imshow(nombre, imagen) # mostrar la imagen en la ventana
cv2.setWindowProperty(nombre,cv2.WND_PROP_TOPMOST,1.0) # poner la ventana en primer plano con un valor double
ancho += ancho_ventana + 10 # aumentar el ancho acumulado en 410 píxeles para la siguiente ventana
cv2.waitKey(4000) # esperar a que se presione una tecla para cerrar todas las ventanas
cv2.destroyAllWindows() # cerrar todas las ventanas abiertas por OpenCV
else:
# Directorio de entrada de imágenes
ruta_entrada = "./extensions/Abysz-LAB-Ext/scripts/Run/MaskDT"
# Obtener el tamaño de la primera imagen en el directorio de entrada
img_path = os.path.join(ruta_entrada, os.listdir(ruta_entrada)[0])
img = cv2.imread(img_path)
img_size = (img.shape[1], img.shape[0])
# Fps del video
fps = 10
# Crear objeto VideoWriter
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video_salida = cv2.VideoWriter('output.mp4', fourcc, fps, img_size)
# Crear ventana con nombre "video"
cv2.namedWindow("video")
# Establecer la ventana en primer plano
cv2.setWindowProperty("video", cv2.WND_PROP_TOPMOST,1.0)
# Crear ventana de visualización
# Leer imágenes en el directorio y agregarlas al video de salida
for file in sorted(os.listdir(ruta_entrada)):
if file.endswith(".jpg") or file.endswith(".jpeg") or file.endswith(".png"): # Verificar que sea una imagen
img = cv2.imread(os.path.join(ruta_entrada, file)) # Leer la imagen
#img_resized = cv2.resize(img, img_size) # Redimensionar la imagen
video_salida.write(img) # Agregar la imagen al video
# Liberar el objeto VideoWriter
video_salida.release()
# Crear objeto VideoCapture para leer el archivo de video recién creado
video_capture = cv2.VideoCapture('output.mp4')
# Crear ventana con nombre "video"
cv2.namedWindow("video")
# Establecer la ventana en primer plano
cv2.setWindowProperty("video", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_NORMAL)
# Mostrar el video en una ventana
while True:
ret, img = video_capture.read()
if ret:
cv2.imshow('video', img)
cv2.waitKey(int(1000/fps))
else:
break
# Liberar el objeto VideoCapture y cerrar la ventana de visualización
video_capture.release()
cv2.destroyAllWindows()
def dfi_video(ruta_salida):
# Directorio de entrada de imágenes
ruta_entrada = ruta_salida
# Obtener el tamaño de la primera imagen en el directorio de entrada
img_path = os.path.join(ruta_entrada, os.listdir(ruta_entrada)[0])
img = cv2.imread(img_path)
img_size = (img.shape[1], img.shape[0])
# Fps del video
fps = 15
# Crear objeto VideoWriter
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video_salida = cv2.VideoWriter('output.mp4', fourcc, fps, img_size)
# Crear ventana con nombre "video"
cv2.namedWindow("video")
# Establecer la ventana en primer plano
cv2.setWindowProperty("video", cv2.WND_PROP_TOPMOST,1.0)
# Crear ventana de visualización
# Leer imágenes en el directorio y agregarlas al video de salida
for file in sorted(os.listdir(ruta_entrada)):
if file.endswith(".jpg") or file.endswith(".jpeg") or file.endswith(".png"): # Verificar que sea una imagen
img = cv2.imread(os.path.join(ruta_entrada, file)) # Leer la imagen
#img_resized = cv2.resize(img, img_size) # Redimensionar la imagen
video_salida.write(img) # Agregar la imagen al video
# Liberar el objeto VideoWriter
video_salida.release()
# Crear objeto VideoCapture para leer el archivo de video recién creado
video_capture = cv2.VideoCapture('output.mp4')
# Crear ventana con nombre "video"
cv2.namedWindow("video")
# Establecer la ventana en primer plano
cv2.setWindowProperty("video", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_NORMAL)
# Mostrar el video en una ventana
while True:
ret, img = video_capture.read()
if ret:
cv2.imshow('video', img)
cv2.waitKey(int(1000/fps))
else:
break
# Liberar el objeto VideoCapture y cerrar la ventana de visualización
video_capture.release()
cv2.destroyAllWindows()
def add_tab():
print('LAB')
with gr.Blocks(analytics_enabled=False) as demo:
with gr.Tabs():
with gr.Tab("Main"):
with gr.Row():
with gr.Column():
with gr.Column():
gr.Markdown("# Abysz LAB 0.1.9 Temporal coherence tools")
gr.Markdown("## DFI Render")
with gr.Column():
ruta_entrada_1 = gr.Textbox(label="Original/reference frames folder", placeholder="RAW frames, or generated ones. (Read the strategies in the guide)")
ruta_entrada_2 = gr.Textbox(label="Generated frames folder", placeholder="The frames of AI generated video")
ruta_salida = gr.Textbox(label="Output folder", placeholder="Remember that each generation overwrites previous frames in the same folder.")
with gr.Accordion("Info", open=False):
gr.Markdown("This process detects static areas between frames (white) and moving areas (black). Use preview map and you will understand this. Basically, it will force the white areas to stay the same on the next frame.")
gr.Markdown("DFI Tolerance adjusts how stiff this process is. Higher = more rigidity + corruption. Lower = more flexible, less corruption, but allows more flick. ")
gr.Markdown("As complement, you can clean the map, to reduce detail and noise, or fatten/expand the areas detected by DFI. It is better that you use preview many times to experience how it works.")
gr.Markdown("### IMPORTANT: The general algorithm is optimized to maintain a balance between deflicking and corruption, so that it is easier to use StableDiffusion at low denoising to reconstruct lost detail while preserving the stability gained.")
with gr.Row():
denoise_blur = gr.Slider(minimum=0, maximum=30, value=0, step=1, label="Map Denoise")
dfi_strength = gr.Slider(minimum=0.5, maximum=20, value=5, step=0.5, label="DFI Tolerance")
dfi_deghost = gr.Slider(minimum=0, maximum=50, value=0, step=1, label="DFI Expand")
with gr.Accordion("Info", open=False):
gr.Markdown("Here you can preview examples of the motion map for those parameters. It is useful, for example, to adjust denoise if you see that it detects unnecessary graininess. Keep in mind that what you see represents movement between two frames.")
gr.Markdown("A good balance point is to throttle DFI until you find just a few things in areas that should be static. If you force it to be TOO clean, it will mostly increase the overall corruption.")
with gr.Row():
dfi_test = gr.Button(value="Preview DFI Map")
test_mode = gr.Slider(minimum=0, maximum=100, value=0, step=1, label="Preview amount. 0 = Quick shot")
with gr.Accordion("Advanced", open=False):
with gr.Accordion("Info", open=False):
gr.Markdown("**Inter Denoise:** Reduces render pixelation generated by corruption. However, be careful. It's resource hungry, and might remove excess detail. Not recommended to change size or FPD, but to use Stable Diffusion to remove the pixelation later.")
gr.Markdown("**Inter Blur:** Fine tunes the dynamic blur algorithm for DFI map. Lower = Stronger blur effects. Between 2-3 recommended.")
gr.Markdown("**Corruption Refresh:** To reduce the distortion generated by the process, you can recover original information every X number of frames. Lower number = faster refresh.")
gr.Markdown("**Corruption Preserve:** Here you decide how much corruption keep in each corruption refresh. Low values will recover more of the original frame, with its changes and flickering, in exchange for reducing corruption. You must find the balance that works best for your goal.")
gr.Markdown("**Smooth:** This smoothes the edges of the interpolated areas. Low values are currently recommended until the algorithm is updated.")
with gr.Row():
inter_denoise = gr.Slider(minimum=1, maximum=25, value=9, step=1, label="Inter Denoise")
inter_denoise_size = gr.Slider(minimum=1, maximum=25, value=9, step=2, label="Inter Denoise Size")
inter_denoise_speed = gr.Slider(minimum=1, maximum=15, value=3, step=1, label="Inter Denoise FPD")
fine_blur = gr.Slider(minimum=1, maximum=5, value=3, step=0.1, label="Inter Blur")
gr.Markdown("### The new dynamic algorithm will handle these parameters. Activate them only for manual control.")
with gr.Row():
frame_refresh_frequency = gr.Slider(minimum=0, maximum=30, value=0, step=1, label="Corruption Refresh (Lower = Faster)")
refresh_strength = gr.Slider(minimum=0, maximum=100, value=0, step=5, label="Corruption Preserve")
smooth = gr.Slider(minimum=1, maximum=99, value=1, step=2, label="Smooth")
with gr.Row():
frames_limit = gr.Number(label="Frames to render. 0=ALL")
run_button = gr.Button(value="Run DFI", variant="primary")
output_placeholder = gr.Textbox(label="Status", placeholder="STAND BY...")
video_dfi = gr.Button(value="Show output folder video")
with gr.Column():
with gr.Column():
gr.Markdown("# |")
gr.Markdown("## Deflickers Playground")
with gr.Column():
ruta_entrada_3 = gr.Textbox(label="Frames folder", placeholder="Frames to process")
ruta_salida_1 = gr.Textbox(label="Output folder", placeholder="Processed frames")
with gr.Accordion("Info", open=False):
gr.Markdown("I made this series of deflickers based on the standard that Vegas Pro includes. You can use them together or separately. Be careful when mixing them.")
gr.Markdown("**Blend:** Blends a percentage between frames. This can soften transitions and highlights. 50 is half of each frame. 80 or 20 are recommended values.")
gr.Markdown("**Overlay:** Use the overlay image blending mode. Note that it works particularly good at mid-high values, wich will modify the overall contrast. You will have to decide what works for you.")
gr.Markdown("**Normalize:** Calculates the average between frames to merge them. It may be more practical if you don't have a specific Blend deflicker value in mind.")
ddf_strength = gr.Slider(minimum=0, maximum=1, value=0, step=0.01, label="BLEND (0=Off)")
over_strength = gr.Slider(minimum=0, maximum=1, value=0, step=0.01, label="OVERLAY (0=Off)")
norm_strength = gr.Slider(minimum=0, maximum=1, value=0, step=1, label="NORMALIZE (0=Off))")
dfk_button = gr.Button(value="Deflickers")
with gr.Tab("LAB Tools"):
with gr.Column():
gr.Markdown("## Style Fuse")
with gr.Accordion("Info", open=False):
gr.Markdown("With this you can merge two sets of frames with overlay technique. For example, you can take a style video that is just lights and/or colors, and overlay it on top of another video.")
gr.Markdown("The resulting video will be useful for use in Img2Img Batch and that the AI render preserves these added color and lighting details, along with the details of the original video.")
with gr.Row():
ruta_entrada_4 = gr.Textbox(label="Style frames", placeholder="Style to fuse")
ruta_entrada_5 = gr.Textbox(label="Video frames", placeholder="Frames to process")
with gr.Row():
ruta_salida_2 = gr.Textbox(label="Output folder", placeholder="Processed frames")
fuse_strength = gr.Slider(minimum=0.1, maximum=1, value=0.5, step=0.01, label="Fuse Strength")
fuse_button = gr.Button(value="Fuse")
gr.Markdown("## Video extract")
with gr.Row():
ruta_entrada_6 = gr.Textbox(label="Video path", placeholder="Remember to use same fps as generated video for DFI")
ruta_salida_3 = gr.Textbox(label="Output folder", placeholder="Processed frames")
with gr.Row():
fps_count = gr.Number(label="Fps. 0=Original")
vidextract_button = gr.Button(value="Extract")
output_placeholder2 = gr.Textbox(label="Status", placeholder="STAND BY...")
with gr.Tab("Guide"):
with gr.Column():
gr.Markdown("# What DFI does?")
with gr.Accordion("Info", open=False):
gr.Markdown("DFI processing analyzes the motion of the original video, and attempts to force that information into the generated video. Demo on https://github.com/AbyszOne/Abysz-LAB-Ext")
gr.Markdown("In short, this will reduce flicker in areas of the video that don't need to change, but SD does. For example, for a man smoking, leaning against a pole, it will detect that the pole is static, and will try to prevent it from changing as much as possible.")
gr.Markdown("This is an aggressive process that requires a lot of control for each context. Read the recommended strategies.")
gr.Markdown("Although Video to Video is the most efficient way, a DFI One Shot method is under experimental development as well.")
gr.Markdown("# Usage strategies")
with gr.Accordion("Info", open=False):
gr.Markdown("If you get enough understanding of the tool, you can achieve a much more stable and clean enough rendering. However, this is quite demanding.")
gr.Markdown("Instead, a much friendlier and faster way to use this tool is as an intermediate step. For this, you can allow a reasonable degree of corruption in exchange for more general stability. ")
gr.Markdown("You can then clean up the corruption and recover details with a second step in Stable Diffusion at low denoising (0.2-0.4), using the same parameters and seed.")
gr.Markdown("In this way, the final result will have the stability that we have gained, maintaining final detail. If you find a balanced workflow, you will get something at least much more coherent and stable than the raw AI render.")
gr.Markdown("**OPTIONAL:** Although not ideal, you can use the same AI generated video as the source, instead of the RAW. The trick is to use DFI and denoise to wash out map details so that you reduce low/mid changes between frames. If you only need a soft deflick, it is a valid option.")
dt_inputs=[ruta_entrada_1, ruta_entrada_2, denoise_blur, dfi_strength, dfi_deghost, test_mode, smooth]
run_inputs=[ruta_entrada_1, ruta_entrada_2, ruta_salida, denoise_blur, dfi_strength, dfi_deghost, test_mode, inter_denoise, inter_denoise_size, inter_denoise_speed, fine_blur, frame_refresh_frequency, refresh_strength, smooth, frames_limit]
dfk_inputs=[ruta_entrada_3, ruta_salida_1, ddf_strength, over_strength, norm_strength]
fuse_inputs=[ruta_entrada_4, ruta_entrada_5, ruta_salida_2, fuse_strength]
ve_inputs=[ruta_entrada_6, ruta_salida_3, fps_count]
dfi_test.click(fn=test_dfi, inputs=dt_inputs, outputs=output_placeholder)
run_button.click(fn=main, inputs=run_inputs, outputs=output_placeholder)
video_dfi.click(fn=dfi_video, inputs=ruta_salida, outputs=output_placeholder)
dfk_button.click(fn=deflickers, inputs=dfk_inputs, outputs=output_placeholder)
fuse_button.click(fn=over_fuse, inputs=fuse_inputs, outputs=output_placeholder2)
vidextract_button.click(fn=extract_video, inputs=ve_inputs, outputs=output_placeholder2)
return [(demo, "Abysz LAB", "demo")]
script_callbacks.on_ui_tabs(add_tab)
|