FluttyProger
commited on
Commit
·
a17c757
1
Parent(s):
63ea1aa
Upload 3 files
Browse files- loadimageb64.py +70 -0
- maskgen.py +63 -0
- maskload.py +39 -0
loadimageb64.py
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from PIL import Image
|
2 |
+
import io
|
3 |
+
import base64
|
4 |
+
import numpy as np
|
5 |
+
import torch
|
6 |
+
|
7 |
+
class imagetob64():
|
8 |
+
def __init__(self):
|
9 |
+
pass
|
10 |
+
|
11 |
+
@classmethod
|
12 |
+
def INPUT_TYPES(s):
|
13 |
+
return {"required": {"images": ("IMAGE", ), },}
|
14 |
+
|
15 |
+
CATEGORY = "image"
|
16 |
+
RETURN_TYPES = ()
|
17 |
+
OUTPUT_NODE = True
|
18 |
+
FUNCTION = "images_tob64"
|
19 |
+
def images_tob64(self, images):
|
20 |
+
imges = []
|
21 |
+
for image in images:
|
22 |
+
i = 255. * image.cpu().numpy()
|
23 |
+
img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
|
24 |
+
buffer = io.BytesIO()
|
25 |
+
img.save(buffer, format="JPEG")
|
26 |
+
buffer.seek(0)
|
27 |
+
imgb64 = base64.b64encode(buffer.getvalue()).decode()
|
28 |
+
imges.append(imgb64)
|
29 |
+
return { "ui": { "images": imges } }
|
30 |
+
|
31 |
+
class loadimageb64:
|
32 |
+
|
33 |
+
def __init__(self):
|
34 |
+
pass
|
35 |
+
|
36 |
+
@classmethod
|
37 |
+
def INPUT_TYPES(s):
|
38 |
+
"""
|
39 |
+
Return a dictionary which contains config for all input fields.
|
40 |
+
Some types (string): "MODEL", "VAE", "CLIP", "CONDITIONING", "LATENT", "IMAGE", "INT", "STRING", "FLOAT".
|
41 |
+
Input types "INT", "STRING" or "FLOAT" are special values for fields on the node.
|
42 |
+
The type can be a list for selection.
|
43 |
+
|
44 |
+
Returns: `dict`:
|
45 |
+
- Key input_fields_group (`string`): Can be either required, hidden or optional. A node class must have property `required`
|
46 |
+
- Value input_fields (`dict`): Contains input fields config:
|
47 |
+
* Key field_name (`string`): Name of a entry-point method's argument
|
48 |
+
* Value field_config (`tuple`):
|
49 |
+
+ First value is a string indicate the type of field or a list for selection.
|
50 |
+
+ Secound value is a config for type "INT", "STRING" or "FLOAT".
|
51 |
+
"""
|
52 |
+
return {"required": {"b64img": ("STRING", {"multiline": False}),}}
|
53 |
+
|
54 |
+
CATEGORY = "image"
|
55 |
+
RETURN_TYPES = ("IMAGE",)
|
56 |
+
|
57 |
+
FUNCTION = "load_imageb64"
|
58 |
+
def load_imageb64(self, b64img):
|
59 |
+
pilim = Image.open(io.BytesIO(base64.b64decode(b64img)))
|
60 |
+
tensor_bw = pilim.convert("RGB")
|
61 |
+
tensor_bw = np.array(tensor_bw).astype(np.float32) / 255.0
|
62 |
+
tensor_bw = torch.from_numpy(tensor_bw)[None,]
|
63 |
+
|
64 |
+
return (tensor_bw,)
|
65 |
+
|
66 |
+
|
67 |
+
NODE_CLASS_MAPPINGS = {
|
68 |
+
"loadimageb64": loadimageb64,
|
69 |
+
"imagetob64": imagetob64,
|
70 |
+
}
|
maskgen.py
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import albumentations as albu
|
2 |
+
import numpy as np
|
3 |
+
from iglovikov_helper_functions.utils.image_utils import pad, unpad
|
4 |
+
from iglovikov_helper_functions.dl.pytorch.utils import tensor_from_rgb_image
|
5 |
+
import cv2
|
6 |
+
import torch
|
7 |
+
from PIL import Image
|
8 |
+
|
9 |
+
def pil2tensor(image):
|
10 |
+
return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
|
11 |
+
|
12 |
+
def tensor2np(image):
|
13 |
+
return np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8)
|
14 |
+
|
15 |
+
class GenImageMask:
|
16 |
+
|
17 |
+
def __init__(self):
|
18 |
+
pass
|
19 |
+
|
20 |
+
@classmethod
|
21 |
+
def INPUT_TYPES(s):
|
22 |
+
"""
|
23 |
+
Return a dictionary which contains config for all input fields.
|
24 |
+
Some types (string): "MODEL", "VAE", "CLIP", "CONDITIONING", "LATENT", "IMAGE", "INT", "STRING", "FLOAT".
|
25 |
+
Input types "INT", "STRING" or "FLOAT" are special values for fields on the node.
|
26 |
+
The type can be a list for selection.
|
27 |
+
|
28 |
+
Returns: `dict`:
|
29 |
+
- Key input_fields_group (`string`): Can be either required, hidden or optional. A node class must have property `required`
|
30 |
+
- Value input_fields (`dict`): Contains input fields config:
|
31 |
+
* Key field_name (`string`): Name of a entry-point method's argument
|
32 |
+
* Value field_config (`tuple`):
|
33 |
+
+ First value is a string indicate the type of field or a list for selection.
|
34 |
+
+ Secound value is a config for type "INT", "STRING" or "FLOAT".
|
35 |
+
"""
|
36 |
+
return {"required": {"image": ("IMAGE",), "segm_model": ("SEGM_MODEL",)}}
|
37 |
+
|
38 |
+
CATEGORY = "image"
|
39 |
+
RETURN_TYPES = ("IMAGE",)
|
40 |
+
RETURN_NAMES = ("BW Mask",)
|
41 |
+
|
42 |
+
FUNCTION = "mask_image"
|
43 |
+
def mask_image(self, image, segm_model):
|
44 |
+
|
45 |
+
transform = albu.Compose([albu.Normalize(p=1)], p=1)
|
46 |
+
image = tensor2np(image)
|
47 |
+
padded_image, pads = pad(image, factor=32, border=cv2.BORDER_CONSTANT)
|
48 |
+
x = transform(image=padded_image)["image"]
|
49 |
+
x = torch.unsqueeze(tensor_from_rgb_image(x), 0)
|
50 |
+
with torch.no_grad():
|
51 |
+
prediction = segm_model(x)[0][0]
|
52 |
+
|
53 |
+
mask = (prediction > 0.01).cpu().numpy().astype(np.uint8)
|
54 |
+
|
55 |
+
mask = unpad(mask, pads)
|
56 |
+
|
57 |
+
imag = pil2tensor(Image.fromarray(cv2.cvtColor(mask, cv2.COLOR_GRAY2RGB) * 255))
|
58 |
+
return (imag,)
|
59 |
+
|
60 |
+
|
61 |
+
NODE_CLASS_MAPPINGS = {
|
62 |
+
"GenImageMask": GenImageMask,
|
63 |
+
}
|
maskload.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from cloths_segmentation.pre_trained_models import create_model
|
2 |
+
|
3 |
+
class GenMaskModela:
|
4 |
+
|
5 |
+
def __init__(self):
|
6 |
+
pass
|
7 |
+
|
8 |
+
@classmethod
|
9 |
+
def INPUT_TYPES(s):
|
10 |
+
"""
|
11 |
+
Return a dictionary which contains config for all input fields.
|
12 |
+
Some types (string): "MODEL", "VAE", "CLIP", "CONDITIONING", "LATENT", "IMAGE", "INT", "STRING", "FLOAT".
|
13 |
+
Input types "INT", "STRING" or "FLOAT" are special values for fields on the node.
|
14 |
+
The type can be a list for selection.
|
15 |
+
|
16 |
+
Returns: `dict`:
|
17 |
+
- Key input_fields_group (`string`): Can be either required, hidden or optional. A node class must have property `required`
|
18 |
+
- Value input_fields (`dict`): Contains input fields config:
|
19 |
+
* Key field_name (`string`): Name of a entry-point method's argument
|
20 |
+
* Value field_config (`tuple`):
|
21 |
+
+ First value is a string indicate the type of field or a list for selection.
|
22 |
+
+ Secound value is a config for type "INT", "STRING" or "FLOAT".
|
23 |
+
"""
|
24 |
+
return {"required": {}}
|
25 |
+
|
26 |
+
CATEGORY = "image"
|
27 |
+
RETURN_TYPES = ("SEGM_MODEL",)
|
28 |
+
|
29 |
+
FUNCTION = "masks_image"
|
30 |
+
def masks_image(self):
|
31 |
+
modela = create_model("Unet_2020-10-30")
|
32 |
+
modela.eval()
|
33 |
+
|
34 |
+
return (modela,)
|
35 |
+
|
36 |
+
|
37 |
+
NODE_CLASS_MAPPINGS = {
|
38 |
+
"GenMaskModela": GenMaskModela,
|
39 |
+
}
|