Merge branch 'main' into dev/august-refactor

This commit is contained in:
melMass
2023-08-08 18:10:39 +02:00
5 changed files with 90 additions and 13 deletions
+9
View File
@@ -37,7 +37,16 @@ jobs:
with:
path: ComfyUI_windows_portable
key: ${{ runner.os }}-comfy-env
- name: ⏬ Install other extensions
shell: bash
run: |
export COMFY_PYTHON="${GITHUB_WORKSPACE}/ComfyUI_windows_portable/python_embeded/python.exe"
cd "${GITHUB_WORKSPACE}/ComfyUI_windows_portable/ComfyUI/custom_nodes"
git clone https://github.com/Fannovel16/comfy_controlnet_preprocessors
cd comfy_controlnet_preprocessors
$COMFY_PYTHON install.py
- name: ♻️ Checking out comfy_mtb to custom_nodes
uses: actions/checkout@v3
with:
+7 -5
View File
@@ -14,7 +14,7 @@
"Film Interpolation (mtb)": "Google Research FILM frame interpolation for large motion",
"Fit Number (mtb)": "Fit the input float using a source and target range",
"Float To Number (mtb)": "Node addon for the WAS Suite. Converts a \"comfy\" FLOAT to a NUMBER.",
"Get Batch From History (mtb)": "Very experimental node to load images from the history of the server.\n\n Queue items without output are ignore in the count.",
"Get Batch From History (mtb)": "Very experimental node to load images from the history of the server.\n\n Queue items without output are ignored in the count.",
"Image Compare (mtb)": "Compare two images and return a difference image",
"Image Premultiply (mtb)": "Premultiply image with mask",
"Image Remove Background Rembg (mtb)": "Removes the background from the input using Rembg.",
@@ -22,8 +22,7 @@
"Int To Bool (mtb)": "Basic int to bool conversion",
"Int To Number (mtb)": "Node addon for the WAS Suite. Converts a \"comfy\" INT to a NUMBER.",
"Latent Lerp (mtb)": "Linear interpolation (blend) between two latent vectors",
"Latent Noise (mtb)": "Inject noise into latent space",
"Latent Transform (mtb)": "Dumb attempt at reproducing some deforum like motion",
"Load Face Analysis Model (mtb)": "Loads a face analysis model",
"Load Face Enhance Model (mtb)": "Loads a GFPGan or RestoreFormer model for face enhancement.",
"Load Face Swap Model (mtb)": "Loads a faceswap model",
"Load Film Model (mtb)": "Loads a FILM model",
@@ -35,9 +34,12 @@
"Save Gif (mtb)": "Save the images from the batch as a GIF",
"Save Image Grid (mtb)": "Save all the images in the input batch as a grid of images.",
"Save Image Sequence (mtb)": "Save an image sequence to a folder. The current frame is used to determine which image to save.\n\n This is merely a wrapper around the `save_images` function with formatting for the output folder and filename.\n ",
"Save Tensors (mtb)": "Save torch tensors (image, mask or latent) to disk, useful to debug things outside comfy",
"Smart Step (mtb)": "Utils to control the steps start/stop of the KAdvancedSampler in percentage",
"String Replace (mtb)": "Basic string replacement",
"Styles Loader (mtb)": "Load csv files and populate a dropdown from the rows (\u00e0 la A111)",
"Text To Image (mtb)": "Utils to convert text to image using a font\n\n\n The tool looks for any .ttf file in the Comfy folder hierarchy.\n ",
"Uncrop (mtb)": "Uncrops an image to a given bounding box\n\n The bounding box can be given as a tuple of (x, y, width, height) or as a BBOX type\n The BBOX input takes precedence over the tuple input"
}
"Transform Image (mtb)": "Save torch tensors (image, mask or latent) to disk, useful to debug things outside comfy\n\n\n it return a tensor representing the transformed images with the same shape as the input tensor\n ",
"Uncrop (mtb)": "Uncrops an image to a given bounding box\n\n The bounding box can be given as a tuple of (x, y, width, height) or as a BBOX type\n The BBOX input takes precedence over the tuple input",
"Unsplash Image (mtb)": "Unsplash Image given a keyword and a size"
}
+29 -7
View File
@@ -26,19 +26,39 @@ class LoadFaceEnhanceModel:
@classmethod
def get_models_root(cls):
return Path(folder_paths.models_dir) / "upscale_models"
fr = Path(folder_paths.models_dir) / "face_restore"
if fr.exists():
return (fr, None)
um = Path(folder_paths.models_dir) / "upscale_models"
return (fr, um) if um.exists() else (None, None)
@classmethod
def get_models(cls):
models_path = cls.get_models_root()
fr_models_path, um_models_path = cls.get_models_root()
if not models_path.exists():
log.warning(f"No models found at {models_path}")
if fr_models_path is None and um_models_path is None:
log.warning("Face restoration models not found.")
return []
if not fr_models_path.exists():
log.warning(
f"No Face Restore checkpoints found at {fr_models_path} (if you've used mtb before these checkpoints were saved in upscale_models before)"
)
log.warning(
"For now we fallback to upscale_models but this will be removed in a future version"
)
if um_models_path.exists():
return [
x
for x in um_models_path.iterdir()
if x.name.endswith(".pth")
and ("GFPGAN" in x.name or "RestoreFormer" in x.name)
]
return []
return [
x
for x in models_path.iterdir()
for x in fr_models_path.iterdir()
if x.name.endswith(".pth")
and ("GFPGAN" in x.name or "RestoreFormer" in x.name)
]
@@ -64,7 +84,7 @@ class LoadFaceEnhanceModel:
def load_model(self, model_name, upscale=2, bg_upsampler=None):
basic = "RestoreFormer" not in model_name
root = self.get_models_root()
fr_root, um_root = self.get_models_root()
if bg_upsampler is not None:
log.warning(
@@ -75,7 +95,9 @@ class LoadFaceEnhanceModel:
sys.stdout = NullWriter()
model = GFPGANer(
model_path=(root / model_name).as_posix(),
model_path=(
(fr_root if fr_root.exists() else um_root) / model_name
).as_posix(),
upscale=upscale,
arch="clean" if basic else "RestoreFormer", # or original for v1.0 only
channel_multiplier=2, # 1 for v1.0 only
+4 -1
View File
@@ -11,7 +11,7 @@ import numpy as np
import os
import torch
from insightface.model_zoo.inswapper import INSwapper
from ..utils import pil2tensor, tensor2pil
from ..utils import pil2tensor, tensor2pil, download_antelopev2
from ..log import mklog, NullWriter
import sys
import comfy.model_management as model_management
@@ -52,6 +52,9 @@ class LoadFaceAnalysisModel:
CATEGORY = "mtb/facetools"
def load_model(self, faceswap_model: str):
if faceswap_model == "antelopev2":
download_antelopev2()
face_analyser = insightface.app.FaceAnalysis(
name=faceswap_model,
root=os.path.join(folder_paths.models_dir, "insightface"),
+41
View File
@@ -4,6 +4,7 @@ import torch
from pathlib import Path
import sys
from typing import List
from .log import log
# region MISC Utilities
@@ -125,3 +126,43 @@ def tensor2np(tensor: torch.Tensor) -> List[np.ndarray]:
# endregion
# region MODEL Utilities
def download_antelopev2():
antelopev2_url = "https://drive.google.com/uc?id=18wEUfMNohBJ4K3Ly5wpTejPfDzp-8fI8"
try:
import gdown
import folder_paths
log.debug("Loading antelopev2 model")
dest = Path(folder_paths.models_dir) / "insightface"
archive = dest / "antelopev2.zip"
final_path = dest / "models" / "antelopev2"
if not final_path.exists():
log.info(f"antelopev2 not found, downloading to {dest}")
gdown.download(
antelopev2_url,
archive.as_posix(),
resume=True,
)
log.info(f"Unzipping antelopev2 to {final_path}")
if archive.exists():
# we unzip it
import zipfile
with zipfile.ZipFile(archive.as_posix(), "r") as zip_ref:
zip_ref.extractall(final_path.parent.as_posix())
except Exception as e:
log.error(
f"Could not load or download antelopev2 model, download it manually from {antelopev2_url}"
)
raise e
# endregion