Files
smthemex-ComfyUI_DeepFakeDe…/DeepFakeDefender_node.py
T

196 lines
6.7 KiB
Python

# !/usr/bin/env python
# -*- coding: UTF-8 -*-
import os
import cv2
import numpy as np
import torch
import torch.nn as nn
from torchvision import transforms
from PIL import Image
from .network import MFF_MoE
import folder_paths
from comfy.utils import ProgressBar,common_upscale
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
device = (
"cuda"
if torch.cuda.is_available()
else "mps" if torch.backends.mps.is_available() else "cpu"
)
current_path = os.path.dirname(os.path.abspath(__file__))
def tensor2pil(tensor):
image_np = tensor.squeeze().mul(255).clamp(0, 255).byte().numpy()
image = Image.fromarray(image_np, mode='RGB')
return image
def phi2narry(img):
img = torch.from_numpy(np.array(img).astype(np.float32) / 255.0).unsqueeze(0)
return img
def nomarl_upscale(img_tensor, width, height):
samples = img_tensor.movedim(-1, 1)
img = common_upscale(samples, width, height, "nearest-exact", "center")
samples = img.movedim(1, -1)
return samples
def nomarl_upscale_topil(img_tensor, width, height):
samples = img_tensor.movedim(-1, 1)
img = common_upscale(samples, width, height, "nearest-exact", "center")
samples = img.movedim(1, -1)
img_pil = tensor2pil(samples)
return img_pil
def images_generator(file_list):# form VH
sizes = {}
for i in file_list:
count = sizes.get(i.size, 0)
sizes[i.size] = count +1
size = max(sizes.items(), key=lambda x: x[1])[0]
yield size[0], size[1]
total_images = len(file_list)
processed_images = 0
pbar = ProgressBar(total_images)
images = map(phi2narry, file_list)
try:
prev_image = next(images)
while True:
next_image = next(images)
yield prev_image
processed_images += 1
pbar.update_absolute(processed_images, total_images)
prev_image = next_image
except StopIteration:
pass
if prev_image is not None:
yield prev_image
def load_images(file_list):
gen = images_generator(file_list)
(width, height) = next(gen)
images = torch.from_numpy(np.fromiter(gen, np.dtype((np.float32, (height, width, 3)))))
if len(images) == 0:
raise FileNotFoundError(f"No images could be loaded from directory '{file_list}'.")
return images
class DeepFakeDefender_Loader:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"ckpt_path": ("STRING", {"default": "DeepFakeDefender"}),
}
}
RETURN_TYPES = ("MODEL","MODEL",)
RETURN_NAMES = ("net","transform_val",)
FUNCTION = "test"
CATEGORY = "DeepFakeDefender_Gold"
def test(self,ckpt_path):
weigths_current_path = os.path.join(folder_paths.models_dir, ckpt_path)
if not os.path.exists(weigths_current_path):
os.makedirs(weigths_current_path)
net = MFF_MoE(pretrained=False)
net.load(path=weigths_current_path)
net = nn.DataParallel(net).cuda()
net.eval()
transform_val = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
transforms.Resize((512, 512), antialias=True),
])
return (net,transform_val,)
class DeepFakeDefender_Sampler:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"image": ("IMAGE",),
"net": ("MODEL",),
"transform_val": ("MODEL",),
"threshold": ("FLOAT", {
"default": 0.500000000,
"min": 0.000000001,
"max": 0.999999999,
"step": 0.001,
"round": 0.0000000001,
"display": "number",
}),
"crop_width": ("INT", {"default": 512, "min": 256, "max": 4096, "step": 32, "display": "number"}),
"crop_height": ("INT", {"default": 512, "min": 256, "max": 4096, "step": 32, "display": "number"}),
},
}
RETURN_TYPES = ("STRING","IMAGE","IMAGE",)
RETURN_NAMES = ("string","above","below",)
FUNCTION = "test"
CATEGORY = "DeepFakeDefender_Gold"
def test(self,image,net,transform_val,threshold,crop_width,crop_height):
empty_img = Image.new('RGB', (512, 512), (255, 255, 255))
B, _, _, _ = image.shape
if B==1:
origin_img_list =[tensor2pil(image.copy())]
img_list=[nomarl_upscale_topil(image, crop_width, crop_height)]
else:
img_list = list(torch.chunk(image, chunks=B))
origin_img_list = [tensor2pil(img) for img in img_list.copy()]
img_list = [nomarl_upscale_topil(img, crop_width, crop_height) for img in img_list]
out_str=''
below_img=[]
above_img=[]
pred_check=np.array([threshold])
for i,img in enumerate(img_list):
#x = img_list[i]
# x = cv2.imread(input_path)[..., ::-1]
# x=np.array(x)
#x=np.asarray(x)
# x = cv2.cvtColor(x, cv2.COLOR_RGB2BGR)[..., ::-1]
#x = Image.fromarray(np.uint8(x))
y = transform_val(img).unsqueeze(0).cuda()
pred = net(y)
pred = pred.detach().cpu().numpy()
print('Prediction of this image [%s] being Deepfake(这张照片是深度伪造的预测值为): %10.9f' % (i+1,pred))
pred = np.around(pred, decimals=9)
string = f"\nPrediction of this image ({i+1}) being Deepfake: {pred}. \n 这张照片({i+1})是深度伪造的预测值为:{pred}.\n"
out_str += string
if np.less_equal(pred,pred_check)==[True] :
below_img.append(origin_img_list[i])
if np.greater(pred,pred_check)==[True] :
above_img.append(origin_img_list[i])
if below_img:
below_image=load_images(below_img)
else:
below_image = load_images([empty_img])
if above_img:
above_image = load_images(above_img)
else:
above_image = load_images([empty_img])
return (out_str,above_image,below_image)
# A dictionary that contains all nodes you want to export with their names
# NOTE: names should be globally unique
NODE_CLASS_MAPPINGS = {
"DeepFakeDefender_Loader": DeepFakeDefender_Loader,
"DeepFakeDefender_Sampler":DeepFakeDefender_Sampler
}
# A dictionary that contains the friendly/humanly readable titles for the nodes
NODE_DISPLAY_NAME_MAPPINGS = {
"DeepFakeDefender_Loader": "DeepFakeDefender_Loader",
"DeepFakeDefender_Sampler":"DeepFakeDefender_Sampler"
}